MFC C++ 托盘应用程序问题

Posted

技术标签:

【中文标题】MFC C++ 托盘应用程序问题【英文标题】:MFC C++ Tray Application Issue 【发布时间】:2013-04-03 11:40:54 【问题描述】:

我正在创建 mfc 应用程序的任务栏图标,并在我编写的 MyView.cpp 文件中

    static const UINT WMU_NOTIFY_TASKBAR_ICON = ::RegisterWindowMessage(_T("NOTIFY_TASKBAR_ICON"));

    IMPLEMENT_DYNCREATE(CMyView, CView)

    BEGIN_MESSAGE_MAP(CMyView, CView)
         // Standard printing commands
         ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
         ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
         ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
         // added messages by the developer
         ON_REGISTERED_MESSAGE(WMU_NOTIFY_TASKBAR_ICON, OnNotifyTaskbarIcon)
    END_MESSAGE_MAP()
    //...

    void CMyView::AddTaskbarIcon()
    
         DWORD dwMessage = NIM_ADD;
         NOTIFYICONDATA nid;

         nid.cbSize = sizeof(NOTIFYICONDATA);
         nid.hWnd = HWND(AfxGetApp()->m_pMainWnd);
         nid.uID = 0;
         nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
         nid.uCallbackMessage = WMU_NOTIFY_TASKBAR_ICON;
         nid.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_SS_ICON));
         nid.dwInfoFlags = NIIF_INFO;
         ::Shell_NotifyIconW(dwMessage, &nid);
    

    LRESULT CMyView::OnNotifyTaskbarIcon( WPARAM wParam, LPARAM lParam )
    
        UINT uID = (UINT)wParam;
        UINT uMouseMsg = (UINT)lParam;

        switch(uMouseMsg)
        
        case WM_LBUTTONDOWN:
            break;

        case WM_LBUTTONDBLCLK:
            //if(IsIconic())
            
                break;
            

        case WM_RBUTTONDOWN:
            
                // must be implemented:
                // app popup menu will be showed
                CMenu* pMenu = GetMenu();
                if( pMenu )
                
                    CMenu *pSubMenu = NULL;
                    pSubMenu = pMenu->GetSubMenu( 0 );
                    
                        SetForegroundWindow(); // *** little patch here ***             
                        POINT pointCursor;             
                        ::GetCursorPos( &pointCursor );            
                        pSubMenu->TrackPopupMenu( TPM_RIGHTALIGN, 
                            pointCursor.x, pointCursor.y, 
                            this );
                    
                
            
            break;

        case WM_RBUTTONDBLCLK:
            break;

        case WM_MOUSEMOVE:
            break;
        

        return 0L;
    

在 My.cpp 中

    BOOL CMyApp::InitInstance()
    
            //...
            myViewPtr->AddTaskbarIcon();
            //...
    

应用程序启动,图标出现在任务栏上,但在鼠标悬停时消失。 我做错了什么吗?谢谢

【问题讨论】:

【参考方案1】:

AfxGetApp()->m_pMainWnd 指向主框架窗口,而不是视图。我怀疑框架窗口正在接收 WMU_NOTIFY_TASKBAR_ICON 消息并且没有处理它,因此 Windows 删除了该图标。

您可以在框架窗口类中处理消息,或者将句柄传递给视图,如下所示:

void CMyView::AddTaskbarIcon()

     ...
     nid.hWnd = GetSafeHwnd();
     ...

【讨论】:

以上是关于MFC C++ 托盘应用程序问题的主要内容,如果未能解决你的问题,请参考以下文章

MFC 任务托盘显示气泡

Ownerdrawn托盘图标(winapi)?

MFC添加图标到托盘

MFC下托盘图标的实现和托盘菜单

C++ Builder托盘控件

Qt系统托盘