【问题标题】:Application minimizes belatedly when clicking show desktop /minimize all单击显示桌面/最小化所有时应用程序最小化
【发布时间】:2026-01-28 10:55:02
【问题描述】:

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

我在(相当大的)代码库中搜索了 SC_MINIMIZE、W_MINIMIZE 等的出现,但没有成功。在点击显示桌面后我也暂停了执行,检查是否有线程被锁定,但没有发现任何问题(但我在多线程方面的调试技巧有些欠缺)。无论如何,从标题栏提示最小化证明它应该是可能的。

我试图更好地理解问题:当最小化命令来自应用程序外部时会发生什么不同?这些命令在 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() 遍历所有窗口并发送

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

使用我的应用程序的窗口句柄。

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

【问题讨论】:

  • 显示一些代码。如何创建工作线程和 UI 线程,如何在线程之间进行通信。对于调试,只需在 CFrameWnd::ActivateFrame(nCmdShow) 中设置一个断点,然后观察 CallStack。
  • 用代码和更多信息更新了我的问题。

标签: c++ mfc windows-7-x64


【解决方案1】:

我找到了这段代码:

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

    [...]

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

    ::SwitchToThread();

    return TRUE;
}

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

【讨论】:

    最近更新 更多