1. 트레이에 ICON 넣기 & 시스템 메뉴에 항목추가하기
2. 커서 모양 바꾸기
3. DragDrop 구현( 파일이름 읽어오기 )
4. spy++ UI 따라해보기( ALT+TAB 버그 수정해보기 )
5. 실행시간에 ICON을 변경, 윈도우 클래스도 변경!!
more..
//-------------------------------------------------------------------------------
// 시스템 메뉴의 ID 16의 배수로 0xF000 보다 작게...
#define IDM_SYS_TOPMOST 0x0010
#define WM_TRAYMESSAGE WM_USER+100
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_CREATE:
{
// 시스템 메뉴의 핸들을 얻어낸다.
HMENU hMenu = GetSystemMenu( hwnd, FALSE );
// 메뉴를 추가한다.
AppendMenu( hMenu, MF_SEPARATOR, 0, 0 );
AppendMenu( hMenu, MF_STRING, IDM_SYS_TOPMOST, "항상위" );
}
return 0;
case WM_SYSCOMMAND:
// 주의 ID 조사시 하위 4비트를 0으로 놓고 조사한다.
switch( LOWORD( wParam & 0xFFF0 ) )
{
case IDM_SYS_TOPMOST:
MessageBox( hwnd, "항상위", "", MB_OK );
return 0;
case SC_MINIMIZE: // 닫기 메뉴의 ID
{
// 트레이에 Icon 넣기.
NOTIFYICONDATA nid = { 0 };
nid.cbSize = sizeof(nid);
nid.hIcon = LoadIcon( 0, IDI_WINLOGO );
nid.hWnd = hwnd;
nid.uCallbackMessage = WM_USER+100;
nid.uID = 1;
strcpy( nid.szTip, "Test" );
nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
Shell_NotifyIcon( NIM_ADD, &nid );
// 애니메이션 효과를 낸다..
RECT rcFrom;
GetWindowRect( hwnd, &rcFrom );
// 실제로는 작업표시줄을 구해야 한다.
RECT rcTo = { 1280, 1024, 1281, 1025 }; //화면 오른쪽 아래
DrawAnimatedRects( hwnd, IDANI_CAPTION, &rcFrom, &rcTo );
// 이제 윈도우를 숨긴다.
ShowWindow( hwnd, SW_HIDE );
}
return 0;
}
// 나머지 모든 메뉴를 처리하기 위해 아래로 보내야 한다.
return DefWindowProc( hwnd, msg, wParam, lParam );
case WM_TRAYMESSAGE:
if( wParam == 1 ) // Icon ID
{
if( lParam == WM_LBUTTONDBLCLK)
{
ShowWindow( hwnd, SW_SHOW );
}
else if( lParam == WM_RBUTTONUP )
{
// Context Menu 를 나타나게 해준다.
}
}
return 0;
case WM_LBUTTONDOWN:
//GetSystemMenu( hwnd, TRUE ); // 초기상태로 되돌린다.
return 0;
case WM_DESTROY:
// Tray Icon을 제거하고 종료해야 한다.
{
NOTIFYICONDATA nid = { 0 };
nid.cbSize = sizeof(nid);
nid.hWnd = hwnd;
nid.uID = 1;
Shell_NotifyIcon( NIM_DELETE, &nid );
}
PostQuitMessage(0);
return 0;
}
// 시스템 메뉴의 ID 16의 배수로 0xF000 보다 작게...
#define IDM_SYS_TOPMOST 0x0010
#define WM_TRAYMESSAGE WM_USER+100
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_CREATE:
{
// 시스템 메뉴의 핸들을 얻어낸다.
HMENU hMenu = GetSystemMenu( hwnd, FALSE );
// 메뉴를 추가한다.
AppendMenu( hMenu, MF_SEPARATOR, 0, 0 );
AppendMenu( hMenu, MF_STRING, IDM_SYS_TOPMOST, "항상위" );
}
return 0;
case WM_SYSCOMMAND:
// 주의 ID 조사시 하위 4비트를 0으로 놓고 조사한다.
switch( LOWORD( wParam & 0xFFF0 ) )
{
case IDM_SYS_TOPMOST:
MessageBox( hwnd, "항상위", "", MB_OK );
return 0;
case SC_MINIMIZE: // 닫기 메뉴의 ID
{
// 트레이에 Icon 넣기.
NOTIFYICONDATA nid = { 0 };
nid.cbSize = sizeof(nid);
nid.hIcon = LoadIcon( 0, IDI_WINLOGO );
nid.hWnd = hwnd;
nid.uCallbackMessage = WM_USER+100;
nid.uID = 1;
strcpy( nid.szTip, "Test" );
nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
Shell_NotifyIcon( NIM_ADD, &nid );
// 애니메이션 효과를 낸다..
RECT rcFrom;
GetWindowRect( hwnd, &rcFrom );
// 실제로는 작업표시줄을 구해야 한다.
RECT rcTo = { 1280, 1024, 1281, 1025 }; //화면 오른쪽 아래
DrawAnimatedRects( hwnd, IDANI_CAPTION, &rcFrom, &rcTo );
// 이제 윈도우를 숨긴다.
ShowWindow( hwnd, SW_HIDE );
}
return 0;
}
// 나머지 모든 메뉴를 처리하기 위해 아래로 보내야 한다.
return DefWindowProc( hwnd, msg, wParam, lParam );
case WM_TRAYMESSAGE:
if( wParam == 1 ) // Icon ID
{
if( lParam == WM_LBUTTONDBLCLK)
{
ShowWindow( hwnd, SW_SHOW );
}
else if( lParam == WM_RBUTTONUP )
{
// Context Menu 를 나타나게 해준다.
}
}
return 0;
case WM_LBUTTONDOWN:
//GetSystemMenu( hwnd, TRUE ); // 초기상태로 되돌린다.
return 0;
case WM_DESTROY:
// Tray Icon을 제거하고 종료해야 한다.
{
NOTIFYICONDATA nid = { 0 };
nid.cbSize = sizeof(nid);
nid.hWnd = hwnd;
nid.uID = 1;
Shell_NotifyIcon( NIM_DELETE, &nid );
}
PostQuitMessage(0);
return 0;
}
2. 커서 모양 바꾸기
more..
//////////////////////////////////////////////////////////////////////////////////////
HCURSOR hCursor = LoadCursor( hInstance, MAKEINTRESOURCE( IDC_CURSOR1 ) );
// 애니메이션 커서 Load
HCURSOR hCursor = LoadCursorFromFile( "C:\\windows\\cursors\\dinosaur.ani" );
//////////////////////////////////////////////////////////////////////////////////////
// 커서 위치별 변화시키기
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HCURSOR h1 = LoadCursorFromFile( "C:\\windows\\cursors\\sizens.ani" );
static HCURSOR h2 = LoadCursorFromFile( "C:\\windows\\cursors\\sizewe.ani" );
static HCURSOR h3 = LoadCursorFromFile( "C:\\windows\\cursors\\banana.ani" );
static RECT gameRect = { 10, 10, 100, 100 };
switch( msg )
{
case WM_SETCURSOR:
{
UINT code = LOWORD( lParam );
POINT pt;
GetCursorPos(&pt);
ScreenToClient( hwnd, &pt );
if ( code == HTCLIENT && PtInRect( &gameRect, pt ) )
{
SetCursor( h3 );
return TRUE;
}
if ( code == HTTOP || code == HTBOTTOM )
{
SetCursor( h1 );
return TRUE; // 커서변경한 경우 TRUE 리턴
}
if ( code == HTLEFT || code == HTRIGHT )
{
SetCursor( h2 );
return TRUE;
}
}
return DefWindowProc( hwnd, msg, wParam, lParam );
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
HCURSOR hCursor = LoadCursor( hInstance, MAKEINTRESOURCE( IDC_CURSOR1 ) );
// 애니메이션 커서 Load
HCURSOR hCursor = LoadCursorFromFile( "C:\\windows\\cursors\\dinosaur.ani" );
//////////////////////////////////////////////////////////////////////////////////////
// 커서 위치별 변화시키기
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HCURSOR h1 = LoadCursorFromFile( "C:\\windows\\cursors\\sizens.ani" );
static HCURSOR h2 = LoadCursorFromFile( "C:\\windows\\cursors\\sizewe.ani" );
static HCURSOR h3 = LoadCursorFromFile( "C:\\windows\\cursors\\banana.ani" );
static RECT gameRect = { 10, 10, 100, 100 };
switch( msg )
{
case WM_SETCURSOR:
{
UINT code = LOWORD( lParam );
POINT pt;
GetCursorPos(&pt);
ScreenToClient( hwnd, &pt );
if ( code == HTCLIENT && PtInRect( &gameRect, pt ) )
{
SetCursor( h3 );
return TRUE;
}
if ( code == HTTOP || code == HTBOTTOM )
{
SetCursor( h1 );
return TRUE; // 커서변경한 경우 TRUE 리턴
}
if ( code == HTLEFT || code == HTRIGHT )
{
SetCursor( h2 );
return TRUE;
}
}
return DefWindowProc( hwnd, msg, wParam, lParam );
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
3. DragDrop 구현( 파일이름 읽어오기 )
more..
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
// 탐색기가 보내주는 메세지
case WM_DROPFILES:
{
// Drop된 파일의 이름을 가진 메모리 핸들을 얻어 낸다.
HDROP hDrop = (HDROP)wParam;
// 먼저 갯수를 파악한다.
int count = DragQueryFile( hDrop, -1, 0, 0 );
for ( int i = 0; i < count; ++i )
{
// 파일의 이름을 꺼낸다.
char name[256] = { 0 };
DragQueryFile( hDrop, i, name, 256 );
MessageBox( 0, name, "", MB_OK );
}
//DragDrop을 종료한다.
DragFinish( hDrop );
}
return 0;
case WM_CREATE:
DragAcceptFiles( hwnd, TRUE );
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
{
switch( msg )
{
// 탐색기가 보내주는 메세지
case WM_DROPFILES:
{
// Drop된 파일의 이름을 가진 메모리 핸들을 얻어 낸다.
HDROP hDrop = (HDROP)wParam;
// 먼저 갯수를 파악한다.
int count = DragQueryFile( hDrop, -1, 0, 0 );
for ( int i = 0; i < count; ++i )
{
// 파일의 이름을 꺼낸다.
char name[256] = { 0 };
DragQueryFile( hDrop, i, name, 256 );
MessageBox( 0, name, "", MB_OK );
}
//DragDrop을 종료한다.
DragFinish( hDrop );
}
return 0;
case WM_CREATE:
DragAcceptFiles( hwnd, TRUE );
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
4. spy++ UI 따라해보기( ALT+TAB 버그 수정해보기 )
more..
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HCURSOR hCursor;
static HICON hFill, hEmpty;
static RECT rc = { 10, 10, 42, 42 };
static HINSTANCE hInstance;
switch( msg )
{
case WM_CREATE:
hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
hCursor = LoadCursor( hInstance, MAKEINTRESOURCE(IDC_CURSOR1) );
hFill = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_ICON1) );
hEmpty = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_ICON2) );
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
DrawIcon( hdc, rc.left, rc.top, hFill );
EndPaint( hwnd, &ps );
}
return 0;
case WM_LBUTTONDOWN:
{
POINT pt = { LOWORD( lParam ), HIWORD( lParam ) };
if( PtInRect( &rc, pt ) )
{
SetCursor( hCursor );
SetCapture( hwnd );
HDC hdc = GetDC( hwnd );
DrawIcon( hdc, rc.left, rc.top, hEmpty );
ReleaseDC( hwnd, hdc );
}
}
return 0;
case WM_LBUTTONUP:
if( GetCapture() == hwnd )
{
ReleaseCapture();
//InvalidateRect( hwnd, &rc, TRUE );
}
return 0;
// 알트탭을 누르면 캡쳐상태가 풀리지만 다시 그리지 못한다. 이를 위해서
// 캡쳐상태가 변경됬을떄 다시 그려주도록 한다.
case WM_CAPTURECHANGED:
{
InvalidateRect( hwnd, &rc, TRUE );
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
{
static HCURSOR hCursor;
static HICON hFill, hEmpty;
static RECT rc = { 10, 10, 42, 42 };
static HINSTANCE hInstance;
switch( msg )
{
case WM_CREATE:
hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
hCursor = LoadCursor( hInstance, MAKEINTRESOURCE(IDC_CURSOR1) );
hFill = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_ICON1) );
hEmpty = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_ICON2) );
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
DrawIcon( hdc, rc.left, rc.top, hFill );
EndPaint( hwnd, &ps );
}
return 0;
case WM_LBUTTONDOWN:
{
POINT pt = { LOWORD( lParam ), HIWORD( lParam ) };
if( PtInRect( &rc, pt ) )
{
SetCursor( hCursor );
SetCapture( hwnd );
HDC hdc = GetDC( hwnd );
DrawIcon( hdc, rc.left, rc.top, hEmpty );
ReleaseDC( hwnd, hdc );
}
}
return 0;
case WM_LBUTTONUP:
if( GetCapture() == hwnd )
{
ReleaseCapture();
//InvalidateRect( hwnd, &rc, TRUE );
}
return 0;
// 알트탭을 누르면 캡쳐상태가 풀리지만 다시 그리지 못한다. 이를 위해서
// 캡쳐상태가 변경됬을떄 다시 그려주도록 한다.
case WM_CAPTURECHANGED:
{
InvalidateRect( hwnd, &rc, TRUE );
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
5. 실행시간에 ICON을 변경, 윈도우 클래스도 변경!!
more..
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HBRUSH hBrush = CreateSolidBrush( RGB(255, 0, 0) );
static HICON hIcon = LoadIcon( GetModuleHandle(0), "aaa" );
static HINSTANCE hInstance;
switch( msg )
{
case WM_CREATE:
{
// LPARAM에는 CreateWindow에서 사용한 내용이 들어 있다.
LPCREATESTRUCT p = (LPCREATESTRUCT)lParam;
hInstance = p->hInstance;
}
return 0;
case WM_LBUTTONDOWN:
// 실행시간에 ICON을 변경하는 2가지 방법
// 1. 클래스 자체의 ICON을 변경 - 이 클래스로 만든 모든 윈도우의 ICON 변경.
SetClassLong( hwnd, GCL_HICON, (LONG)hIcon );
SetClassLong( hwnd, GCL_HBRBACKGROUND, (LONG)hBrush );
InvalidateRect( hwnd, 0, TRUE );
// 2번째 방법 - WM_SETICON 메세지 사용 - 현재 윈도우만 변경.
SendMessage( hwnd, WM_SETICON, 0, (LPARAM)hIcon );
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
{
static HBRUSH hBrush = CreateSolidBrush( RGB(255, 0, 0) );
static HICON hIcon = LoadIcon( GetModuleHandle(0), "aaa" );
static HINSTANCE hInstance;
switch( msg )
{
case WM_CREATE:
{
// LPARAM에는 CreateWindow에서 사용한 내용이 들어 있다.
LPCREATESTRUCT p = (LPCREATESTRUCT)lParam;
hInstance = p->hInstance;
}
return 0;
case WM_LBUTTONDOWN:
// 실행시간에 ICON을 변경하는 2가지 방법
// 1. 클래스 자체의 ICON을 변경 - 이 클래스로 만든 모든 윈도우의 ICON 변경.
SetClassLong( hwnd, GCL_HICON, (LONG)hIcon );
SetClassLong( hwnd, GCL_HBRBACKGROUND, (LONG)hBrush );
InvalidateRect( hwnd, 0, TRUE );
// 2번째 방법 - WM_SETICON 메세지 사용 - 현재 윈도우만 변경.
SendMessage( hwnd, WM_SETICON, 0, (LPARAM)hIcon );
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}