|
작업 표시줄의 오른쪽에 시계를 포함한 작은 아이콘들이 배치되어 있는 영역을 말한다. 주로 시스템상태를 보여주는 감시하는 프로그램이나 백그라운드 작업을 하는 프로그램을 관리하는 부분이다. |
ú TRAY 장점
TRAY아이콘은 하나의 응용프로그램을 대표하면서 적은 공간을 차지하기 때문에 유용하다. 그리고 아이콘 별로 팝업메뉴, 더블 클릭 등 다양한 명령을 내릴 수 있고 애니메이션 까지도 가능하며 예를 들어 볼륨조절기가 있다.
또한 어떤 프로그램이든지 이 영역에 아이콘을 등록 할 수 있고 수정이 가능하며 아이콘으로부터 사용자의 입력을 받아 들일 수도 있다.
ú Shell_Notifylcon()함수
이 함수는 작업표시줄에 메시지를 Send해주는 역할을 한다 |
BOOL Shell_NotifyIcon (DWORD dwMessage, PNOTIFYICONDATA pnid);
PNOTFYICONDNDAT pnid : 이 구조체에는 작업에 사용될 정보들이 전달
TRAY로 보내는 메시지
메시지 |
설명 |
NIM_ADD |
트레이에 아이콘을 등록한다. 아이콘과 함께 툴팁, 콜백 메세지등 을 지정 할수 있다 |
NIM_DELETE |
등록한 아이콘을 삭제한다 |
NUM_MODIFY |
등록한 아이콘이나 툴팁등을 변경한다 |
예 Shell_NotifyIcon(NIM_ADD,&nid); è 좌표 값을 넣어줌
ú NOTIFYICONDATA 구조체
이 구조체에 등록 또는 수정하고자 하는 아이콘 정보를 채운 후 Shell_NotifyIcon 함수를 호출하면 트레이에 아이콘이 나타나며 아이콘을 등록한 윈도우는 사용자가 아이콘을 클릭할 때 콜백 메시지를 받게 된다. |
될수 있으므로 등록된 아이콘 끼리 구별하기 위한 아이디
UINT uFlags; //아래 참조(※)
DWORD dwStateMask;
Union {
UINT uTimeout; ▩풍선도움말 지정
UINT uVersion;
} DUMMY UNIONNAME;
TCHAR szInfoTitle[64];
DWORD dwInfoFlags;
} NOTIFYICONDATA, *PNOTIFYICONDATA;
ú Flag
플래그 |
설명 |
NIF_ICON |
hIcon 멤버로 아이콘을 지정한다 LoadIcon 등의 함수로 아이콘 핸들을 얻은 후 이멤버에 대입 |
NIF_MESSAGE |
uCallbackMesage로 콜백 메시지를 지정함 트레이는 사용자가 아이콘을 클릭할때 이메세지를 hWnd로 보냄 |
NIF_TIP |
szTip 멤버로 툴팁을 지정한다 최대 64자까지 지정해놓으면 아이콘위에 마우스 커서가 머무를 때툴팁이 나타난다(풍선도움말) |
NIF_STATE |
dwState와 dwStateMask 멤버로 상태를 지정 |
NIF_INFO |
풍선 도움말을 보여준다 szInfo,uTimout,dwInFlags 멤버사용 |
ú 예제 CODE
#define TRAY_NOTIFY (WM_APP + 100) //사용자정의 메시지
NOTIFYICONDATA nid;
nid.cbSize= sizeof(nid);
nid.hWnd= hWnd;
nid.uID= 1;
nid.uFlags= NIF_ICON | NIF_TIP | NIF_MESSAGE;
nid.uCallbackMessage= TRAY_NOTIFY;
nid.hIcon= LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON));
lstrcpy(nid.szTip, TEXT("TRAY ICON 실습”));
ú PopupMenu 붙이기
§ 사용자가 아이콘에게 내리는 명령의 수가 제한 되어 있음 § 사용 가능한 명령의 목록을 나열해 두고 사용할 수 있음 § 많은 종류의 명령 항목을 포함할 수 있으며, 그 명령을 일일이 외우지 않아도 되므로 편리 § 마우스 왼쪽 버튼을 눌러졌다는 통지 메시지를 받았을 때 팝업메뉴를 띄우고 WM_COMMAND에 메뉴 항목의 명령을 처리 PopupMenu란?
ú GetCursorPos()함수
|
◆ 좌표를 직접 조사하여야함 트레이의 통지메시지는 단순히 마우스버튼이 눌려졌다는 상태만 보내 주고 마우스 좌표를 전달 해주지 않음
예 : POINT pt;
GetCursorPos(point &pt); è 좌표 값을 넣어줌
ú TrackPopupMenu()함수
§ PopupMenu를 띠우는 함수 |
BOOL TrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, int nReserved, HWND hWnd, CONST RECT *prcRect); hMenu : 메뉴의 핸들 uFlags : 메뉴가 보여질 위치의 플래그 x, y : 메뉴가 나타날 좌표 nReserved : 0으로 줌 hWnd : 윈도우 핸들 (WM_COMMAND 메시지를 받음) prcRect : 메뉴가 차지하는 화면의 영역 (NULL입력 시 메뉴의 바깥쪽을 클릭할 경우 메뉴는 사라짐)
플래그 |
설명 |
TPM_CENTERALIGN |
정한 위치의 중앙에 오게 한다. |
TPM_LEEFTALIGN |
지정한 위치의 좌측 정렬 |
TPM_RIGHTALIGN |
지정한 위치의 오른쪽 정렬 |
TPM_BOTTOMALIGN |
지정한 위치의 바닥에 정렬 |
TPM_TOPALIGN |
지정한 위치의 위쪽에 정렬 |
TPM_VCENTERALIGN |
지정한 위치의 수직중앙 정렬 |
TPM_LEFTBUTTON |
마우스 왼쪽 버튼을 눌러 팝업메뉴를 선택한다. |
TPM_RIGHTBUTTON |
마우스 오른쪽 버튼을 눌러 팝업메뉴를 선택한다. |
예 :
TrackPopupMenu( hTRAYMenu, TPM_LEFTBUTTON, pt.x, pt.y, 0, hWnd, 0 );
è 왼쪽버튼을 클릭시 팝업메뉴 선택
ú SetForegroundWindow()함수
이 함수는 TrackPopupMenu() 앞,뒤로 넣어주어야 함 |
쉘 라이브러리는 팝업메뉴가 출력 된 후 이 메뉴를 제대로 지우지 못함
이 함수 호출문은 사실상 불필요하나 쉘 라이브러리 버그를 피하기 위해 반드시 있어야 함 |
ú 예제 CODE
HMENU hMenu, hTrayMenu; hMenu = LoadMenu(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MENU) ); htrayMenu = GetSubMenu( hMenu, 0 ); POINT pt; GetCursorPos(&pt); SetForegroundWindow(hWnd); TrackPopupMenu( hTRAYMenu, TPM_LEFTBUTTON, pt.x, pt.y, 0, hWnd, 0 ); SetForegroundWindow(hWnd);
ú 실습
▦ CODE 부분
#include <windows.h>
#include "resource.h"
#define TRAY_NOTIFY (WM_APP + 100) //TRAY_NOTIFY를 WM_APP + 100의 사용자 정의 메시지로 정의
//사용자가 아이콘을 클릭할 때 아이콘을 등록한 윈도우로 보내짐
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage, WPARAM wParam,LPARAM IParam);
void OnCommand(HWND hWnd,WORD cid,WORD cmsg,HWND cWnd);
void OnDestroy(HWND hWnd);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void OnCreate(HWND hWnd);
void OnTrayMessage(HWND hwnd, WPARAM wParam, LPARAM lParam);
void MenuLoad(HWND hWnd);
void MemoProc(HWND hWnd);
void DrawProc(HWND hWnd);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
INT WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdParam,int nCmdShow)
{
LPCTSTR lpszClass=TEXT("TrayIcon만들기 실습");
WNDCLASS wndclass = {0,};
wndclass.hInstance = hInstance;
wndclass.lpszClassName=lpszClass;
wndclass.lpfnWndProc = WndProc;
RegisterClass(&wndclass);
CreateWindow(lpszClass,lpszClass,0,0,0,0,0,0,0,hInstance,0);
MSG Message;
while (GetMessage(&Message,NULL,0,0)) {
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
switch (iMessage) {
case WM_CREATE: OnCreate(hWnd); break;
case TRAY_NOTIFY: OnTrayMessage(hWnd, wParam, lParam); break;
case WM_COMMAND: OnCommand(hWnd, LOWORD(wParam),HIWORD(wParam),(HWND)lParam); break;
case WM_DESTROY: OnDestroy(hWnd); break;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}
void OnCommand(HWND hWnd,WORD cid,WORD cmsg,HWND cWnd)
{
switch(cid)
{
case ID_DRAWPANNEL : DrawProc(hWnd); break;
case ID_MEMO : MemoProc(hWnd); break;
case ID_EXIT : DestroyWindow(hWnd); break;
}
}
void OnCreate(HWND hWnd)
{
/////////////////////////////작업정보전달 구조체////////////////////////////////
NOTIFYICONDATA nid;
nid.cbSize = sizeof(nid);
nid.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON));
nid.hWnd = hWnd;
lstrcpy(nid.szTip, TEXT("TRAY ICON 실습 ~ing"));
nid.uCallbackMessage= TRAY_NOTIFY;
nid.uID = 1;
nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
Shell_NotifyIcon(NIM_ADD,&nid);
}
/////////////////////////////사용자 정의 메세지 발생시 호출되는부분//////////////////////////
void OnTrayMessage(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
if( wParam == 1 )
{
if( lParam == WM_RBUTTONUP)
{
MenuLoad(hWnd);
}
else if( lParam == WM_LBUTTONDBLCLK)
{
MessageBox(0,TEXT("왼쪽 클릭"),TEXT("경고"),MB_OK);
}
}
}
/////////////////////////[TrayIcon 클릭 시 팝업 메뉴를 띄우는 부분]///////////////////////////////////
void MenuLoad(HWND hWnd)
{
HMENU hMenu = LoadMenu(GetModuleHandle(0), MAKEINTRESOURCE(IDR_MENU));
HMENU hTrayMenu = GetSubMenu(hMenu, 0);
POINT pt;
GetCursorPos(&pt);
SetForegroundWindow(hWnd);
TrackPopupMenu(hTrayMenu, TPM_LEFTBUTTON, pt.x, pt.y, 0, hWnd, 0);
SetForegroundWindow(hWnd);
DestroyMenu(hTrayMenu);
DestroyMenu(hMenu);
}
////////////////////////////////[그림판 & 메모장 만든 부분]////////////////////////////////////////////
void MemoProc(HWND hWnd)
{
TCHAR notepad[] = TEXT("notepad.exe");
STARTUPINFO ps={0,};
PROCESS_INFORMATION pi;
CreateProcess(0,notepad,0,0,0,0,0,0,&ps,&pi);
}
void DrawProc(HWND hWnd)
{
TCHAR paint[] = TEXT("mspaint.exe");
STARTUPINFO ps={0,};
PROCESS_INFORMATION pi;
CreateProcess(0,paint,0,0,0,0,0,0,&ps,&pi);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void OnDestroy(HWND hWnd)
{
NOTIFYICONDATA nid;
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uID = 0;
Shell_NotifyIcon(NIM_DELETE,&nid);
PostQuitMessage(0);
}
ú 참고문헌
*윈도우즈 API 정복 2 [한빛미디어 김상형]
|