ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 트레이 아이콘 처리하기
    IT/C/C++ 2008. 12. 17. 16:15

    출처 : 고수닷넷
    http://www.gosu.net/GosuWeb/Article-detail.aspx?ArticleCode=368

    1. 트레이 통지와 관련된 함수와 파라미터

    BOOL WINAPI Shell_NontifyIcon(DWORD dwMessage, PNOTIFYICONDATA pnid);
    
      dwMessage로는 다음과 같은 값을 입력할 수 있습니다.
    • NIM_ADD : 트레이에 새로운 아이콘 추가
    • NIM_DELETE : 트레이 영역의 아이콘 제거
    • NIM_MODIFY : 트레이 영역에 있는 아이콘 수정
    typedef struct _NOTIFYICONDATA
    {
        DWORD    cbSize;
        HWND    hWnd;
        UINT    uID;
        UINT    uFlags;
        UINT    uCallbackMessage;
        HICON    hIcon;
        char    szTip[64];
    } NOTIFYICONDATA, *PNOTIFYICONDATA;
    
    • cbSize: 구조체의 크기
    • hWnd: 윈도우 핸들
    • uID: 아이콘 식별자, 호출한 애플리케이션의 아이콘을 다른것과 구ㅕㄹ해서 식별할수 있게 해주는 사용자 정의값
    • uFlags: NIF_MESSAGE : uCallbackMessage 사용 NIF_ICON : hIcon 사용 NIF_TIP : szTip 사용
    • uCallbackMessage: 아이콘이 hWnd윈도우와 통신하기 위해서 사용할 메시지 ID. 메시지는 WM_APP의 오프셋으로 선언되는 사용자 정의 메시지이다.
    • hIcon: 화면에 그릴 아이콘의 핸들.
    • szTip: 아이콘의 툴팁을 위한 텍스트.

    2. 트레이에 아이콘 추가

    NOTIFYICONDATA    nid;
    
    // 구조체 초기화
    ZeroMemory(&nid, sizeof nid);
    
    // 구조체 설정
    nid.cbSize = sizeof nid;
    nid.hWnd = hWnd;
    nid.uID = ICON_ID;
    nid.uFlags = NIF_TIP | NIF_ICON | NIF_MESSAGE;
    nid.uCallbackMessage = WM_MESSAGE;
    nid.hIcon = hSmallIcon;
    lstrcpy(nid.szTip, "Sample");
    
    // 트레이 영역에 추가
    Shell_NotifyIcon(NIM_ADD, &nid);
    

    3. 트레이 아이콘 제거

    제거시에는 hWnd와 uID멤버만 셋팅하면 됩니다.

    NOTIFYICONDATA    nid;
    
    ZeroMemory(&nid, sizeof nid);
    
    nid.cbSize = sizeof nid;
    nid.hWnd = hWnd;
    nid.uID = ICON_ID;
    
    Shell_NotifyIcon(NIM_DELETE, &nid);
    

    4. 트레이로 부터의 메시지 수신

    마우스와 관련된 메시지만 통지합니다.

    • wParam : 등록시에 설정한 ID(nid.uID).
    • lParam : 메시지 종류 (WM_LBUTTONUP, ...).
    case WM_MESSAGE:
        if(wParam == ICON_ID)
        {
            switch(lParam)
            {
                case WM_RBUTTONUP:
                    // 처리
                    break;
            }
        }
    
        break;
    

    5. Context메뉴

    일반적으로 트레이에서 오른쪽 버튼을 누르면 context 메뉴를 화면에 표시합니다. 아래는 그러한 일을 하는 코드의 일부입니다.

    POINT pt;
    GetCursorPos(&pt);
    
    SetForegroundWindow(hWnd);
    TrackPopupMenu(menu, TPM_LEFTALIGN, pt.x, pt.y, 0, hWnd, NULL);
    PostMessage(hWnd, WM_NULL, 0, 0);
    

    주의할 점은 TrackPopupMenu 앞에 SetForegroundWindow API 를 호출해 주고, 후에 WM_NULL 메시지를 포스트 해주어야 합니다. 그렇지 않을 경우 메뉴가 화면에서 사라지지 않는 버그 현상이 생기게 됩니다.

    6. For MFC.

    아래는 MFC에서 일반적으로 하게 되는 트레이 작업 영역에 추가 및 삭제를 위한 코드의 일부입니다.

    6.1 추가

    #define WM_TRAYNOTIFY WM_APP + 1
    
    NOTIFYICONDATA    nid;
    
    ::ZeroMemory(&nid, sizeof nid);
    
    nid.cbSize        = sizeof nid;
    nid.hIcon        = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    nid.hWnd        = this->m_hWnd;
    nid.uID            = IDR_MAINFRAME;
    nid.uFlags        = NIF_TIP | NIF_ICON | NIF_MESSAGE;
    nid.uCallbackMessage    = WM_TRAYNOTIFY;
    
    lstrcpy(nid.szTip, "Test");
    
    ::Shell_NotifyIcon(NIM_ADD, &nid);
    

    6.2 제거

    NOTIFYICONDATA    nid;
    
    ::ZeroMemory(&nid, sizeof nid);
    
    nid.cbSize    = sizeof(nid);
    nid.uID        = IDR_MAINFRAME;
    nid.hWnd    = this->m_hWnd;
    
    ::Shell_NotifyIcon(NIM_DELETE, &nid);
    

    6.3 메시지 처리

    ON_MESSAGE(WM_TRAYNOTIFY, OnTrayNotify)
    
    LONG TestDlg::OnTrayNotify(WPARAM wParam, LPARAM lParam)
    {
        CMenu    menu, *pTrayMenu;
        CPoint    pt;
    
        if(wParam == IDR_MAINFRAME)
        {
            switch(lParam)
            {
            case WM_RBUTTONUP:
                menu.LoadMenu(IDR_TRAYMENU);
                pTrayMenu = menu.GetSubMenu(0);
    
                ::GetCursorPos(&pt);
    
                SetForegroundWindow();
                pTrayMenu->TrackPopupMenu(TPM_LEFTALIGN, pt.x, pt.y, this, NULL);
                SetForegroundWindow();
    
                pTrayMenu->DestroyMenu();
                menu.DestroyMenu();
                break;
    
            case WM_LBUTTONDBLCLK:
                if(!IsWindowVisible())
                    ShowWindow(SW_SHOW);
    
                SetForegroundWindow();
                break;
            }
        }
    
        return 0;
    }
    
Designed by Tistory.