windows 添加文本输入窗口时,WIN32GUI菜单栏未呈现

yftpprvb  于 2023-08-07  发布在  Windows
关注(0)|答案(2)|浏览(135)

概要

当在下面的行中调用CreateWindowW时,使用AppendMenu示例化的GUI菜单栏消失。

CreateWindowW(L"Edit", L"...", WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL, 200, 152, 100, 50, hWnd, NULL, NULL, NULL);

字符串
这个对CreateWindowW的调用创建了一个文本输入框。
下面的两个图像显示了GUI窗口,其中(1)和(2)注解掉了上面的代码行。
GUI,而不破坏CreateWindowW调用:

的数据
带有错误CreateWindowW调用的GUI:

编码

#include <Windows.h>
#include <sal.h>


constexpr auto FILE_DROPDOWN_ID = 1;
constexpr auto HELP_POPUP_ID = 2;
constexpr auto LOAD_DROPDOWN_ID = 3;
constexpr auto LOAD_TSD_NO_OFFSET = 4;
constexpr auto FILE_MENU_EXIT = 5;
constexpr auto CHANGE_TITLE = 6;

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);

void AddMenus(HWND);
void AddControls(HWND);
void AddMenusAndControls(HWND);

HMENU hMenu;

//int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow) {
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) {
    
    //MessageBox(NULL, L"Upconverter Start up", L"Please load your file", MB_OK);

    WNDCLASSW wc = { 0 };
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW; // Define window background
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hInstance = hInstance;
    wc.lpszClassName = L"myWindowClass";
    wc.lpfnWndProc = WindowProcedure;

    if (!RegisterClassW(&wc)) // Pass as reference because arg is type pointer
        return -1;

    CreateWindowW(L"myWindowClass", L"My Window Name", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 200, 500, 500,
        NULL, NULL, NULL, NULL);

    // Event driven loop

    MSG msg = { 0 }; 

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

    return 0;
}

LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
    switch (msg)
    {
    case WM_COMMAND: // Triggered for every button or menu item. Tells us that something has been clicked. 

        switch (wp)  // This switch statement governs the resultant behavior of a button press on the main window. 
        {
        //case FILE_DROPDOWN_ID:
            //MessageBeep(MB_DEFBUTTON1);
        case HELP_POPUP_ID:
            MessageBeep(MB_DEFBUTTON2);
        case FILE_MENU_EXIT:
            DestroyWindow(hWnd);
        case LOAD_DROPDOWN_ID:
            MessageBeep(MB_ICONINFORMATION);
            break;
        case CHANGE_TITLE:
            
            break;
        }

    case WM_CREATE:
        //AddControls(hWnd);
        //AddMenus(hWnd);
        AddMenusAndControls(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefMDIChildProcW(hWnd, msg, wp, lp);
    }
}

void AddMenusAndControls(HWND hWnd) {

    hMenu = CreateMenu();
    HMENU hFileMenu = CreateMenu();
    HMENU hSubMenu = CreateMenu();

    AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, L"File");
        AppendMenu(hFileMenu, MF_STRING, LOAD_DROPDOWN_ID, L"New");
        AppendMenu(hFileMenu, MF_POPUP, (UINT_PTR)hSubMenu, L"Open Submenu");
            AppendMenu(hSubMenu, MF_STRING, CHANGE_TITLE, L"Change Title");
        AppendMenu(hFileMenu, MF_SEPARATOR, NULL, NULL);
        AppendMenu(hFileMenu, MF_STRING, FILE_MENU_EXIT, L"Exit");
    
    AppendMenu(hMenu, MF_STRING, HELP_POPUP_ID, L"Help");
    

    CreateWindowW(L"static", L"Enter text here: ", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, 200, 100, 100, 50, hWnd, NULL, NULL, NULL);
    CreateWindowW(L"Edit", L"...", WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL, 200, 152, 100, 50, hWnd, NULL, NULL, NULL); // WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL

    SetMenu(hWnd, hMenu);
}

