单击显示桌面/最小化所有时,应用程序会延迟最小化

Application minimizes belatedly when clicking show desktop /minimize all

我有一个相当大的应用程序,它有多个线程(例如 Opengl 渲染线程)和一个图形用户界面。单击标题栏中的最小化按钮时,应用程序会立即关闭。 但是,当单击 windows 任务栏上的显示桌面或按 Win+D 或 Win+M 时,应用程序会延迟最小化(几秒钟后)。

我在(相当大的)代码库中搜索了 SC_MINIMIZE、W_MINIMIZE 等,但没有成功。我也点了show desktop后暂停执行,检查有没有线程被锁,也没发现什么问题(不过我在多线程方面的debug能力有点欠缺)。不管怎样,标题栏的提示最小化证明应该可以。

我试图更好地理解问题:当最小化命令来自应用程序外部时会发生什么不同?这些命令到达 MFC 应用程序中的什么位置?

我希望应用程序在单击任务栏中的“显示桌面”或按 win+D 或 win+M 时迅速最小化。但是,它会延迟最小化。

附加信息:

CFrameWnd::ActivateFrame(nCmdShow) 在应用程序启动时仅调用一次。

渲染线程的创建如下:

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);
    }
}

线程之间的通信通过来回发送事件发生,例如:

MyRenderThread::sendEvent([this, name]()
{
    if (!this->load(name))
    {
        this->unload();
    }
} );

但我不认为线程是问题所在。 我发现单击最小化按钮时会调用 OnSysCommand() 消息处理程序,但如果单击显示桌面按钮则不会调用。在我创建的测试应用程序中,单击显示桌面时将调用 OnSysCommand()。

摩尔更新:

如果您创建另一个应用程序,我的应用程序甚至可以适当地最小化,使用 EnumWindows() 遍历所有 windows 并发送

::SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);

使用我的应用程序的 window 句柄。

好像只显示桌面,Win+D和Win+M都被屏蔽了

我找到了这段代码:

BOOL CMyApplicationApp::OnIdle(LONG lCount)
{
    CWinApp::OnIdle(lCount);

    [...]

    ::Sleep(5);
    if(m_mainFrame->IsIconic())
    {
        ::Sleep(100);
    }

    ::SwitchToThread();

    return TRUE;
}

阅读文档中有关 CWinApp::OnIdle() 的内容后,我确信 sleep() 的部分是多余的。我假设原始开发人员想要节省 CPU 周期或其他东西。删除代码后,应用程序会立即最小化。