概要
当在下面的行中调用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
中的不同行,也没有效果。
这是怎么回事
感谢你的帮助。
2条答案
按热度按时间nqwrtyyt1#
你的窗口程序被严重破坏了。它有一个非void返回类型,但是除了
default:
之外,它在所有路径上都没有返回任何东西。窗口过程的正确结构是在函数的末尾无条件地调用默认窗口过程**。任何不应传递给默认窗口过程的消息都需要通过
return
退出其case
(并指定返回值),而不是break
。变更
字符串
至
型
我还修复了你选择调用哪个默认窗口过程的问题,因为你的WinMain似乎把这个窗口用作顶层框架,而不是MDI子窗口。
因为MDI子控件在焦点改变时自动将其菜单迁移到MDI父控件,并且因为您正在添加一个能够接收焦点的新子控件(在框架具有焦点之前),所以很可能发送到窗口的与焦点相关的消息发生了变化,并且由于您忠实地转发了它们,因此您获得了所要求的MDI菜单行为(即使您不想要它)。如果你没有MDI,不要使用
DefMDIChildProcW
!yruzcnhs2#
switch(msg){ case WM_COMMAND://为每个按钮或菜单项触发。告诉我们有东西被点击了。
字符串