PDA

View Full Version : Problem using SetPixelFormat function



Darvesh
10-15-2009, 04:17 AM
Hi,

I am trying to call SetPixelFormat function to draw into a window created by another process. I have got the window handle and device context handle using FindWindow and GetDC functions. I have noticed that the window handle and device context handles are correct. However, SetPixelFormat function fails with error code 0xc0070006. Any idea why I am getting this error?

Is this possible at all to use the device context of window of another process to draw in that window using OpenGL?

Here is the source code:
// Source code to create a sample window in process 1
#include <windows.h>

// Global variable

HINSTANCE hinst;

// Function prototypes.

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
BOOL InitApplication(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);

// Application entry point.

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
BOOL fGotMessage;

if (!InitApplication(hinstance))
return FALSE;

if (!InitInstance(hinstance, nCmdShow))
return FALSE;

while ((fGotMessage = GetMessage(&amp;msg, (HWND) NULL, 0, 0)) != 0 &amp;&amp; fGotMessage != -1)
{
TranslateMessage(&amp;msg);
DispatchMessage(&amp;msg);
}
return msg.wParam;
UNREFERENCED_PARAMETER(lpCmdLine);
}

BOOL InitApplication(HINSTANCE hinstance)
{
WNDCLASS wc;
wc.style = NULL;//CS_GLOBALCLASS;//CS_GLOBALCLASS;//CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "MainWClass";

if (!RegisterClass(&amp;wc))
{
return NULL;
}

}

BOOL InitInstance(HINSTANCE hinstance, int nCmdShow)
{
HWND hwnd;

// Save the application-instance handle.

hinst = hinstance;

// Create the main window.
hwnd = CreateWindow("MainWClass", "Sample",
WS_VISIBLE,
0, 0,
240 + 10, 320 + 40,
NULL, NULL, hinstance, NULL);


if (!hwnd)
return FALSE;

UpdateWindow(hwnd);
return TRUE;

}

// Source code to find the window and use that window to draw something in another process 2

#include <windows.h>

// Global variable

HINSTANCE hinst;

// Function prototypes.

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
BOOL InitApplication(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);

// Application entry point.

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
BOOL fGotMessage;
PWINDOWINFO pwi;
BOOL retCode;
COLORREF crColor,retCrColor;
//HDC hdc;
int iPixelFormat;

HWND hfoundWND=NULL;
HDC hdc;
DWORD errCode=0;
PIXELFORMATDESCRIPTOR pfd1 = {
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
hfoundWND=FindWindow("MainWClass","Sample");

if( NULL == hfoundWND)
{
errCode=GetLastError();

}
hdc= GetDC( hfoundWND );
if( NULL == hdc)
{
errCode=GetLastError();

}



// get the best available match of pixel format for the device context
iPixelFormat = ChoosePixelFormat(hdc, &amp;pfd1);
if( 0 == iPixelFormat)
{
errCode=GetLastError();
}



errCode=SetPixelFormat(hdc, iPixelFormat, &amp;pfd1);
if(0 == errCode)
{
errCode=GetLastError();
printf("SetPixelFormat failed, %d\n", (UINT)errCode);

}


crColor=0x00ff0000;
retCrColor=SetBkColor(hdc, crColor);
if( CLR_INVALID == retCrColor)
{
errCode=GetLastError();
}

pwi=(PWINDOWINFO)malloc(sizeof( WINDOWINFO));
pwi->cbSize=sizeof(WINDOWINFO);
if(FALSE == GetWindowInfo(
hfoundWND,
pwi))
{
errCode=GetLastError();
}

retCode=ShowWindow(
hfoundWND,
SW_HIDE);







while ((fGotMessage = GetMessage(&amp;msg, (HWND) NULL, 0, 0)) != 0 &amp;&amp; fGotMessage != -1)
{
TranslateMessage(&amp;msg);
DispatchMessage(&amp;msg);
}
free(pwi);
return msg.wParam;
UNREFERENCED_PARAMETER(lpCmdLine);
}

yooyo
10-15-2009, 05:24 AM
I think it is not possible.. It was possible long time ago in Windows 95-98, but not in 2k, XP or Vista.

Only way to mess with another process is to do DLL inject in target proces memory space. See "taksi" project on sourceforge.

punky
10-15-2009, 10:19 PM
i was so free to translate your code into human readable :
i was not able to translate 0xc007 but 0006 means the Handle is invalid
so maybe u got a wrong handle

punky
10-15-2009, 10:24 PM
for easy understanding errorcode's use this function:
it will display the errorcode in a human readable form
(LPTSTR lpszFunction) can be anystring u call the functions like
ErrorExit(" SetPixel Error"); to know where the GetLastError comes from.



void ErrorExit(LPTSTR lpszFunction) // Any LPTSTR
{
//SetThreadContext
// Retrieve the system error message for the last-error code
// Microsoft funktion
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError(); /// <<<--- the ERROR CODE to translate

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &amp;lpMsgBuf,
0, NULL );

// Display the error message and exit the process

lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("\n%s failed with error %d: %s\n"),
lpszFunction, dw, lpMsgBuf);
printf("<?> %s \n",(LPCTSTR)lpDisplayBuf); // prints the error message

LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);

}

punky
10-15-2009, 11:43 PM
anyway there is no problem using opengl in other window forms as u can see, the Calculator.exe is used here to do OpenGL on(WINDOWs XP):

http://lh4.ggpht.com/_M88JYhzTo4s/StgV6dLeUcI/AAAAAAAAAEc/86pSVhER7Z4/calculator.jpeg
to view this graphic bigger click here:
http://lh4.ggpht.com/_M88JYhzTo4s/StgV6dLeUcI/AAAAAAAAAEc/86pSVhER7Z4/calculator.jpeg