오늘 작업 내용 중에 기본 기능으로 구현 한 다이얼로그 트레이 동작 기능을 정리 해보려 한다.
실행하는 다이얼로그 기반의 응용 프로그램을 Tray에 등록하고,
시스템 메뉴의 최소화, 혹은 X 버튼 클릭 시 종료가 아닌, 트레이로 상주하도록 구현해 보았다.
일단 기본적으로 짚고 넘어가자.
1. 시스템 메뉴란?
일반적으로 사용하는 Window의 프로그램 창의 오른쪽 상단에 있는 그것.
|
<시스템 메뉴>
2. Tray Icon 이란?
MS 윈도우 계통의 작업 표시줄의 하단 우측편에에 작은 아이콘으로 등록어 기능을 수행하는 그룹을 말한다.
|
< 트레이 아이콘 >
각설하고,
일단 내가 했던 작업 방식으로 진행해보도록 하겠음.
1. 트레이에 사용 될 메뉴 리소스 작성
- 일단, 트레이 우클릭 시 표시 될 메뉴 리소스를 먼저 작성한다.
|
<필요한 메뉴 리소스를 추가한다>
2. 메뉴에 대한 이벤트를 추가한다.
<메뉴 리소스 추가 및 서브 메뉴 추가> <각 서브메뉴에 이벤트 처리기 추가> |
3. 헤더 및 cpp 파일에 메뉴 이벤트에 대한 동작을 구현한다.
// 트레이 메뉴 중 정보 창 호출 void CXXXDlg::OnTraymenuAbout() { CAboutDlg* pDlg = new CAboutDlg; pDlg->DoModal(); delete pDlg; } // 트레이 메뉴 중 다이얼로그 복원 void CXXXDlg::OnTraymenuOpen() { SetRestoreDialog(); <- 이건 나중에 구현 후 추가해 준다. } // 종료시 호출 void CXXXDlg::OnDestroy() { CDialog::OnDestroy(); }
기본형으로 정보창만 호출하도록 기본 구현 하였다.
트레이 구현 시 추가로 더 작업하기 위해 나중에 다시 작업한다.
4. 커맨드에 대한 이벤트 처리 추가
<다이얼로그 속성의 메시지 버튼에서 메시지 이벤트를 추가해준다> |
위와 같이 이벤트 추가 후, 오버라이드 된 함수를 구현해준다.
// 트레이 메뉴 중 정보 창 호출 void CXXXDlg::OnTraymenuAbout() { CAboutDlg* pDlg = new CAboutDlg; pDlg->DoModal(); delete pDlg; } // 트레이 메뉴 중 다이얼로그 복원 void CXXXDlg::OnTraymenuOpen() { SetRestoreDialog(); <- 이건 나중에 구현 후 추가해 준다. } // 종료시 호출 void CXXXDlg::OnDestroy() { CDialog::OnDestroy(); }
WM_SIZE 메시지는 다이얼로그의 사이즈가 변경 되었을 경우 호출되는 내부 메시지 함수다.
이것을 virtual 로 상속받아 오버라이드 하여 사용한다.
오버라이드의 개념을 모르겠다면... 그것부터 확실히 숙지하고 작업 하도록 하자.
5. 트레이 동작 함수 추가
private: void SetMinimizeToTray(); void SetRestoreDialog(); LRESULT OnTrayIconClick(WPARAM wParam, LPARAM lParam); // 트레이 아이콘 클릭 메세시 처리 Callback 함수
SetMinimizeToTray() : 다이얼로그를 트레이로 보내는 함수
SetRestoreDialog() : 트레이에 있던 정보를 삭제 후 다이얼로그를 보여주는 함수
OnTrayIconClick() : 트레이 아이콘 클릭 시 수행 될 콜백 함수
#define TRAY_NOTIFY (WM_APP + 100) // 트레이 설정 함수 void CXXXDlg::SetMinimizeToTray() { NOTIFYICONDATA nId; ShowWindow(SW_SHOWMINIMIZED); PostMessage(WM_SHOWWINDOW, FALSE, SW_OTHERUNZOOM); nId.cbSize = sizeof(NOTIFYICONDATA); nId.hWnd = this->m_hWnd; nId.uID = 0; Shell_NotifyIcon(NIM_DELETE, &nId); nId.cbSize = sizeof(NOTIFYICONDATA); nId.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); nId.hWnd = this->m_hWnd; CString str; GetWindowText(str); _tcscpy_s(nId.szTip, str.GetBuffer(str.GetLength()+1)); str.ReleaseBuffer(); nId.uID = 0; nId.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; nId.uCallbackMessage = TRAY_NOTIFY; Shell_NotifyIcon(NIM_ADD, &nId); } // 윈도우 다이얼로그 복원 함수 void CXXXDlg::SetRestoreDialog() { NOTIFYICONDATA nId; nId.cbSize = sizeof(NOTIFYICONDATA); nId.hWnd = this->m_hWnd; nId.uID = 0; Shell_NotifyIcon(NIM_DELETE, &nId); ShowWindow(SW_RESTORE); SetForegroundWindow(); }
PostMessage() 를 통해 트레이의 메세지를 추가해 준다.
BEGIN_MESSAGE_MAP(CXXXDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_WM_SIZE() ON_MESSAGE(TRAY_NOTIFY, OnTrayIconClick) ON_COMMAND(ID_TRAYMENU_ABOUT, &CXXXDlg::OnTraymenuAbout) ON_COMMAND(ID_TRAYMENU_OPEN, &CXXXDlg::OnTraymenuOpen) ON_WM_DESTROY() ON_BN_CLICKED(IDOK, &CXXXDlg::OnBnClickedOk) END_MESSAGE_MAP()
메세지 맵에 위에서 등록 한 메세지를 등록해준다.
// Tray Icon 클릭 시 처리하는 콜백 함수 LRESULT CINESRemoteDMServerDlg::OnTrayIconClick(WPARAM wParam, LPARAM lParam) { switch(lParam) { case WM_LBUTTONDBLCLK: // 왼쪽 버튼 더블 클릭의 경우 다이얼로그 복원 { SetRestoreDialog(); break; } case WM_RBUTTONDOWN: // 오른쪽 버튼 클릭의 경우 메뉴 호출 { CPoint ptMouse; ::GetCursorPos(&ptMouse); CMenu Menu; Menu.LoadMenu(IDR_TRAY_MENU); CMenu* pMenu = Menu.GetSubMenu(0); pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, ptMouse.x, ptMouse.y, AfxGetMainWnd()); break; } } return 0; }
앞서 선언되었던 트레이 아이콘 클릭 시 호출되는 콜백함수를 구현해준다.
결론적으로 간단히 정리하자면,
시스템 메뉴 최소화 클릭 시 ON_WM_SIZE 메세지를 통하여 트레이 아이콘을 생성하여 등록하고,
현재의 다이얼로그는 숨김상태로 바꾼다.
트레이 좌, 우 클릭 시 해당하는 메시지를 호출하여 다이얼로그를 다시 보이게 하고 트레이에 등록된 정보를 없애거나,
아니면 메뉴를 호출하여 해당하는 동작을 수행하도록 한다.
조금만 응용하면, OnCommand() 메시지 처리 함수에서 시스템 메뉴의 X 버튼을 클릭 하였을 경우에도 트레이로 동작하도록
수행할 수 있다.
'Develope > MFC' 카테고리의 다른 글
[CTreeCtrl] 트리 컨트롤 Drag & Drop (0) | 2013.03.18 |
---|---|
Overlapped IO 와 IOCP 이야기 (4) (0) | 2013.03.13 |
Overlapped IO 와 IOCP 이야기 (3-2) (0) | 2013.03.13 |
Overlapped IO 와 IOCP 이야기 (3-1) (0) | 2013.03.13 |
Overlapped IO 와 IOCP 이야기 (2) (0) | 2013.03.13 |
Overlapped IO 와 IOCP 이야기 (1) (1) | 2013.03.13 |
Visual Leak Detector (Memory Leak 찾기) (0) | 2013.02.14 |
MINI DUMP 파일이 0KB 인 경우? (0) | 2013.01.24 |
윈도우 이벤트 로그 작성하기 (0) | 2013.01.23 |
컨트롤 폰트 설정 (0) | 2012.12.18 |