C++ Win32Api窗口菜单激活问题

C++ Win32Api窗口菜单激活问题,c++,windows,winapi,win32gui,win32-process,C++,Windows,Winapi,Win32gui,Win32 Process,运行我的程序,它运行,由于我有一个菜单,退出破坏窗口,它运行,并立即退出窗口。不确定如何解决我在编译程序以使其不运行WindowProcedure函数并传递导致窗口被破坏的参数EXITMENU时遇到的问题 *.CPP #include <windows.h> #define HELPMENU 1 #define HIGHSCROREMENU 2 #define EXITMENU 3 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPre

运行我的程序,它运行,由于我有一个菜单,退出破坏窗口,它运行,并立即退出窗口。不确定如何解决我在编译程序以使其不运行WindowProcedure函数并传递导致窗口被破坏的参数EXITMENU时遇到的问题

*.CPP

#include <windows.h>
#define HELPMENU 1
#define HIGHSCROREMENU 2
#define EXITMENU 3

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow) {
    WNDCLASS wc = { 0 }; // WNDCLASSW is a structure
    LPCWSTR title = L"Window"; // Long Pointer Constant Wide (UTF-16) String 

    wc.hbrBackground = (HBRUSH)COLOR_WINDOW; // Background
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_HAND); // Sets Cursor
    wc.hInstance = hInst; // Instance of window
    wc.lpszClassName = L"windowClass"; // Class name
    wc.lpfnWndProc = WindowProcedure; // Pointer to the function // Controller of window handle

    if (!RegisterClassW(&wc)) { // Registers the window class
        return -1;
    }

    //                                                   | binary combination value, posX, posY, Width, Height

    // Creates the window
    CreateWindow(wc.lpszClassName, title, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_BORDER, 100, 100, 800, 600, NULL, NULL, NULL, NULL);

    MSG msg = { 0 };


    while (GetMessage(&msg, NULL, NULL, NULL) > 0) { // Keeps the window running
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

/* Event Paths */
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
    switch (msg) {
    case WM_CREATE: // On window creation
        AddControls(hWnd);
        AddMenu(hWnd);
        break;
    case WM_LBUTTONDOWN: // Left Mouse button
        break;
    case WM_DESTROY: // Makes GetMessage Function return false, closing the window
        PostQuitMessage(0);
        return 0;
    case EXITMENU:
        DestroyWindow(hWnd); // This part of the code shouldn't run on creation
        break;
    default:
        return DefWindowProc(hWnd, msg, wp, lp);
    }
}

/* Creates menu */
void AddMenu(HWND hWnd) {
    hMenu = CreateMenu(); // Creates menu object
    // AppendMenu(Menu Instance, Usage Type, Argument, String info);
    AppendMenu(hMenu, MF_STRING, HELPMENU, L"Help - F1");
    AppendMenu(hMenu, MF_STRING, HIGHSCROREMENU, L"Highscores - F2"); // Menu Created
    AppendMenu(hMenu, MF_STRING, EXITMENU, L"Exit - ESC");
    // SetMenu(Window Handle , Menu Instance);
    SetMenu(hWnd, hMenu); // Sets menu for window // 
} 

