windows程序设计---菜单求助(困扰我很久)

砂锅终结者 2016-07-15 01:35:07
如题,我的窗口创建一个菜单资源,然后LoadMenu到此窗口的菜单句柄中,在WM_CREATE期间SetMenu
编译运行后,菜单显示正确,且功能正常。

【问题如下】
①我使用鼠标左键点击菜单(下拉选择、或者来回移动鼠标不选择),几次(有时4次,有时8、9次)后,我的菜单消失了(或 菜单不消失,但不再出现下拉选项了!),且此时系统菜单(系统菜单我没做任何改动)也不能下拉了!这是为什么呢?

②我使用alt+方向键选择菜单,过程跟鼠标的一样,不会出现菜单消失或者菜单失效问题(但是再使用鼠标的话,依然会出现①的问题)。
...全文
183 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
砂锅终结者 2016-07-15
  • 打赏
  • 举报
回复
谢谢!我再仔细研究下具体原因。
Eleven 2016-07-15
  • 打赏
  • 举报
回复
引用 11 楼 qq_24114693 的回复:
重复加载(全局变量的情况下)为什么会有影响呢?
可能与GDI资源泄漏有关系,你LoadMenu会调用很多次,但是并没有DestroyMenu()之前的,而一个进程的GDI资源是有限的,从而导致GDI上显示不正常也是一定的。
砂锅终结者 2016-07-15
  • 打赏
  • 举报
回复
重复加载(全局变量的情况下)为什么会有影响呢?
hurryboylqs 2016-07-15
  • 打赏
  • 举报
回复
窗口过程函数是频繁的被调用的,使用变量要注意
用户 昵称 2016-07-15
  • 打赏
  • 举报
回复
没错,每次都会重新loadmenu,变量,还是该用全局的,就用全局的。
砂锅终结者 2016-07-15
  • 打赏
  • 举报
回复
我是这样理解的。 ① hmenu= LoadMenu (hInstance,"XXXX") ; 加载菜单,给到一个菜单句柄,hmenu是一个确切的值(任何句柄都是整数值) ②然后设置菜单:SetMenu (hwnd, hmenu) ; 此时的hmenu(形参)给到函数setmenu(,)里面的是一个实际的值,所以无论Loadmenu多少次,只是改版hmenu的值,并不会影响之前的菜单。 而setmenu(,)没有再次执行,所以没影响。除非hmeun是一个指针,那改变hmenu才会间接的影响setmenu(,)
砂锅终结者 2016-07-15
  • 打赏
  • 举报
回复
试了半天,似乎没问题了,关于这个: “ hmenu1= LoadMenu (hInstance,"WINDOWS_MENU_yzx") ; hmenu2= LoadMenu (hInstance,"WINDOWS_MENU") ; 上面的这两个可以放到WM_CREATE处理中,只做一次。 ” 为什么重复加载菜单就会出问题呢?
Eleven 2016-07-15
  • 打赏
  • 举报
回复
你上面代码的问题就是每次进入窗口过程函数中都会做一次LoadMenu的操作~
Eleven 2016-07-15
  • 打赏
  • 举报
回复
HMENU hmenu1,hmenu2; HINSTANCE hInstance; 上面的这些变量定义成全局变量,hInstance 可以在WinMain函数中初始化它。 hmenu1= LoadMenu (hInstance,"WINDOWS_MENU_yzx") ; hmenu2= LoadMenu (hInstance,"WINDOWS_MENU") ; 上面的这两个可以放到WM_CREATE处理中,只做一次。
砂锅终结者 2016-07-15
  • 打赏
  • 举报
回复
hmenu1是中文菜单 ,hmenu2是英文菜单
砂锅终结者 2016-07-15
  • 打赏
  • 举报
回复
这是我的全部程序(不包含RC及那个自定义的头文件)
#include <windows.h>
#include "YZX_exercise_private.h"

/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
void ErrorExit(LPTSTR lpszFunction);

/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)

