Problem using SetPixelFormat function

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(&msg, (HWND) NULL, 0, 0)) != 0 && fGotMessage != -1) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&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(&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, &pfd1); 
if( 0 == iPixelFormat)
{
	errCode=GetLastError();
}

 

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

", (UINT)errCode);

	}


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

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

 retCode=ShowWindow(      
 hfoundWND,
SW_HIDE);







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

}

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.

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

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) &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("
%s failed with error %d: %s
"),
	lpszFunction, dw, lpMsgBuf);
	printf("<?>  %s 
",(LPCTSTR)lpDisplayBuf); // prints the error message

      LocalFree(lpMsgBuf);
	LocalFree(lpDisplayBuf);
 
	}

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):


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