#包括
#定义帮助菜单1
#定义HighScromeNu 2
#定义EXITMENU 3
int WINAPI WinMain(HINSTANCE hInst、HINSTANCE hPrevInst、LPSTR args、int ncmdshow){
WndClassWC={0};//WNDCLASSW是一个结构
LPCWSTR title=L“窗口”;//长指针常量宽(UTF-16)字符串
wc.hbrBackground=(HBRUSH)颜色\u窗口;//背景
wc.hIcon=LoadIcon(空,IDI_应用程序);
wc.hCursor=LoadCursor(NULL,IDC_HAND);//设置光标
wc.hInstance=hInst;//窗口实例
wc.lpszClassName=L“windowClass”;//类名
wc.lpfnWndProc=WindowProcedure;//指向函数//窗口句柄控制器的指针
如果(!RegisterClassW(&wc)){//注册窗口类
返回-1;
}
//|二进制组合值,posX,posY,宽度,高度
//创建窗口
CreateWindow(wc.lpszClassName,title,WS|u重叠窗口| WS|u可见| WS|u边框,100100800600,NULL,NULL,NULL,NULL);
MSG={0};
而(GetMessage(&msg,NULL,NULL,NULL)>0){//保持窗口运行
翻译信息(&msg);
发送消息(&msg);
}
返回0;
}
/*事件路径*/
LRESULT回调窗口过程(HWND HWND、UINT msg、WPARAM wp、LPARAM lp){
开关(msg){
案例WM_CREATE://关于窗口创建
AddControls(hWnd);
添加菜单(hWnd);
打破
case WM_LBUTTONDOWN://鼠标左键
打破
case WM_DESTROY://使GetMessage函数返回false,关闭窗口
PostQuitMessage(0);
返回0;
案例列表:
DestroyWindow(hWnd);//这部分代码不应在创建时运行
打破
违约:
返回DefWindowProc(hWnd、msg、wp、lp);
}
}
/*创建菜单*/
无效添加菜单(HWND HWND){
humenu=CreateMenu();//创建菜单对象
//AppendMenu(菜单实例、用法类型、参数、字符串信息);
附录菜单(hMenu、MF_字符串、HELPMENU、L“Help-F1”);
附录菜单(hMenu、MF_字符串、HighScromeNu、L“Highscores-F2”);//已创建菜单
附录菜单(hMenu、MF_字符串、EXITMENU、L“Exit-ESC”);
//SetMenu(窗口句柄、菜单实例);
设置菜单(hWnd,hMenu);//设置窗口的菜单//
} 

您没有正确处理
WindowProcedure()中的菜单命令。

您已将
EXITMENU
定义为3,该值与
WM_MOVE
消息的值相同。因此,在您的
开关中
,当窗口在创建窗口期间收到
WM\u MOVE
消息时,您将立即销毁窗口

您需要通过
WM_COMMAND
消息来处理菜单命令,请参见以下文档:

当用户从菜单中选择命令项时,系统向窗口程序发送
WM_command
消息。
WM_命令
消息的
wParam
参数的低位字包含所选项目的标识符。窗口过程应该检查标识符并相应地处理消息

请尝试以下方法:

LRESULT回调窗口过程(HWND HWND、UINT msg、WPARAM wp、LPARAM lp){
开关(msg){
...
case WM_命令:
开关(wp){
案例帮助菜单:{
...
返回0;
}
case highscromenu:{
...
返回0;
}
案例列表:{
窗口(hWnd);
返回0;
}
}
打破
}
...
}
返回DefWindowProc(hWnd、msg、wp、lp);
}

<强> Update:>,请考虑使用<代码> ExtMutue处理程序使用<代码> SeNeMeST(WMyHOLD)而不是<代码> Debug YouWOW()/<代码>。如果您的应用程序维护了用户关闭应用程序时应保存的数据,则您可以添加

WM_CLOSE
处理程序来执行该操作,而不管窗口是如何关闭的(退出菜单、
X
CLOSE按钮、Alt-F4等)
DefWindowProc()
在处理
WM\u CLOSE
时销毁窗口

LRESULT回调窗口过程(HWND HWND、UINT msg、WPARAM wp、LPARAM lp){
开关(msg){
...
案例WM_结束:{
如果(数据已修改){
提示用户保存数据。。。
如果(取消){
返回0;
}
如果(应该保存){
保存数据。。。
}
}
打破
}
case WM_命令:
开关(wp){
...
案例列表:{
发送消息(hWnd,WM_CLOSE,0,0);
返回0;
}
}
打破
}
...
}
返回DefWindowProc(hWnd、msg、wp、lp);
}

#定义EXITMENU 3
为什么<代码>3是winuser.h中定义的
WM\u MOVE
。EXITMENU不是消息。正好匹配WM_移动,不是破坏窗口的好理由。使用WM_命令检测菜单命令。谢谢dxiv和@Hans Passant,他们没有意识到它已经覆盖了定义的值。我将转而考虑执行WM_命令。仍然试图从整体上理解Win32Api。太棒了,我刚才所做的正是感谢你和@Hans Passant。相关: