Click here to Skip to main content
15,881,803 members
Please Sign up or sign in to vote.
3.00/5 (1 vote)
See more:
Hi,
I am trying to print random numbers on a window using a thread named MyThread1 through C - Win32 programming.
But it does not update the main window and i see the main window being blank always.
Below is the pseudo code.

C++
VOID MyThread1( PVOID pvoid )
{
   HDC hdc;

   TCHAR szBuff[10];
   hdc = GetDC( hwnd );
   wsprintf( szBuff, TEXT("%d"), rand() );
   TextOut( hdc, rand(), rand(), szBuff, lstrlen( szBuff ) );
   ReleaseDC( hwnd );

}

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM, wParam, LPARAM lParam )
{
   switch( message )
   {
     case WM_CREATE:
          for( int i = 0; i < 10; i++ )
             _beginthread( MyThread1, 0, NULL );
     case WM_DESTROY:
          PostQuitMessage( 0 );
          break;
   }
   return DefWindowProc( hwnd, message, wParam, lParam );
}


Instead of using multiple threads i m using single thread to print random chars at random position on the main window.
Please let me know is this the right way or am i going wrong somewhere in between.

Thanks
Posted
Updated 2-Oct-11 6:50am
v2
Comments
André Kraak 2-Oct-11 12:51pm    
Edited question:
Added pre tags

1 solution

Writing on DC from the other thread is absolutely useless and even dangerous. All rendering should occur in the handler of a Windows message WM_PAINT. It always happens in your UI thread. So, the question is: how to make the rendered graphics changing with time and trigger this message? Well, not be sending or posting it. It's done via the Windows API Invalidate. In order to improve performance you can also call InvalidateRect or InvalidateRect with parameter (rectangle or region) to invalidate only the part of the scene.
See http://msdn.microsoft.com/en-us/library/dd145005%28v=vs.85%29.aspx[^].

Now, how to change graphics from a separate thread to create some animation effect? First of all, your thread makes no sense as it writes graphical data only once, but you could make the thread running in cycle with some delay, generating different text in each iteration. To do this, have a shared memory holding, say, the string you output. As this memory should be used by two threads (the string will be written by the thread you created and read by your UI thread), addressing to this memory should be inter-locked using critical section (this is the most light-weight method), via the methods EnterCriticalSection/LeaveCriticalSection, see:
http://en.wikipedia.org/wiki/Critical_section[^],
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682608%28v=vs.85%29.aspx[^],
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684169(v=vs.85).aspx[^].

You additional (non-UI) thread should only modify this data and notify your UI thread about the change by invalidating the client area of the window.

—SA
 
Share this answer
 
v2
Comments
Espen Harlinn 3-Oct-11 15:43pm    
Good reply, as usual :)
Sergey Alexandrovich Kryukov 3-Oct-11 18:11pm    
Thank you, Espen.
--SA
Sergey Alexandrovich Kryukov 3-Oct-11 18:20pm    
By the way, the term "parent window" is inaccurate. A parent to what? A window cannot be a parent to a thread. Normally, it's only a parent to its controls.
--SA
Chuck O'Toole 3-Oct-11 19:05pm    
Good answer. Didn't I read somewhere that Windows actually "fails" calls that try to manipulate a windows that belongs to a different thread? Or maybe that's just the CWnd derived windows. I forget and can't find the reference right now.
Espen Harlinn 3-Oct-11 19:11pm    
The API is "mostly" thread safe, wrapper libraries are usually not ...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900