I have a rather large application with multiple threads (such as an Opengl render thread) and a graphical user interface. When clicking the minimize button in the title bar the application closes promptly. However, when clicking Show desktop on the windows taskbar or pressing Win+D or Win+M the application minimizes belatedly (after a few seconds).
I searched the (rather large) code base for occurrences of SC_MINIMIZE, W_MINIMIZE and such without success. I have also paused execution after clicking show desktop to check if some threads are locked, but could not find any problems (but my debugging skills in the area of multithreading are somewhat lacking). Anyways, the prompt minimization from the title bar proves that it should be possible.
I am trying to understand the problem better: What happens differently when the minimize command is coming from outside the application? Where do these commands arrive inside an MFC application?
I expect the application to minimize promptly when clicking Show Desktop in the taskbar or when pressing win+D or win+M. However, it minimizes belatedly.
Additional info:
The CFrameWnd::ActivateFrame(nCmdShow) is called only once when the application is launched.
Here is the creation of the render thread:
m_threadObject = new MyRenderThread();
// If the thread is currently running, return error
if( m_threadObject ->getCurrentStatus() != Stopped )
return false;
m_threadObject ->setCurrentStatus( Initialized );
m_threadObject ->setContinueFlag( true );
// Create the thread
m_threadObject ->handle = AfxBeginThread(_sgThreadInternal::ThreadProc, (void*)m_threadObject);
// if the creation failed, reset status, and return error
if( m_threadObject ->handle == NULL )
{
m_threadObject ->setCurrentStatus( Stopped );
return false;
}
// if the wait flag is set, wait for the status to change
if( waitFlag )
{
while( m_threadObject ->getCurrentStatus() == Initialized )
{
sgThread::sleep(1);
}
}
Communication between threads takes place by sending events back and forth, for example:
MyRenderThread::sendEvent([this, name]()
{
if (!this->load(name))
{
this->unload();
}
} );
But I am not convinced that the threads are the problem. I found out that the OnSysCommand() message handler is called when the minimize button is clicked but not if the show desktop button is clicked. In a test application I created OnSysCommand() is called when show desktop is clicked.
Moar update:
My application is even properly minimized if you create another application, iterate through all windows using EnumWindows() and send
::SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
using my application's window handle.
It seems only show desktop, Win+D and Win+M are blocked.