【问题标题】:Windows: Message-only window appears when I call back from native to managed codeWindows:当我从本机代码回调到托管代码时,出现仅消息窗口
【发布时间】:2011-06-07 15:26:04
【问题描述】:

经过一番努力,我设法从第三方 MFC dll 中捕获了 Windows 消息(我问过这个问题here)。简而言之,我必须创建一个带有消息循环的仅消息窗口,该窗口捕获第三方 dll 的消息。

所述仅消息窗口必须保持隐藏状态。最初确实如此,因为我将 HWND_MESSAGE 传递给 CreateWindowEx 并使用 SW_HIDE 调用 ShowWindow。 但是,我的 C++ dll 对托管代码有一些回调。我注意到,当我执行触发第一个操作的用户操作时,会出现一个控制台窗口。直到我关闭我的应用程序才会消失。

由于控制台窗口以我的应用程序的可执行路径作为其标题,我认为该窗口以某种方式与我的应用程序相关联。于是我把NULL传给了CreateWindowEx的hInstance参数,但是没有用。

这是我的仅消息窗口代码:

DWORD WINAPI CDRTech::MessageLoopThread( void * pParams ){
    HWND hwnd;
    MSG mensaje;
    WNDCLASSEX wincl;
    const string windowClass = "DR_TECH_MESSAGE_HANDLER";

    // Window class
    wincl.hInstance = ::GetModuleHandle(NULL);
    wincl.lpszClassName = windowClass.c_str();
    wincl.lpfnWndProc = ::DefWindowProc;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof (WNDCLASSEX);
    wincl.hIcon = ::LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = ::LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = ::LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = ::GetSysColorBrush(COLOR_BACKGROUND);
    if(!::RegisterClassEx(&wincl)){
        ::GetErrorLoggerInstance()->Log( LOG_TYPE_ERROR, "CDRTech", "MessageLoopThread", "Could not register Message Handling Window" );
        return 0;
    }

    //Create Window (hidden)
    hwnd = ::CreateWindowEx(
            0,                      //Default ExStyle
            windowClass.c_str(),    //Window class
            "DRTech",               //Window Title
            WS_OVERLAPPEDWINDOW,    //Default Style
            CW_USEDEFAULT,          //Let Windows decide position
            CW_USEDEFAULT,
            10,                     //Width
            10,                     //Height
            HWND_MESSAGE,           //Message-only window
            NULL,                   //No Menu
            NULL,                   //Handle to application
            NULL                    //Window creation data
    );
    ::ShowWindow( hwnd, SW_HIDE );

    CDRTech* pThis = reinterpret_cast<CDRTech*>( pParams );
    pThis->InitDRTechLibrary();
    //Start message loop
    while(TRUE == GetMessage(&mensaje, NULL, 0, 0)){
        TranslateMessage(&mensaje);
        DispatchMessage(&mensaje);
    }
    return mensaje.wParam;
}

【问题讨论】:

    标签: c++ winapi window hide messages


    【解决方案1】:

    您创建的窗口与您看到的控制台窗口无关。您调用的东西会创建一个控制台窗口(或者您的程序被标记为控制台应用程序,在这种情况下,控制台是在您的应用程序启动时创建的)。

    AllocConsole() 处设置断点以查找创建控制台的人员。

    【讨论】:

    • 我的代码中没有调用 AllocConsole(),我该怎么做?我的程序是一个 Windows 窗体应用程序。
    • 您可以在函数上放置断点,即使它们不在您的代码中。在 WinDbg 中,您只需键入 bp kernel32!AllocConsole。在 Visual Studio 中按 Ctrl+B 并键入 AllocConsole。此外,如果您使用 Visual Studio,请务必取消选中“仅显示我的代码”选项。
    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-24
    • 1970-01-01
    • 2011-01-21
    • 2020-06-21
    相关资源
    最近更新 更多