Jump to content
  • Advertisement
Sign in to follow this  
moeron

Window thread troubles

This topic is 4830 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am writing a renderer that has a seperate thread for the rendering stuff, this is not a problem. The problem comes when I attempt to create a second thread for the window that is being rendered to. I needed to make a seperate thread for the window because my main thread stops while WaitForSingleObject waits for the rendering thread to stop. So I decided to make another thread for my window so it could process its messages...Basically it still does not seem to be responding to user input, though it does invalidate and redraw. Let me show you some sample code and maybe someone could give me some suggestions...By the way, the project is a MFC DLL.
// this is the main CWinApp class
class CRendererApp : public CWinApp
{
// the usual crap...
 
  // allows me to make the message pump still
  // go when my thread is waiting
   virtual DoRun(void)
   {
     return CWinApp::Run();
   }
};
CRendererApp theApp;

// this lets me keep the messages flowing from anywhere
// in my app
int UpdateApp(void)
{
    return theApp.DoRun();
}





BOOL bWindowReady = FALSE;

// here is the Window thread's proc function
u32 __stdcall windowThreadProc(void *pvVoid)
{
   AFX_MANAGE_STATE(AfxGetStaticModuleState());
   if( pvVoid )
   {
       CWnd *parentWindow = reinterpret_cast<CWnd*>(pvVoid);
       CWnd *newWindow = new CWnd();
       LPCSTR lpszClass = AfxRegisterWndClass(CS_OWNDC);
       if( !newWindow->CreateEx(WS_EX_OVERLAPPEDWINDOW,
                       lpszClass,
                       0,0,640,480,0,0,0) )
          return(-1);

       newWindow->ShowWindow(SW_SHOW);
       newWindow->UpdateWindow();

       CRITICAL_SECTION crit;
       ::InitializeCriticalSection(&crit);
       ::EnterCriticalSection(&crit);
       // this tells my main thread that the window is created
       // and ready to render to..
       bWindowReady = TRUE;
       // this is just a copy of a global render abort flag...
       BOOL bCopyAbort= bAbort;
       ::LeaveCriticalSection(&crit);

       // this keeps this thread alive until the window is closed
       // or the user aborts...(both cases change bAbort to TRUE
       while(!bCopyAbort)
       {
         // I originally had all this wrapped up in Critical sections
         // too but it didn't change anything, just slowed it down
         UpdateApp();
         newWindow->UpdateWindow();
         ::EnterCriticalSection(&crit);
         bCopyAbort = bAbort;
         ::LeaveCriticalSection(&crit);
         ::Sleep(30);
       }

       ::DeleteCriticalSection(&crit);         
   }
   return(0);
}

// ok here is where I actually create the window thread
// it is a child of the main DLL thread
BOOL CRenderInterface::InitRender(CWnd *pParentWindow)
{
   AFX_MANAGE_STATE(AfxGetStaticModuleState());
   CRITICAL_SECTION crit;
   ::InitializeCriticalSection(&crit);
   m_hWindowThread = reinterpret_cast<HANDLE>(__beginthreadex( 0,0,
                                                 windowThreadProc,
                                                 pParentWindow,
                                                 0, &m_windowThreadID) );

   ::EnterCriticalSection(&crit);
   BOOL bCopyWindowReady = bWindowReady;
   ::LeaveCriticalSection(&crit);
   while( !bCopyWindowReady )
   {
      // just wait patiently for window to be made...
      ::EnterCriticalSection(&crit);
      bCopyWindowReady = bWindowReady;
      ::LeaveCriticalSection(&crit);
      ::Sleep(100);
   }

   
    // now that my window is made, i create my render thread, it doesn't matter
    // because thats working fine...

    // this call puts my main thread to sleep until my window is closed    
    ::WaitForSingleObject(m_hWindowThread, INFINITE);
    ::CloseHandle(m_hWindowThread);

    // close my render threads too...

    return(0);
}





Can anyone think of any function calls that would make this window properly respond to user interface? Am I just missing something simple? Thanks in advance. moe.ron [edit] fixed some typos

Share this post


Link to post
Share on other sites
Advertisement
The thread that listens to the messages should be the one that created the window in the first place, so make sure that's the case here.

BTW, why make a separate thread here? Can't you just check messages after every frame? I'm no really little MFC, but wasn't there a CApp::doIdle()-function in which you could put your call to the renderer?

Share this post


Link to post
Share on other sites
I make a seperate thread for the window because I thought that would allow it to process messages. I thought if it was on the main thread it too would stop during the WaitForSingleObject call that is waiting for the renderer thread, which is necessary to have as a seperate thread. This isn't a realtime renderer btw, this is a renderer for a 3d application.

I guess I could put the calls in the DoIdle function though...I would have to reorganize how I'm doing things...maybe that is my only choice though.

Share this post


Link to post
Share on other sites
Windows objects aren't really meant to be used in that sort of multithreaded manner. You might get it to kinda work but would have wierd problems. You have a few different alternatives (in no particular order):

Have your new thread do the WaitForSingleObject instead of trying to play with the window. When the wait succeeds do a PostMessage back to the window thread to let it know.

Use MsgWaitForMultipleObjects.

Poll the object during message-loop idle as you were already thinking.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Window message queues are tied to the thread that created the window. It's impossible for a second thread to process the window's messages, because the window's messages are getting sent to the first thread.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!