고수닷넷 - 데미소다오렌지님
1. 트레이 통지와 관련된 함수와 파라미터
BOOL WINAPI Shell_NontifyIcon(DWORD dwMessage, PNOTIFYICONDATA pnid);
- NIM_ADD : 트레이에 새로운 아이콘 추가
- NIM_DELETE : 트레이 영역의 아이콘 제거
- NIM_MODIFY : 트레이 영역에 있는 아이콘 수정
dwMessage
로는 다음과 같은 값을 입력할 수 있습니다.
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; }
댓글