奇怪的错误,请求大侠相救
错误描述为:右击托盘图标时,不能弹出菜单栏
我想实现托盘技术,由于是单文档的程序,所以我
第一步,就在CMainFrame中声明了private: NOTIFYICONDATA  m_tnid;。
第二步,在CMainFrame的头文件中加入了#define WM_USER_NOTIFYICON WM_USER+1。
第三步,新建菜单,ID为IDR_MENU。
第四步,在CMainFrame中重载了WindowProc(UINT message, WPARAM wParam, LPARAM lParam),并且进行了消息映射 ON_MESSAGE(WM_USER_NOTIFYICON, WindowProc)   
函数实现为
LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
// TODO: Add your specialized code here and/or call the base class if(lParam==WM_LBUTTONDOWN)         //响应左单击图标
ShowWindow(SW_SHOW);
else if(lParam==WM_LBUTTONDBLCLK)  //响应左双击图标
ShowWindow(SW_SHOW);
else if(lParam==WM_RBUTTONDOWN)    //响应右单击图标
{
CPoint point; 
        GetCursorPos(&point); 
CMenu menu; 
        menu.LoadMenu(IDR_MENU); //载入事先定义的选单 
        CMenu *pmenu=menu.GetSubMenu(0); 
        pmenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,AfxGetMainWnd());
pmenu->DestroyMenu();
} return CFrameWnd::WindowProc(message, wParam, lParam);
}
第五步,在CMainFrame中手动添加OnSysCommand(WPARAM wParam);,并进行消息映射 ON_MESSAGE(WM_SYSCOMMAND,OnSysCommand)
函数实现为
void CMainFrame::OnSysCommand(WPARAM wParam)
{
if(wParam==SC_MINIMIZE)        //响应最小化按钮
{
ShowWindow(SW_HIDE);
     Shell_NotifyIcon(NIM_ADD,&m_tnid);
}
else if(wParam==SC_CLOSE)     //响应关闭按钮
{            
Shell_NotifyIcon(NIM_DELETE,&m_tnid); //关闭时删除系统托盘图标
DestroyWindow();                      //关闭窗口
}
}
第六步,在CMainFrame::OnCreate中初始化了托盘图标
m_tnid.cbSize=sizeof(NOTIFYICONDATA);
m_tnid.hWnd=m_hWnd;
m_tnid.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;
m_tnid.uCallbackMessage=WM_USER_NOTIFYICON;
_tcscpy(m_tnid.szTip, "任务管理器");
m_tnid.uID=IDR_MAINFRAME;
m_tnid.hIcon=AfxGetApp()->LoadIcon(IDI_ICON1);
Shell_NotifyIcon(NIM_ADD,&m_tnid);最后运行程序
然后我运行了程序,实现了点击窗口的最小化键时,窗口隐藏到了托盘区,左击图标时,也能再次显示窗口,但是当右击图标时,不出现菜单栏,而是出现了这样的错误
 
TaskManage是我的工程名
当我在else if(lParam==WM_RBUTTONDOWN)    //响应右单击图标
{
CPoint point; 
        GetCursorPos(&point); 
CMenu menu; 
        menu.LoadMenu(IDR_MENU); //载入事先定义的选单 
        CMenu *pmenu=menu.GetSubMenu(0); 
        pmenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,AfxGetMainWnd());
pmenu->DestroyMenu();
}
}设置断点调试运行,当右击托盘的图标时,出现报错为
 
两三天了,都没解决,很是郁闷,还请高手相助。

