Search code examples
c++mfctraymessage-loop

MFC messageloop in dialog window


i created a MFC dialog application.

now i want to use a messageloop, but i can not find it. I read that mfc will create it for me but that it will be hidden. so how can i manipulate the messageloop?

i need the messageloop to recieve events from my tray icon which i created for that application.

so that i can use something like that:

long CALLBACK WndProc(HWND hWnd, UINT nMsg, UINT wParam, LONG lParam) 
{ 
   switch(nMsg) 
   { 
   case (WM_USER + 1): 
      { 
         switch(lParam) 
         { 
         case WM_RBUTTONUP: 
            { 
               /**/
            } 
         } 
         return 0; 
      } 

   default: 
      return DefWindowProc(hWnd, nMsg, wParam, lParam); 
   } 
}

I'm still a beginner at mfc.


Solution

  • After installing an icon to the system tray by Shell_NotifyIcon, this icon become the extension of your dialog UI. When the user interact with this icon, the UI messages will be re-directed to your dialog by the OS automatically.

    To serve these user messages you needs to perform few steps:

    (1) Add a message handler definition (ON_MESSAGE(WM_TRAY_NOTIFY, OnTrayNotify)) inside the (.cpp) file. Must be inside the BEGIN_MESSAGE_MAP/END_MESSAGE_MAP block:

    BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
       //{{AFX_MSG_MAP(CTestDlg)
       ON_WM_PAINT()
       ON_WM_QUERYDRAGICON()
       ...
       //}}AFX_MSG_MAP
       ON_MESSAGE(WM_TRAY_NOTIFY, OnTrayNotify)
    END_MESSAGE_MAP()
    

    (2) Add a message handler implementation in the (.cpp) file, to perform the actual work

    void CTestDlg::OnTrayNotify(UINT nID, LPARAM lEvent)
    {
        if (nID==TRAYICON_ID1)
        {   
            // handle messages here
            if (lEvent==WM_LBUTTONDBLCLK)
            {  // do left button double click, usually restore application
            }
            if (lEvent==WM_RBUTTONUP)
            {  // do right button up, usually popup a menu at clicked location
            }
        }
    }
    

    (3) Add a prototype definition of this message handler (afx_msg void OnTrayNotify(UINT nID, LPARAM lEvent);) inside the (.h) file. Must be inside the BEGIN_MESSAGE_MAP/END_MESSAGE_MAP block:

    // Generated message map functions
    //{{AFX_MSG(CTestDlg)
    virtual BOOL OnInitDialog();
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    ...
    //}}AFX_MSG
    afx_msg void OnTrayNotify(UINT nID, LPARAM lEvent);
    DECLARE_MESSAGE_MAP()
    

    (4) Add definition inside (.h) file

    #define WM_TRAY_NOTIFY WM_USER+567
    #define TRAYICON_ID1 0x1234
    

    The code above is assuming:

    • The dialog name is CTestDlg, change it to your dialog name
    • The user-callback-message identifier (uCallbackMessage) used to setup Shell_NotifyIcon is WM_TRAY_NOTIFY
    • The identifier of the tray icon (uID) sed to setup Shell_NotifyIcon is TRAYICON_ID1