Click to See Complete Forum and Search --> : Changing MFC GDI in thread


Ergodyne
June 3rd, 2010, 05:58 AM
Hello,

I have an MCF application in which I have started several CWinThreads that interact with the main window.

Now I'm trying to change the system menu in the window in one of the threads, but my attempts at this have so long failed. Is this not possible?

At first I tried this, which gave me an exception in runtime
AfxGetMainWnd()->GetSystemMenu(FALSE)->EnableMenuItem( SC_CLOSE, MF_BYCOMMAND | MF_ENABLED );

After some googling, I realized that this has to be thread safe and so I have tried different variants of this.
The below now runs in the code, but it doesn't enable the close button as desired. (The close button has been disabled by the main window before starting the WinThreads.

HMENU hMenu =AfxGetMainWnd()->GetSystemMenu(FALSE)->GetSafeHmenu();
EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_ENABLED );

Any hints on how one can do this?

VictorN
June 3rd, 2010, 06:23 AM
Your approach is completely wrong: you must not access any CWnd objects from another thread.
Instead you should post (PostMessage) a user defined message from your worker thread to the main thread window notifying it that it has to change something (in this particular case - to enable SC_CLOSE button), then in the message handler of the main window class you execute the code to enable SC_CLOSE.

Note also that AfxGetMainWnd returns different pointers for different threads, and if thread has no window then the returned pointer is temporary (doesn't correspond any real window)!

BTW, your question has nothing to do with GDI!

Ergodyne
June 3rd, 2010, 06:32 AM
Thanks for the advice! I will try using messages.

Since the application uses GDI I threw that in, but yes you are right, the question does not have anything to do with that.

VictorN
June 3rd, 2010, 07:35 AM
I'd recommend you to read this essay: Using Worker Threads (http://www.flounder.com/workerthreads.htm)