解决方案 »

  1.   

    http://hiphotos.baidu.com/xdhw1/pic/item/c450f341a3291e7c86947358.jpg
    http://hiphotos.baidu.com/xdhw1/pic/item/7967f60e6defef5c94ca6b58.jpg
      

  2.   

    我做的时候没遇到报错问题,但弹出来的菜单是灰色的,不可用……
    LPPOINT lPoint = new tagPOINT;
    ::GetCursorPos(lPoint);
    CMenu menu;
    menu.CreatePopupMenu();
    menu.AppendMenu(MF_POPUP,WM_DESTROY,_T("退出"));
    menu.AppendMenu(MF_STRING|MF_ENABLED,WM_CLOSE_WINDOW,_T("关闭"));
    menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,lPoint->x,lPoint->y,this);
    HMENU hMenu = menu.Detach();
    menu.DestroyMenu();
    delete lPoint;
      

  3.   

    virtual LRESULT WindowProc( 
    UINT message, 
    WPARAM wParam, 
    LPARAM lParam ); 本来就是虚函数。直接实现它就可以了。ON_MESSAGE(WM_USER_NOTIFYICON, WindowProc)   //有点问题、
      

  4.   

    灰的是因为你的menu的事件没有映射啊, 你映射个oncommand 或者updateui事件。你的托盘的其他操作应该没问题。
      

  5.   

    我现在的问题是,不能加载我自己绘制的菜单,只能在程序中生成菜单如下的代码就会出现我说的错误
    {
    CPoint point;  
      GetCursorPos(&point);  
    CMenu menu;  
      menu.LoadMenu(IDR_MENU); //载入事先定义的选单  
      CMenu *pmenu=menu.GetSubMenu(0);  
      pmenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,AfxGetMainWnd());
    pmenu->DestroyMenu();
    }
    但是这样的代码就没有错误
    LPPOINT lPoint = new tagPOINT;
    ::GetCursorPos(lPoint);
    CMenu menu;
    menu.CreatePopupMenu();
    menu.AppendMenu(MF_POPUP,WM_DESTROY,_T("退出"));
    menu.AppendMenu(MF_STRING|MF_ENABLED,WM_CLOSE_WINDOW,_T("关闭"));
    menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,lPoint->x,lPoint->y,this);
    HMENU hMenu = menu.Detach();
    menu.DestroyMenu();
    delete lPoint;不知为什么不能载入自己加的选单我是菜鸟,刚学MFC三个星期
      

  6.   

    注意你代码的这两个问题 pmenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,AfxGetMainWnd());menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,lPoint->x,lPoint->y,this);AfxGetMainWnd()和this,所属的窗口内容。
      

  7.   

    托盘的图标,给你一个我的代码吧,我用的是win32的全局API函数,参考一下:void ContextMenu(HWND hwnd)
    {
    POINT pt;
    GetCursorPos(&pt); HMENU hmenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_MENU));
    HMENU hmnuPopup = GetSubMenu(hmenu, 0);
    SetMenuDefaultItem(hmnuPopup, IDOK, FALSE);
    SetForegroundWindow(hwnd);
    TrackPopupMenu(hmnuPopup, TPM_LEFTALIGN, pt.x, pt.y, 0, hwnd, NULL);
    SetForegroundWindow(hwnd);
    DestroyMenu(hmnuPopup);
    DestroyMenu(hmenu);
    }
      

  8.   

    没有必要写这么多吧!!我的代码:
    #define NIM_MESSAGE WM_USER+10afx_msg LRESULT OnNimMessage(WPARAM w,LPARAM l);ON_MESSAGE(NIM_MESSAGE,OnNimMessage)LRESULT CInetChatDlg::OnNimMessage(WPARAM w,LPARAM l)
    {
    if(w)
    {
    switch(l)
    {
    case WM_RBUTTONUP:
    {
     CMenu menu,*menu1=new CMenu();
     menu1->CreatePopupMenu();
     menu.LoadMenu(IDR_MENU1);
     menu1=menu.GetSubMenu(0);
     CPoint point;
     GetCursorPos(&point);
     menu1->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON,point.x,point.y,this,NULL);
     break;
    }
    case WM_LBUTTONDBLCLK:
    {
    if(ishide==0)
    {
                    this->ShowWindow(SW_HIDE);
    ishide=1;
    }
    else
    {
                       this->ShowWindow(SW_SHOW);
       ishide=0;
    }
    break;
    }
    default:
    break;
    }
    }
    return 0;
    }NOTIFYICONDATA nid = 
    {
    sizeof(nid),
            m_hWnd,
            1,
            NIF_ICON | NIF_MESSAGE | NIF_TIP, 
            NIM_MESSAGE,
            icon,
            "局域网鸿雁传书"
    } ;
    BOOL b = Shell_NotifyIcon(NIM_ADD ,&nid);NOTIFYICONDATA nid = 
    {
    sizeof(nid),
            m_hWnd,
            1,
            NIF_ICON | NIF_MESSAGE | NIF_TIP, 
            NIM_MESSAGE,
            icon,
            "局域网鸿雁传书"
    };
    BOOL b = Shell_NotifyIcon(NIM_DELETE ,&nid);
      

  9.   


    小心你这个代码:
    CMenu menu,*menu1=new CMenu();
    menu1->CreatePopupMenu();
    new、create了,不释放,再多的内存也被耗光了。
      

  10.   

    if ((wParam == IDR_MAINFRAME)&&(lParam == WM_LBUTTONDBLCLK))
    {
    ShowWindow(SW_SHOWNORMAL);
    SetForegroundWindow();
    }