1. NOTIFYICONDATA 구조체
상태바 영역에 필요한 메시지 정보를 내포한다.
typedef struct _NOTIFYICONDATAA { DWORD cdSize; // 구조체의 크기(byte) HWND hWnd; // 트레이를 소유한 핸들 UINT uID; // 구분할수 있는 ID 값 UINT uFlags; // 멤버들이 내포하고 있는 데이터의 추가 정보를 어떻게 나타낼지 결정 UINT uCallbackMessage; HICON hIcon; #if (NTDDI_VERSION < NTDDI_WIN2K) TCHAR szTip[64]; #endif #if (NTDDI_VERSION >= NTDDI_WIN2K) TCHAR szTip[128]; DWORD dwState; DWORD dwStateMask; TCHAR szInfo[256]; union { UINT uTimeout; UINT uVersion; // Used with Shell_NotifyIcon flag NIM_SETVERSON. } DUMMYUNIONNAME; TCHAR szInfoTitle[64]; DWORD dwInfoFlags; #endif #if (NTDDI_VERSON >= NTDDI_WINXP) GUID guidItem; #endif #if (NTDDI_VERSON >= NTDDI_VISTA) HICON hBalloonIcon; #endif } |
2. ::Shell_NotifyIcon() API 함수
이 메서드는 작업표시줄에 메시지를 Send해주는 역할을 한다. 원형은 아래와 같다.
BOOL Shell_NotifyIcon ( DWORD dwMessage, PNOTIFYICONDATA lpdata; ); |
-. dwMessage : NIM_ADD, MIN_MODIFY, NIM_DELETE를 사용하여 트레이 아이콘을
추가, 수정, 삭제 할 수 있게 해준다.
-. lpdata : NOTIFYICONDATA 구조체를 통해 정보를 전달한다.
3. 트레이 아이콘 사용 예제
-. ESC 키를 누를경우 트레이 아이콘으로 등록한다.
-. 트레이 아이콘을 왼쪽버튼 더블클릭하면 정상적으로 활성화된다.
-. 트레이 아이콘에서 마우스 오른쪽 버튼을 누를 경우 팝업 메뉴가 뜬다.
1) PreTranslateMessage 메서드 사용해 ESC 키를 누를경우 트레이화
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) { if (pMsg->message == WM_KEYDOWN) { switch (pMsg->wParam) { case VK_ESCAPE : { // 트레이 아이콘 NOTIFYICONDATA nid; ZeroMemory(&nid, sizeof(nid)); nid.cdSize = sizeof(nid); nid.uID = 0; nid.hWnd = GetSafeHwnd(); nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE; BOOL bRet = ::Shell_NotifyIcon(NIM_ADD, &nid); AfxGetApp()->m_pMainWnd->ShowWindow(SW_HIDE); |
위 소스는 MainFrame에 구현한 소스이다. 그럼 PreTranslateMessage()의 설명을 생략하고
트레이 아이콘을 추가하는 부분을 설명하도록 하겠다.
// 트레이 아이콘 NOTIFYICONDATA nid; ZeroMemory(&nid, sizeof(nid)); nid.cdSize = sizeof(nid); nid.uID = 0; nid.hWnd = GetSafeHwnd(); nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE; BOOL bRet = ::Shell_NotifyIcon(NIM_ADD, &nid); AfxGetApp()->m_pMainWnd->ShowWindow(SW_HIDE); |
Shell_NotifyIcon에서 사용한 NOTIFYICONDATA 구조체 선언 및 초기화를 해준다.
-. nid.uFlags는 NIF_ICON | NIF_TIP | NIF_MESSAGE등의 아이콘, 툴팁, 메시지 사용을 지정.
-. nid.hIcon은 App의 아이콘을 로드.
-. nid.szTip은 툴팁으로 나올 문자열을 담는다.
-. nid.uCallbackMessage는 사용자 지정 메시지인 WM_TRAY_NOTIFICATION으로 지정.
::Shell_NotifyIcon에 NIM_ADD(아이콘 추가) 속성을 지정하고, 설정한 NOTIFYICONDATA 구조체 정보를 넘긴다.
마지막으로 현재 윈도우를 숨긴다.
2) 사용자 메시지를 추가
-. MainFram.h protected : afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg LRESULT OnTrayNotifycaton(WPARAM, LPARAM); DECLARE_MESSAGE_MAP() -. MainFram.cpp // CMainFrame BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) |
정의하는 WM_APP부터 시작하면 내부에서는 유일한 메시지 값이어야한다.
그렇기 때문에 WM_TRAY_NOTIFYCATON은 WM_APP + 1 치환한다.
그리고 사용자 메시지의 경우 WM_COMMNAD를 사용하기 때문에 메시지 맵에서 ONMESSAGE 를 사용한다.
그리고 OnTraynotifycaton(WPARAM wParam, LPARAM lParam)의 워ㅕㄴ형을 가진 메서드를 생성하고 지정한다.
WPARAM과 LPARAM은 SendMessage()나 PostMessage()를 사용해 메시지를 받을때 사용한다.
LRESULT CMainFrame::OnTrayNotifycation(WPARAM wParam, LPARAM lParam) { switch (lParam) { case WM_RBUTTONDOWN : { CPoint ptMouse; ::GetCursorPos(&ptMouse); CMenu menu; BOOL bRet = ::Shell_NotifyIcon(NIM_DELETE, &nid); |
-. WM_RBUTTONDOWN 메시지는 현재의 커서 위치를 알아와 트레이 아이콘 위에 이벤트가 일어날 경우
생성되어 있는 첫번째 인덱스 메뉴를 활성화 시킨다.
-. WM_LBUTTONDBLCLK 메시지는 트레이 아이콘의 uID를 지정하고 핸들을 얻어와 더블클릭시 트레이아이콘을
제거하고 윈도우를 활성화 시켜준다.