본문 바로가기

3.구현/VC++

트레이 아이콘 다루기

작성일: 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

반응형