为什么弹出菜单在WINAPI中不起作用?

问题描述 投票:0回答:1

我目前正在使用 Windows API 开发 Windows 桌面应用程序。我对 API 还很陌生,所以我正在使用 Visual Studio Community 提供的一些可视化帮助进行开发。

结构很简单:我有一个主窗口,其中放置了一些文本框和一个菜单。

如果我像这样创建窗口:

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int cShow) {

    MSG msg;
    HWND hVentana;

    WNDCLASSEX wc;

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = 0;
    wc.lpfnWndProc = cVentana;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = L"MainWindowClass";
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&wc)) {
        MessageBox(NULL, L"Fallo al registrar la clase de ventana.", L"Error", MB_OK | MB_ICONERROR);
        return 0;
    }

    hVentana = CreateWindowEx(0, L"MainWindowClass", L"Emulador", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1600, 900, NULL, NULL, hInst, NULL);

    if (!hVentana) {
        MessageBox(NULL, L"Fallo al crear la ventana.", L"Error", MB_OK | MB_ICONERROR);
        return 0;
    }

    HMENU hMenu = LoadMenu(hInst, L"IDD_MENU1");    // El menu está definido en resource.rc

    SetMenu(hVentana, hMenu);
    
    HWND hTextBox = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY | ES_AUTOVSCROLL | ES_MULTILINE,
        10, 10, 387, 824, hVentana, NULL, GetModuleHandle(NULL), NULL);
    
    HWND hRamBox = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY | ES_AUTOVSCROLL | ES_MULTILINE,
        407, 477, 785, 309, hVentana, NULL, GetModuleHandle(NULL), NULL);
    
    HWND hSearchBox = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
        407, 796, 785, 38, hVentana, NULL, GetModuleHandle(NULL), NULL);

    HWND hTerminalBox = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY | ES_AUTOVSCROLL | ES_MULTILINE,
        407, 60, 785, 405, hVentana, NULL, GetModuleHandle(NULL), NULL);
    
    HWND hRegistrosBox = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY | ES_AUTOVSCROLL | ES_MULTILINE,
        1202, 10, 374, 824, hVentana, NULL, GetModuleHandle(NULL), NULL);

    ShowWindow(hVentana, cShow);
    UpdateWindow(hVentana);

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

没问题。

但是,如果我这样做:

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int cShow) {

    MSG msg;
    HWND hVentana;
    hVentana = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, cVentana);


    ShowWindow(hVentana, cShow);
    UpdateWindow(hVentana);

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

显示菜单,但如果我将鼠标悬停在任何项目上,则不会弹出该项目的选项。

我这里有菜单资源和对话框资源:

/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDD_MENU1 MENU
BEGIN
    POPUP "Archivo"
    BEGIN
        MENUITEM "Cargar programa",             ID_LOADPROGRAM
        MENUITEM "Cargar campaña",              ID_LOADCAMPAING
        MENUITEM "Salir",                       ID_EXIT
    END
    POPUP "Generar"
    BEGIN
        MENUITEM "Informe de instrucciones",    ID_GENERAR_INFORMEDEINSTRUCCIONES
        MENUITEM "Archivo RAM",                 ID_GENERAR_ARCHIVORAM
    END
END


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_DIALOG1 DIALOGEX 0, 0, 1600, 900
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CAPTION | WS_SYSMENU
CAPTION "Emulador"
MENU IDD_MENU1
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    EDITTEXT        IDC_TEXTBOX,10,10,387,824,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_TABSTOP
    EDITTEXT        IDC_RAMBOX,407,477,785,309,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_TABSTOP
    EDITTEXT        IDC_SEARCHBOX,407,796,785,38,ES_AUTOHSCROLL | NOT WS_TABSTOP
    EDITTEXT        IDC_TERMINALBOX,407,60,785,405,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_TABSTOP
    EDITTEXT        IDC_REGISTERSBOX,1202,10,374,824,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_TABSTOP
END

如果资源文件中包含所有对话框就好了,所以如果有其他方法可以制作它,请随时告诉我。

注意:此外,出于任何原因,当我使用第一种形式时,窗口的尺寸是正确的,但如果我使用第二种形式,则窗口比我指定的尺寸大。

c++ winapi
1个回答
0
投票

使用

CreateDialog()
时,您需要在调用
IsDialogMessage()
+
TranslateMessage()
之前将
DispatchMessage()
添加到消息循环中,例如:

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int cShow) {

    MSG msg;
    HWND hVentana = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, cVentana);

    ShowWindow(hVentana, cShow);
    UpdateWindow(hVentana);

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

    return msg.wParam;
}
© www.soinside.com 2019 - 2024. All rights reserved.