Click to See Complete Forum and Search --> : CreateWindow fails in thread call


nappaji
January 22nd, 2008, 06:36 PM
CreateWindow fails

--------------------------------------------------------------------------------

I have the following non-threaded code that works fine i.e Window creation is successful.

<code>

INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
WNDCLASSEX m_wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
L"thread", NULL };

RegisterClassEx( &m_wc );

HWND m_hWnd = CreateWindow( L"thread", L"threads",
WS_OVERLAPPEDWINDOW, 100, 100, 800, 800,
NULL, NULL, m_wc.hInstance, NULL );

ShowWindow( m_hWnd, SW_SHOWDEFAULT );
UpdateWindow( m_hWnd );
for ( ;; )
return 0;
}
<\code>

I am trying to convert this to a threaded application (I am new to Windows threading);
When I call the CreateWindow in the worker thread, it crashes at the CreateWindow call; Below is the code


<code>
DWORD WINAPI ThreadFunc( LPVOID lpParam )
{
WNDCLASSEX m_wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
L"thread", NULL };

RegisterClassEx( &m_wc );

HWND m_hWnd = CreateWindow( L"thread", L"threads",
WS_OVERLAPPEDWINDOW, 100, 100, 800, 800,
NULL, NULL, m_wc.hInstance, NULL );

ShowWindow( m_hWnd, SW_SHOWDEFAULT );
UpdateWindow( m_hWnd );

return 0;
}


//-----------------------------------------------------------------------------
// Name: wWinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
DWORD dwThreadId, dwThrdParam = 1;
HANDLE hThread;

hThread = CreateThread(
NULL, // default security attributes
0, // use default stack size
ThreadFunc,
&dwThrdParam, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier

// Check the return value for success.

if (hThread == NULL)
{
printf( "CreateThread failed (%d)\n", GetLastError() );
}
else
{
CloseHandle( hThread );
}
}
<\code>

MikeAThon
January 25th, 2008, 07:36 PM
Your WinMain function exits right after it creates the thread. This kills the thread too.

Try modifying WinMain to keep it alive. For example, put a call to getchar() in it, so that it stays alive until you enter a character.

Mike

PS: The general consensus is that it is a bad idea to create windows from within a thread. All windows should be created from the main thread. If you are new to Windows threading, then the reasons for this advice might be a bit obscure, so you probably should simply heed the advice, and re-think you design so that all windows are created from the main thread.

nappaji
January 25th, 2008, 07:45 PM
Thanks MikeAThon.

I have one more question.
Is it possible to send notification messages from child thread to parent that created the thread?

SendMessage requires a window, but my parent does not have a window.
can i use the SendThreadMessage to send from thread to parent process?

Thanks!

MikeAThon
January 25th, 2008, 08:11 PM
Yes, you can use PostThreadMessage (not SendThreadMessage, which doesn't exist), but only if (1) your main thread does not create any windows, (2) your main thread calls PeekMessage() once to create a message queue, and (3) your main thread is running a GetMessage()-style message loop that searches for the posted message

See http://msdn2.microsoft.com/en-us/library/ms644946(VS.85).aspx and http://msdn2.microsoft.com/en-us/library/ms644928(VS.85).aspx

Mike

PS: The questions you are asking are a small part of the reason why threads should not create windows.

nappaji
January 25th, 2008, 08:25 PM
Thanks again!
So, can I use PostThreadMessage(GetCurrentProcessId(), msg, lParam, wParam) ??

In my child process, I have a message handler procedure, which handles all the messages from the window, such as WM_DESTROY etc.

From the child's MsgProc, I want to send the msg to the parent message handler procedure.

To use PostThreadMessage, I need the threadId. Can I use the processID here? I tried it and it seems to not work.

MikeAThon
January 26th, 2008, 11:37 AM
So, can I use PostThreadMessage(GetCurrentProcessId(), msg, lParam, wParam) ??
No. PostThreadMessage requires a thread identifier, not a process identifier.

You need to provide the child thread with thre thread identifier of the main thread, The main thread can find this value using GetCurrentTheadId().

Your goals in doing all this are completely unclear. Again, since you are new to windows threading, I strongly recommend to jettison this entire approach until you understand the reasons, and can explain them to others, why child threads should not create windows.

Mike