void AddMenus(HWND hWnd) {

    hMenu = CreateMenu();
    HMENU hFileMenu = CreateMenu();
    HMENU hSubMenu = CreateMenu();

    AppendMenu(hSubMenu, MF_STRING, CHANGE_TITLE, L"Change Title");

    AppendMenu(hFileMenu, MF_STRING, LOAD_DROPDOWN_ID, L"New");
    AppendMenu(hFileMenu, MF_POPUP, (UINT_PTR)hSubMenu, L"Open Submenu");
    AppendMenu(hFileMenu, MF_SEPARATOR, NULL, NULL);
    AppendMenu(hFileMenu, MF_STRING, FILE_MENU_EXIT, L"Exit");

    AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, L"File");
    AppendMenu(hMenu, MF_STRING, HELP_POPUP_ID, L"Help");

    SetMenu(hWnd, hMenu);

}

void AddControls(HWND hWnd) {
    CreateWindowW(L"static", L"Enter text here: ", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, 200, 100, 100, 50, hWnd, NULL, NULL, NULL);
    CreateWindowW(L"Edit", L"...", WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL, 200, 152, 100, 50, hWnd,
        NULL, NULL, NULL); // WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL
}

讨论

我怀疑它与窗口句柄hWnd有关,允许覆盖窗口内容。因此,我更改了之前hWnd的两个通道

case WM_CREATE:
        AddControls(hWnd);
        AddMenus(hWnd);


一个函数调用。

case WM_CREATE:
        AddMenusAndControls(hWnd);


但这没有效果。它也可能与SetMenu有关,但我不确定是什么方式。我尝试将SetMenu调用移动到AddMenusAndControls中的不同行,也没有效果。
这是怎么回事
感谢你的帮助。

nqwrtyyt

nqwrtyyt1#

你的窗口程序被严重破坏了。它有一个非void返回类型,但是除了default:之外,它在所有路径上都没有返回任何东西。
窗口过程的正确结构是在函数的末尾无条件地调用默认窗口过程**。任何不应传递给默认窗口过程的消息都需要通过return退出其case(并指定返回值),而不是break
变更

case WM_DESTROY:
    PostQuitMessage(0);
    break;
default:
    return DefMDIChildProcW(hWnd, msg, wp, lp);
}

字符串

case WM_DESTROY:
    PostQuitMessage(0);
    break;
}
return DefWindowProcW(hWnd, msg, wp, lp);


我还修复了你选择调用哪个默认窗口过程的问题,因为你的WinMain似乎把这个窗口用作顶层框架,而不是MDI子窗口。
因为MDI子控件在焦点改变时自动将其菜单迁移到MDI父控件,并且因为您正在添加一个能够接收焦点的新子控件(在框架具有焦点之前),所以很可能发送到窗口的与焦点相关的消息发生了变化,并且由于您忠实地转发了它们,因此您获得了所要求的MDI菜单行为(即使您不想要它)。如果你没有MDI,不要使用DefMDIChildProcW

yruzcnhs

yruzcnhs2#

switch(msg){ case WM_COMMAND://为每个按钮或菜单项触发。告诉我们有东西被点击了。

switch (wp)  // This switch statement governs the resultant behavior of a button press on the main window. 
    {
    //case FILE_DROPDOWN_ID:
        //MessageBeep(MB_DEFBUTTON1);
    case HELP_POPUP_ID:
        MessageBeep(MB_DEFBUTTON2);
    case FILE_MENU_EXIT:
        DestroyWindow(hWnd);
    case LOAD_DROPDOWN_ID:
        MessageBeep(MB_ICONINFORMATION);
        break;
    case CHANGE_TITLE:
        
        break;
    }
    break; ///THIS WAS CAUSING ERROR ADD THIS BREAK;
case WM_CREATE:
    //AddControls(hWnd);
    //AddMenus(hWnd);
    AddMenusAndControls(hWnd);
    break;

字符串

相关问题