{
HWND hwnd; /* 窗口句柄 */
MSG messages; /* 消息结构*/
WNDCLASSEX wincl; /* 窗口类结构 */
HMENU hmenu; /* 菜单句柄 */

/* The Window structure */
wincl.hInstance = hThisInstance; /* 窗口实例句柄 */
wincl.lpszClassName = szClassName; /* 窗口类名称 */
wincl.lpfnWndProc = WindowProcedure; /* 窗口消息的处理程序 */
//wincl.style = CS_DBLCLKS; /* 窗口可获得鼠标双击信息 */
wincl.style =CS_HREDRAW | CS_VREDRAW ;

wincl.cbSize = sizeof (WNDCLASSEX);


wincl.hIcon = LoadIcon (hThisInstance,"WINDOWS_ICO"); /*窗口图标样式(显示器下方工具栏上的图标)*/
wincl.hIconSm = LoadIcon (hThisInstance,"WINDOWS_TITLE_ICO"); /*窗口 标题栏 图标样式*/
wincl.hCursor = LoadCursor (NULL,IDC_ARROW) ; /*窗口 鼠标 图标样式*/


wincl.lpszMenuName =NULL; /* 菜单名称(资源名) */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;/* Use Windows's default color as the background of the window */



/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;

/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* 窗口名称 */
"Windows x App", /* 窗口的标题栏文字*/
WS_OVERLAPPEDWINDOW, /* 窗口风格*/
350, /* 窗口起点位置(水平) */
100, /* 窗口起点位置(垂直) */
650, /* 窗口水平长度 */
350, /* 窗口垂直长度*/
HWND_DESKTOP, /* 此窗口的父窗口句柄*/
NULL, /* 菜单句柄 */
hThisInstance, /*应用程序实例句柄*/
NULL /* No Window Creation data */
);

ShowWindow (hwnd, nFunsterStil);/*显示窗口*/
UpdateWindow (hwnd) ;

while (GetMessage (&messages, NULL, 0, 0))/*消息循环,当有WM_QUIT时,函数GetMessage()返回值是0 */
{
TranslateMessage(&messages); /* Translate virtual-key messages into character messages */
DispatchMessage(&messages); /* Send message to WindowProcedure */
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}


/* This function is called by the Windows function DispatchMessage() */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HMENU hmenu1,hmenu2;
HINSTANCE hInstance;

PAINTSTRUCT ps ;
HDC hdc ;
static k=11,m;
static char xox[]="123456789";

hInstance = (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE) ;
hmenu1= LoadMenu (hInstance,"WINDOWS_MENU_yzx") ;
hmenu2= LoadMenu (hInstance,"WINDOWS_MENU") ;
//SetMenu (hwnd, hmenu2) ;



switch (message) /* handle the messages */
{

case WM_CREATE:

SetMenu (hwnd, hmenu2) ;

return 0 ;

case WM_PAINT:

hdc = BeginPaint (hwnd, &ps) ;

if(k==11)TextOut (hdc,100,200,"123456789",9) ;
else
switch(m)
{
case 2:TextOut (hdc,100,200,"NEW",3) ;break;
case 3:TextOut (hdc,100,200,"WORD",4) ;break;
case 4:TextOut (hdc,100,200,"SAVE",4) ;break;
default: break;
}


EndPaint (hwnd, &ps) ;


return 0 ;

case WM_MENUSELECT:

switch (LOWORD (wParam))
{

case IDM_FILE_NEW:
k=0;
m=2;
InvalidateRect (hwnd, NULL, 1) ;
break;

case IDM_FILE_OPENW:
k=0;
m=3;
InvalidateRect (hwnd, NULL, 1) ;
break;

case IDM_FILE_SAVE:
k=0;
m=4;
InvalidateRect (hwnd, NULL, 1) ;
break;

case IDM_FILE_SAVE_AS:
break;


case IDM_FILE_EXIT:;
break;

}
InvalidateRect (hwnd, NULL, 0) ;
return 0 ;

case WM_COMMAND:

switch (LOWORD (wParam))
{

case 111:
SetMenu (hwnd, hmenu2) ;
break;



case IDM_FILE_OPENT:
MessageBox(hwnd,"None such function!",szClassName, MB_ICONEXCLAMATION | MB_OK) ;
break;

case IDM_FILE_SAVE:

break;

case IDM_FILE_SAVE_AS:
MessageBeep (0) ;
break;

case IDM_FILE_EXIT:
SendMessage (hwnd, WM_CLOSE, 0, 0) ;
break;

case IDM_TOOLS_CHINESE:
SetMenu (hwnd, hmenu1) ;
break;

default: break;
}

return 0;







case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}

return 0;
}
砂锅终结者 2016-07-15
  • 打赏
  • 举报
回复
没什么特殊处理啊,就是load资源,然后在WM_CREATE期间set菜单,
Eleven 2016-07-15
  • 打赏
  • 举报
回复
你的代码中是怎么写的?对菜单有做什么特殊处理吗?

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