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

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

概要

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

  1. 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:

编码

  1. #include <Windows.h>
  2. #include <sal.h>
  3. constexpr auto FILE_DROPDOWN_ID = 1;
  4. constexpr auto HELP_POPUP_ID = 2;
  5. constexpr auto LOAD_DROPDOWN_ID = 3;
  6. constexpr auto LOAD_TSD_NO_OFFSET = 4;
  7. constexpr auto FILE_MENU_EXIT = 5;
  8. constexpr auto CHANGE_TITLE = 6;
  9. LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
  10. void AddMenus(HWND);
  11. void AddControls(HWND);
  12. void AddMenusAndControls(HWND);
  13. HMENU hMenu;
  14. //int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow) {
  15. int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) {
  16. //MessageBox(NULL, L"Upconverter Start up", L"Please load your file", MB_OK);
  17. WNDCLASSW wc = { 0 };
  18. wc.hbrBackground = (HBRUSH)COLOR_WINDOW; // Define window background
  19. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  20. wc.hInstance = hInstance;
  21. wc.lpszClassName = L"myWindowClass";
  22. wc.lpfnWndProc = WindowProcedure;
  23. if (!RegisterClassW(&wc)) // Pass as reference because arg is type pointer
  24. return -1;
  25. CreateWindowW(L"myWindowClass", L"My Window Name", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 200, 500, 500,
  26. NULL, NULL, NULL, NULL);
  27. // Event driven loop
  28. MSG msg = { 0 };
  29. while (GetMessage(&msg, NULL, NULL, NULL)) {
  30. TranslateMessage(&msg);
  31. DispatchMessage(&msg);
  32. }
  33. return 0;
  34. }
  35. LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
  36. switch (msg)
  37. {
  38. case WM_COMMAND: // Triggered for every button or menu item. Tells us that something has been clicked.
  39. switch (wp) // This switch statement governs the resultant behavior of a button press on the main window.
  40. {
  41. //case FILE_DROPDOWN_ID:
  42. //MessageBeep(MB_DEFBUTTON1);
  43. case HELP_POPUP_ID:
  44. MessageBeep(MB_DEFBUTTON2);
  45. case FILE_MENU_EXIT:
  46. DestroyWindow(hWnd);
  47. case LOAD_DROPDOWN_ID:
  48. MessageBeep(MB_ICONINFORMATION);
  49. break;
  50. case CHANGE_TITLE:
  51. break;
  52. }
  53. case WM_CREATE:
  54. //AddControls(hWnd);
  55. //AddMenus(hWnd);
  56. AddMenusAndControls(hWnd);
  57. break;
  58. case WM_DESTROY:
  59. PostQuitMessage(0);
  60. break;
  61. default:
  62. return DefMDIChildProcW(hWnd, msg, wp, lp);
  63. }
  64. }
  65. void AddMenusAndControls(HWND hWnd) {
  66. hMenu = CreateMenu();
  67. HMENU hFileMenu = CreateMenu();
  68. HMENU hSubMenu = CreateMenu();
  69. AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, L"File");
  70. AppendMenu(hFileMenu, MF_STRING, LOAD_DROPDOWN_ID, L"New");
  71. AppendMenu(hFileMenu, MF_POPUP, (UINT_PTR)hSubMenu, L"Open Submenu");
  72. AppendMenu(hSubMenu, MF_STRING, CHANGE_TITLE, L"Change Title");
  73. AppendMenu(hFileMenu, MF_SEPARATOR, NULL, NULL);
  74. AppendMenu(hFileMenu, MF_STRING, FILE_MENU_EXIT, L"Exit");
  75. AppendMenu(hMenu, MF_STRING, HELP_POPUP_ID, L"Help");
  76. CreateWindowW(L"static", L"Enter text here: ", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, 200, 100, 100, 50, hWnd, NULL, NULL, NULL);
  77. CreateWindowW(L"Edit", L"...", WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL, 200, 152, 100, 50, hWnd, NULL, NULL, NULL); // WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL
  78. SetMenu(hWnd, hMenu);
  79. }
  80. void AddMenus(HWND hWnd) {
  81. hMenu = CreateMenu();
  82. HMENU hFileMenu = CreateMenu();
  83. HMENU hSubMenu = CreateMenu();
  84. AppendMenu(hSubMenu, MF_STRING, CHANGE_TITLE, L"Change Title");
  85. AppendMenu(hFileMenu, MF_STRING, LOAD_DROPDOWN_ID, L"New");
  86. AppendMenu(hFileMenu, MF_POPUP, (UINT_PTR)hSubMenu, L"Open Submenu");
  87. AppendMenu(hFileMenu, MF_SEPARATOR, NULL, NULL);
  88. AppendMenu(hFileMenu, MF_STRING, FILE_MENU_EXIT, L"Exit");
  89. AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, L"File");
  90. AppendMenu(hMenu, MF_STRING, HELP_POPUP_ID, L"Help");
  91. SetMenu(hWnd, hMenu);
  92. }
  93. void AddControls(HWND hWnd) {
  94. CreateWindowW(L"static", L"Enter text here: ", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, 200, 100, 100, 50, hWnd, NULL, NULL, NULL);
  95. CreateWindowW(L"Edit", L"...", WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL, 200, 152, 100, 50, hWnd,
  96. NULL, NULL, NULL); // WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL
  97. }

讨论

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

  1. case WM_CREATE:
  2. AddControls(hWnd);
  3. AddMenus(hWnd);


一个函数调用。

  1. case WM_CREATE:
  2. AddMenusAndControls(hWnd);


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

nqwrtyyt

nqwrtyyt1#

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

  1. case WM_DESTROY:
  2. PostQuitMessage(0);
  3. break;
  4. default:
  5. return DefMDIChildProcW(hWnd, msg, wp, lp);
  6. }

字符串

  1. case WM_DESTROY:
  2. PostQuitMessage(0);
  3. break;
  4. }
  5. return DefWindowProcW(hWnd, msg, wp, lp);


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

展开查看全部
yruzcnhs

yruzcnhs2#

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

  1. switch (wp) // This switch statement governs the resultant behavior of a button press on the main window.
  2. {
  3. //case FILE_DROPDOWN_ID:
  4. //MessageBeep(MB_DEFBUTTON1);
  5. case HELP_POPUP_ID:
  6. MessageBeep(MB_DEFBUTTON2);
  7. case FILE_MENU_EXIT:
  8. DestroyWindow(hWnd);
  9. case LOAD_DROPDOWN_ID:
  10. MessageBeep(MB_ICONINFORMATION);
  11. break;
  12. case CHANGE_TITLE:
  13. break;
  14. }
  15. break; ///THIS WAS CAUSING ERROR ADD THIS BREAK;
  16. case WM_CREATE:
  17. //AddControls(hWnd);
  18. //AddMenus(hWnd);
  19. AddMenusAndControls(hWnd);
  20. break;

字符串

展开查看全部

相关问题