首页 > 解决方案 > MFC - 发送 WM_IDLEUPDATECMDUI 消息时出现奇怪的访问冲突

问题描述

我目前正在修改旧 MFC 应用程序的代码,我已更新该应用程序以使用 Visual Studio 2017 进行编译。此应用程序包含多个 MDI 框架。

但是,当我关闭这些我无法弄清楚的框架时,会随机发生奇怪的访问冲突,主要形式如下:

BOOL PSS_App::OnIdle(LONG count)
{
    if (!count)
        if (m_pMainWnd)
        {
            // look for any top-level windows owned by this class. NOTE handlers are used to
            // avoid generation of too many temporary CWnds
            for (HWND hWnd = ::GetWindow(m_pMainWnd->m_hWnd, GW_HWNDFIRST); hWnd; hWnd = ::GetNextWindow(hWnd, GW_HWNDNEXT))
                if (::GetParent(hWnd) == m_pMainWnd->m_hWnd)
                {
                    // if owned window is active, move the activation to the application window
                    if (GetActiveWindow() == hWnd && !::GetCapture())
                        m_pMainWnd->SetActiveWindow();

                    // update the buttons for the top-level window
                    ::SendMessage(hWnd, WM_IDLEUPDATECMDUI, WPARAM(TRUE), 0L);
                }
        }

    return CWinApp::OnIdle(count);
}

调用该::SendMessage(hWnd, WM_IDLEUPDATECMDUI, WPARAM(TRUE), 0L);函数时会发生此问题。我尝试使用以下代码获取 hWnd 类名:

char lpClassName[256];
::GetClassName(hWnd, lpClassName, 256);

我得到tooltips_class32了结果,但我不知道它指的是哪个类。如果我尝试按以下方式修改代码:

// update the buttons for the top-level window
if (std::strcmp(lpClassName, "tooltips_class32") != 0)
    ::SendMessage(hWnd, WM_IDLEUPDATECMDUI, WPARAM(TRUE), 0L);

这个问题不再发生在这个函数中,我可以毫无问题地关闭我的子 MDI 框架,但是当主窗体失去焦点时(例如,当我在应用程序外部单击时)会随机发生另一个访问冲突。

有人可以向我解释这里发生了什么,或者至少向我提供有关可能发生的事情的信息吗?究竟tooltips_class32是什么,在 MFC 中哪种类可以继承它?或者是一个ActiveX 相关的控件?

注意我不知道它是否有链接,但主应用程序继承自 CWinApp,它继承自 CWinThread。该应用程序没有使用多线程,除了初始屏幕。但是,即使我完全停用启动画面代码,问题仍然存在。

另请注意,该应用程序是一个巨大的应用程序,包含大约 30 个附加的 DLL。我现在无法在 Debug 中运行它,因为加载时其中一个模块中发生了另一个奇怪的访问冲突,这发生在 Debug 中,但从未在 Release 中。因此,该应用程序当前正在发布中运行。

标签: c++visual-studio-2017mfcaccess-violationsendmessage

解决方案


推荐阅读