작성일: 2009.05.19 (http://ospace.tistory.com/), ospace114@엠팔.컴
트레이 아이콘 생성
아래 코드는 프로그램 처음 시작할 때나 초기화되는 곳에 추가하면 된다. 혹은 따로 클래스를 만들어서 메소드로 호출해도된다.
NOTIFYICONDATA nid;
nid.cbSize = sizeof(nid); // 구조체 크기
nid.hWnd = this->m_hWNd; // 윈도우 핸들러
nid.uID = IDI_TRAY; // 트레이 아니콘 리소스 ID
nid.uFlag = NIF_MESSAGE | NIF_ICON | NIF_TIP; // 사용될 멤버 플래그
nid.uCallbackMessage = UM_TRAYICON; // 사용자 정의 메시지 식별자.
// nid.hIcon = LoadIcon(hInstance, IDI_TRAY); // win32
nid.hIcon = LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_TRAY)); // 트레이에 보여질 IDI_TRAY 아이콘 리소스 생성
lstrcpy(nid, szTip, "트레이아이콘"); // 트레이에 툴팁에 표시될 내용
Shell_NotifyIcon(NIM_ADD, &nid);
SendMessage(WM_SETICON, (WPARAM) TRUE, (LPARAM) nid.hIcon);
uFlags 플래그들
- NIF_ICON; hIcon 멤버가 유효함
- NIF_MESSAGE: uCallbackMessage 멤버가 유효함
- NIF_TIP: szTimp 멤버가 유효함
- NIF_STATE: dwState와 dwStateMask 멤버가 유효함
- NIF_INFO: szInfo, uTimeout, szInfoTitle, dwInfoFlags 멤버가 유효함.
- NIF_GUID: 예약됨.
트레이 아이콘 제거
트레이 남아 있는 아이콘을 제거
NOTIFYICONDATA nid;
nid.cbSize = sizeof(nid);
nid.hWnd = m_hWnd;
nid.uID = IDI_TRAY; // 삭제할 트레이 ID
Shell_NotifyIcon(NIM_DELETE, &nid);
Shell_NotifyIcon()에서 메시지 종류
- NIM_ADD: 트레이 상태 영역에 아이콘 추가. 구조체에 있는 hWnd와 uID 멤버 사용.
- NIM_DELETE: 아이콘을 제거. 구조체에 있는 hWnd와 uID 멤버 사용.
- NIM_SETFOCUS: 공통 컨트롤 5.0에서 지원. 테스크바 알림영역으로 포커스됨. 예를 들어 숏컷 메뉴가 esc키에 의해서 취소되면, NIM_SETFOCUS를 사용해서 포커스를 테스크바 알림 영역으로 돌려준다.
- NIM_SETVERSION: 공콩 컨트롤 5.0 지원. uVersion 멤버에 따랏 테스크바를 동작할려할 때에 사용. Win 2k에서 버전 5.0이 되는지 여부를 판별. 안된다면 이전 notify icon으로 동작하도록 해야함.
공통 컨트롤(참조: MSDN - Shell and Common Controls Versions)
- 4.0 : All DLL, Win 95, Win NT 4.0
- 4.7: All DLL, IE 3.x
- 4.71: All DLL, IE 4.0
- 4.72: All DLL, IE 4.01, Win 98
- 5.0: Shlwapi.dll, IE 5.0
- 6.0: Shlwapi.dll, IE 6.0, Win XP
- 5.0: Shell32.dll, Win 2k, Win ME
- 6.0: Shell32.dll, Win XP
- 5.8: Comctl32.dll, IE 5.0
- 5.81: Comctl32.dll, Win 2k, Win ME
- 6.0: Comctl32.dll, Win XP
메시지 처리하기
앞에서 정의한 uCallbackMessage 의 식별자 UM_TRAYICON를 핸들러를 등록한다.
먼저 식별자 정의
#define UM_TRAYICON (WM_USER + 1)
멤버 함수 선언
LONG TrayIconMessage(WPARAM wParam, LPARAM lParam);
메시지 맵에 추가
ON_MESSAGE(UM_TRAYICON, TrayIconMessage)
LONG xxx::TrayIconMessage(WPARAM wParam, LPARAM lParam)
{
if(lParam == WM_LBUTTONUP) {
MessageBox("Left button click", "INFO");
}
return 0;
}
메뉴 생성해서 호출하기
리소스에서 IDR_MENU1 메뉴 리소스를 생성하고 적당한 메뉴 아이템 추가. 트레이 아이콘에서 왼쪽 버튼을 누를경우 메뉴를 보여주기 위해서 앞의 TrayIconMessage()에서 다음 내용으로 변경.
CMenu menu, *pMenu;
POINT pt;
switch((UINT)lParam) {
case WM_LBUTTONUP):
menu.LoadMenu(IDR_MENU1);
pMenu = menu.GetSubMenu(0);
GetCursorPos(&pt);
pMenu->TrackPopupMenu(TPM_RIGHTALIGN, pt.x, pt.y, this);
break;
}
트레이 아이콘으로 숨기기
추가로 [x] 버튼을 클릭해서 프로그램 종료시 실제 종료하지 않고, 화면만 없애버리고 트레이 아이콘은 그대로 보여주고 싶다면, 아래와 같이 수정한다.
종료 핸들러 부분 수정. MFC인 경우는 OnClose핸들러
ShowWindow(SW_HIDE);
트레이 아이콘 더블클릭하여 프로그램 표시하기
앞의 TrayIconMessage()에서 더블 클릭에 대한 처리를 추가해줌.
case WM_LBUTTONDBLCLK):
ShowWindow(SH_SHOW);
break;
트레이 아이콘 변경
트레이 아이콘 변경 함수를 생성.
BOOL ChangIcon(HICON hIcon)
{
NOTIFYICONDATA nid;
nid.cbSize = sizeof(nid);
nid.uFlags = NIF_ICON;
nid.hWnd = m_hWnd;
nid.uID = IDR_MAINFRAME;
nid.uIcon = hIcon;
return Shell_NofifyIcon(NIM_MODIFY, &nid);
}
실제 사용시
ChangeIcon(LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_TRY2)));
아이콘 핸들러로 넘겨주는 이유는 뒤에서 나오는 애니메이션 트레이 아이콘을 위한 것이다.
애니메이션 트레이 아이콘
방법은 쉽다. 먼저 아이콘 핸들러를 배열로 초기화한다. 아래 예제는 총 8개의 아이콘 이미지를 연속으로 초기화한다.
주의할 것은 처음 아이콘 ID가 IDI_TRAY1에서 IDI_TRAY8까지 연속적으로 증가하는 값이어야 한다.
HICON icons[8];
for(int i = startIconID, j = 0; j < 8; ++i, ++j) {
icons[j] = LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(i));
}
에니메이션 작동은 다음과 같다. 일정 시간 타이머를 주고,
#define IDT_TIMER1 1
SetTimer(m_hWnd, IDT_TIMER1, 1000, NULL); // 0.1 sec timer
현재 표시될 아이콘 인덱스를 위한 변수로
int currentIcon = 0;
타이머 핸들러에서
ChangeIcon(icons[currentIcon]);
if(++currentIcon > 9) {
currentIcon = 0;
}
에니메이션을 멈추고 싶다면, 해당 타이머를 중지시키면된다.
KillTimer(m_hWnd, IDT_TIMER1);
트레이 아이콘은 생각보다 어렵지 않다. 물론 리소스 관리라는 귀찮은 작업은 있지만...
트레이 아이콘에서 왼쪽 버튼을 눌러
출처
[1] [MFC] 트레이아이콘 만들기
MSDN - Shell and Common Controls Versions
'3.구현 > VC++' 카테고리의 다른 글
Vista 호환 프로그램 데이터 저장위치 다루기 (0) | 2009.07.31 |
---|---|
[컨트롤이야기] 리치에디트(RichEdit) 컨트롤 사용하기 (4) | 2009.06.18 |
VC에서 운영체제별 매크로 선언 (0) | 2009.05.15 |
VC에서 자동으로 빌드번호 증가시키기 ( Incresing the build number automatically) (0) | 2008.08.13 |
Registry(레지스트리) 변경을 감시하여 이벤트 처리하기 (0) | 2008.08.07 |