ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MFC 트레이 아이콘 등록 및 윈도우 감추기
    IT/C/C++ 2008. 12. 17. 14:39

    MFC 프로그램을 최소화 버튼을 눌렀을 때 태스크 바에 나타나지 않고 트레이에 등록된 상태로 만드는 방법.


    우선 프로젝트에 현재 트레이 상태를 알수 있는 BOOL 변수를 선언한다.

    Protected 에 선언 변수 이름은 m_bIsTrayIcon 로 하겠다.

    다음 트레이아이콘을 등록하는 함수를 만든다. 함수 이름은 RegistTrayIcon 로 하겠다.
    Private 로 선언

    그리고 코딩한다.
    void CTrayDlg::RegistTrayIcon()
    {
     NOTIFYICONDATA  nid;
     nid.cbSize = sizeof(nid);
     nid.hWnd = m_hWnd; // 메인 윈도우 핸들
     nid.uID = IDR_MAINFRAME;  // 아이콘 리소스 ID
     nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; // 플래그 설정
     nid.uCallbackMessage = WM_TRAYICON_MSG; // 콜백메시지 설정
     nid.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); // 아이콘 로드
     CString Title = _T("Test Tray");   // 트레이 위에 커서가 올라갔을 때 표시되는 프로그램명
     lstrcpy(nid.szTip, Title);
     Shell_NotifyIcon(NIM_ADD, &nid);
     SendMessage(WM_SETICON, (WPARAM)TRUE, (LPARAM)nid.hIcon);
     m_bIsTrayIcon = TRUE;


    }

    그리고.. 다이얼로그의 헤더파일에 가서

    #define  WM_TRAYICON_MSG WM_USER + 1 을 정의 해준다.
    본 예에서는 TrayDlg.h 가 되겠다.

    다시 TrayDlg.cpp 에 가서
    BEGIN_MESSAGE_MAP(CTrayDlg, CDialog)  부분에 다음을 추가한다.
    ON_MESSAGE(WM_TRAYICON_MSG, TrayIconMsg)
    이 부분을 다시 보면 다음과 같다.

    BEGIN_MESSAGE_MAP(CTrayDlg, CDialog)
     //{{AFX_MSG_MAP(CTrayDlg)
     ON_WM_SYSCOMMAND()
     ON_WM_PAINT()
     ON_WM_QUERYDRAGICON()
     //}}AFX_MSG_MAP
     ON_MESSAGE(WM_TRAYICON_MSG, TrayIconMsg)
    END_MESSAGE_MAP()


    그리고 함수를 하나더 추가하는데
    protected 로 void TrayIconMsg(WPARAM wParam, LPARAM lParam); 함수를 추가한다.
    코딩은 다음과 같다.
    트레이로 등록된 아이콘을 클릭시 발생하는 함수가 되는 것이다.

    // WM_TRAYICON_MSG 이 메세지를 받으면 구동..
    void CTrayDlg::TrayIconMsg(WPARAM wParam, LPARAM lParam)
    {
     // 등록된 TrayIcon 클릭하면 Show....
     if(lParam == WM_LBUTTONDBLCLK)
     { 
      ShowWindow(SW_SHOW);
     }
    }


    자 다음으로는 OnSysCommand 라는 함수가 정의 되어 있을 것인데,
    이곳에 버튼을 클릭했을시 윈도우를 어떻게 할지 핸들링을 할 수 있다.

    void CTrayDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
     {
      CAboutDlg dlgAbout;
      dlgAbout.DoModal();
     }

    /*  상단에 x 버튼을 눌렀을때
     else if(nID == SC_CLOSE)
     {
     
     }
    */
     // 최소화 버튼을 눌렀을때
     else if(nID == SC_MINIMIZE)
     {
      ShowWindow(SW_HIDE);
     }

     else
     {
      CDialog::OnSysCommand(nID, lParam);
     }
    }

    위의 코드는 최소화버튼을 눌렀을때 윈도우를 감추게 된다.

    그리고 OnInitDialog() 함수로 간다.
    이 함수는 다이얼로그가 실행되기 위해서 최초로 동작하는 함수이다.
    맨 아래에 이 두줄을 추가한다.
     m_bIsTrayIcon = FALSE;
     RegistTrayIcon();

    그리고 마지막으로 프로그램이 종료될때 트레이 아이콘을 종료 해줘야 하므로
    OnDestroy 함수를 이용해야 한다.

    클래스 위져드(Ctrl+W) 를 열어서 WM_DESTROY 를 선택하고
    Add Function 을 클릭, 편집한다.
    void CTrayDlg::OnDestroy()
    {
     CDialog::OnDestroy();
     
     // TODO: Add your message handler code here
     if(m_bIsTrayIcon) // 현재 트레이 아이콘으로 설정되었는지 확인
     {
      NOTIFYICONDATA  nid;
      nid.cbSize = sizeof(nid);
      nid.hWnd = m_hWnd; // 메인 윈도우 핸들
      nid.uID = IDR_MAINFRAME;

      // 작업 표시줄(TaskBar)의 상태 영역에 아이콘을 삭제한다.
      Shell_NotifyIcon(NIM_DELETE, &nid);
     }
     
    }


    아참.. 깜박했다. 다이얼로그의 Properties 에서
    Styles 의 Minimize box 를 체크해줘야 한다는 것이다~ ㅋ
    그래야 오른쪽 상단에 줄이는 버튼이 나오지 -_-;;

    출처
    http://hotangs.tistory.com/archive/20070804


Designed by Tistory.