处理选项卡停止使用DispatchMessage()而不通过消息循环阻止线程?

时间:2018-10-31 01:21:48

标签: c++ windows winapi visual-c++ win32gui

我在DLL中为UI视图提供了一个导出OpenUI()的功能,该功能可创建无模式的主对话框,并且还具有无模式的子对话框。

我从一个单独的DLL(我的控制器)中调用函数export OpenUI()。

如果OpenUI()中的消息循环阻止了函数的返回,除非关闭对话框,如何在函数调用后执行更多代码? 我无法删除消息循环,因为没有它,制表位将无法工作。

我需要函数导出以在执行后立即返回,因此我不能使用模式对话框。创建子线程也不是一种选择,因为它导致我的应用程序出现问题。

我们非常感谢您的帮助。 谢谢。

我的控制器dll的伪代码

 typedef int(*DLL_OPENUI)();
    int func()
    {
        HINSTANCE hinst_dll = LoadLibrary(dll_path);
        DLL_OPENUI DllOpenUI = (DLL_OPENUI)GetProcAddress(hinst_dll, "OpenUI");
        int ret = DllOpenUI();

        //...execute more code here

        return ret;
    }

我的UI视图dll的伪代码

__declspec(dllexport) OpenUI()
{
    hwnd_main = CreateDialog(hinst, IDD_MAIN, MainDlgProc);
    ShowWindow(hwnd_main, SW_SHOW);

    MSG msg;
    while ((GetMessage(&msg, NULL, 0, 0) > 0))
    {
        if (!IsDialogMessage(hwnd, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return 0;
}

LRESULT CALLBACK  MainDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message) 
    {
        case WM_INITDIALOG:
        OnInitDialog();
        break;
    }
}

void OnInitDialog()
{
    CreateDialog(hinst, IDD_NAV_PANE, hwnd_main, NavPaneProc);
    CreateDialog(hinst, IDD_NAV_TABS, hwnd_main, NavTabsProc);
    CreateDialog(hinst, IDD_TAB_1, hwnd_main, TabOneProc);
    CreateDialog(hinst, IDD_TAB_2, hwnd_main, TabTwoProc);
    CreateDialog(hinst, IDD_TAB_3, hwnd_main, TabThreeProc);
    CreateDialog(hinst, IDD_DETAILS_PANE_BG, hwnd_main, BackgroundProc);
    CreateDialog(hinst, IDD_DETAILS_PANE, hwnd_main, DetailsPaneProc);

    //...execute more code below
}

1 个答案:

答案 0 :(得分:0)

您必须有一个活动的消息循环,无法解决。一种实现方法是拥有一个新函数,该函数将PeekMessage并且仅执行一次循环代码。如果后续对PeekMessage的调用实际上会得到一条消息而不是阻塞,则GetMessage返回非零值。 ProcessOneMessage可能看起来像这样:

BOOL ProcessOneMessage(HWND hwnd)
{
    MSG msg;
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
       if (msg.message == WM_QUIT)
          return TRUE;

       TranslateMessage(&msg);
       DispatchMessage(&msg);
    }

    return FALSE;
}

因此,在您的主代码中,您必须经常调用此函数(每10毫秒一次就可以了)。无论代码执行什么操作,它都必须在10毫秒内调用一次该函数。您将拥有一个活动窗口并同时运行您的代码。但是一旦函数返回TRUE,则窗口将关闭,并且您不得再次调用该函数。有关更多信息,请搜索PeekMessage。该代码来自以下链接:https://jeffpar.github.io/kbarchive/kb/074/Q74042/