菜单弹出问题,请高手指教,拜托了 本帖最后由 goldenhill 于 2009-08-20 19:15:15 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 static bool init=false; 去掉static 要么就像ls的把static去掉要么就把m_SysMenu.DestroyMenu(); 这句去掉。在其他退出的时候再调用这句删除菜单。 问题可能不在那里,那个static 不是原始代码,我只是为了调试才加上的,原始代码里面,这些都没有m_SysMenu.CreateMenu(); m_SysMenu.AppendMenu(MF_STRING,0x6000,_T("hello")); m_SysMenu.AppendMenu(MF_STRING,0x6001,_T("hello1")); .....m_SysMenu.DestroyMenu(); 这些代码原来都是在窗体的创建与释放里面的我怀疑问题出现在TrackPopupMenu函数调用完以后,m_hMenu指针就失效了。即m_SysMenu类创建的对象已经失效了这时候调用DestroyMenu,没反应,返回值也是false如果再调用m_SysMenu.CreateMenu();,则抱错,m_hMenu不等于NULL 不是因为TrackPopupMenu函数调用完以后,m_hMenu指针就失效了,而是TrackPopupMenu会阻塞程序,要鼠标点击了菜单或者点击菜单以外的区域才会返回。这样如果你点击速度快,OnLButtonDown响应的时候,TrackPopupMenu还没返回,也就是下面的m_SysMenu.DestroyMenu(); 还没来的及调用,就要调用m_SysMenu.CreateMenu();这时m_hMenu不等于NULL 。所以建议还是不要用类成员变量来保存这个菜单,直接用函数内的局部变量保存就行了。另外弹出菜单最好用m_SysMenu.CreatePopupMenu(); 不要用m_SysMenu.CreateMenu(); 不是因为TrackPopupMenu函数调用完以后,m_hMenu指针就失效了,而是TrackPopupMenu会阻塞程序,要鼠标点击了菜单或者点击菜单以外的区域才会返回。 这个我理解,不过我说了,请不要看m_SysMenu.CreateMenu(); 与m_SysMenu.DestroyMenu(); 这只是我调试的时候加上的。我修改了很多模式,这只是其中一种。为了避免大家误会,还原代码CMenu m_SysMenu; void CMainDlg::OnLButtonDown(UINT nFlags, CPoint point) { SetForegroundWindow(*this); m_SysMenu.TrackPopupMenu(TPM_LEFTBUTTON,point.x,point.y,*this); ::PostMessage( m_hWnd, WM_NULL, 0, 0 ); } 这时候,第一次调用,正常,第二次调用。失败。原因我也怀疑可能出在TrackPopupMenu阻塞程序不过我自己不确定,并且,即使这地方有问题,我也不知道怎么才能避免这种情况 不是因为TrackPopupMenu函数调用完以后,m_hMenu指针就失效了,而是TrackPopupMenu会阻塞程序,要鼠标点击了菜单或者点击菜单以外的区域才会返回。 这个我理解,不过我说了,请不要看m_SysMenu.CreateMenu(); 与m_SysMenu.DestroyMenu(); 这只是我调试的时候加上的。我修改了很多模式,这只是其中一种。为了避免大家误会,还原代码CMenu m_SysMenu; void CMainDlg::OnLButtonDown(UINT nFlags, CPoint point) { SetForegroundWindow(*this); m_SysMenu.TrackPopupMenu(TPM_LEFTBUTTON,point.x,point.y,*this); ::PostMessage( m_hWnd, WM_NULL, 0, 0 ); } 这时候,第一次调用,正常,第二次调用。失败。原因我也怀疑可能出在TrackPopupMenu阻塞程序不过我自己不确定,并且,即使这地方有问题,我也不知道怎么才能避免这种情况 这个我试验过,曾用过CMenu menu1=SysMenu.GetSubMenu(1);....menu1.TrackPopupMenu(TPM_LEFTBUTTON,point.x,point.y,*this); 错误一样。还是函数调用一次没问题,第二次出现问题,抱错还是指针失效当然,如果用LoadMenu就没有问题,可是那就等于重新加载了一遍菜单资源。这个就是另外一回事了,那不是前一个资源还没释放,滞留在内存中?问题更麻烦 请确认下TrackPopupMenu(TPM_LEFTBUTTON,point.x,point.y,*this); 第四个参数是*this 还是this 如果是*this 请修改为this C++书本翻页控件,有图有真相 edit控件的取值范围问题 那里有C++标准库的源代码下载呢,俺想研究下 怪!今天我用gdi+出现了这个 调整 声音 函数 VC(我是新人,没有太多的悬赏,请谅解!) 请教GDI画直线反锯齿的解决 “const” 什么时候会放到语句的最后面? 编译时出现这样的问题是怎么回事~? 请教大侠在VC中,利用ADO使用MAX计算最大值怎么不行?急! 二流高手请进! csdn blog 稳定性 太差啦 高分求教,GRPS MODEM的编程实现发送短信和接收短信!
去掉static
m_SysMenu.CreateMenu();
m_SysMenu.AppendMenu(MF_STRING,0x6000,_T("hello"));
m_SysMenu.AppendMenu(MF_STRING,0x6001,_T("hello1"));
.....
m_SysMenu.DestroyMenu();
这些代码原来都是在窗体的创建与释放里面的
我怀疑问题出现在
TrackPopupMenu函数调用完以后,m_hMenu指针就失效了。即m_SysMenu类创建的对象已经失效了
这时候调用DestroyMenu,没反应,返回值也是false
如果再调用m_SysMenu.CreateMenu();,则抱错,m_hMenu不等于NULL
不是因为TrackPopupMenu函数调用完以后,m_hMenu指针就失效了,而是TrackPopupMenu会阻塞程序,要鼠标点击了菜单或者点击菜单以外的区域才会返回。这样如果你点击速度快,OnLButtonDown响应的时候,TrackPopupMenu还没返回,也就是下面的m_SysMenu.DestroyMenu(); 还没来的及调用,就要调用m_SysMenu.CreateMenu();这时m_hMenu不等于NULL 。所以建议还是不要用类成员变量来保存这个菜单,直接用函数内的局部变量保存就行了。另外弹出菜单最好用m_SysMenu.CreatePopupMenu(); 不要用m_SysMenu.CreateMenu();
这个我理解,不过我说了,
请不要看m_SysMenu.CreateMenu(); 与m_SysMenu.DestroyMenu();
这只是我调试的时候加上的。
我修改了很多模式,这只是其中一种。
为了避免大家误会,还原代码CMenu m_SysMenu;
void CMainDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
SetForegroundWindow(*this);
m_SysMenu.TrackPopupMenu(TPM_LEFTBUTTON,point.x,point.y,*this);
::PostMessage( m_hWnd, WM_NULL, 0, 0 );
}
这时候,第一次调用,正常,第二次调用。失败。
原因我也怀疑可能出在
TrackPopupMenu阻塞程序
不过我自己不确定,并且,即使这地方有问题,我也不知道怎么才能避免这种情况
这个我理解,不过我说了,
请不要看m_SysMenu.CreateMenu(); 与m_SysMenu.DestroyMenu();
这只是我调试的时候加上的。
我修改了很多模式,这只是其中一种。
为了避免大家误会,还原代码CMenu m_SysMenu;
void CMainDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
SetForegroundWindow(*this);
m_SysMenu.TrackPopupMenu(TPM_LEFTBUTTON,point.x,point.y,*this);
::PostMessage( m_hWnd, WM_NULL, 0, 0 );
}
这时候,第一次调用,正常,第二次调用。失败。
原因我也怀疑可能出在
TrackPopupMenu阻塞程序
不过我自己不确定,并且,即使这地方有问题,我也不知道怎么才能避免这种情况
CMenu menu1=SysMenu.GetSubMenu(1);
....menu1.TrackPopupMenu(TPM_LEFTBUTTON,point.x,point.y,*this);
错误一样。还是函数调用一次没问题,第二次出现问题,抱错还是指针失效
当然,如果用LoadMenu就没有问题,可是那就等于重新加载了一遍菜单资源。
这个就是另外一回事了,那不是前一个资源还没释放,滞留在内存中?问题更麻烦
第四个参数是*this 还是this 如果是*this 请修改为this