2011년9월6일_winAPI_WM_COMMAND메시지와 lParam, wParam의 값, 액셀러레이터(Accelerator), 메뉴편집기, 아이콘, 커서



● WM_COMMAND 메시지

프로그램 실행중에 사용자가 메뉴 항목을 선택하면 WM_COMMAND메시지가 발생한다.
이 때 어떤 메뉴 항목이 선택되었는가는 wParam의 하위 워드로 전달되므로 LOWORD(wParam)을 읽어 판단할 수 있다.
그 외에 액셀러레이터를 누를 때도 발생하며 또한 버튼, 에디트 박스 등의 컨트롤이 부모 윈도우로 통지 메시지를 보낼 때도 발생함.

image

메시지 발생 후 lParam과 wParam에는 상기의 그림과 같은 값들이 들어가게 각 값들의 의미는 아래의 표와 같다.
★아래의 도표는 무조건 외울 것

설명
lParam 통지 메시지를 발생시킨 컨트롤의 윈도우 핸들
LOWORD(wParam) 메뉴나 액셀러레이터, 컨트롤의 ID
HIWORD(wParam) 컨트롤이 보내는 통지 메시지로  액셀러레이터가 선택된 경우 1
                                                 메뉴가 선택된 경우 0

외울 것이 점점 많아 지는구나~ 죽을 때까지 공부합시다~
컨트롤은 나중에 할 것이라 자세한 설명은 생략하고 버튼, 에디트박스같은 것이다.





● 액셀러레이터(Accelerator)

윈도우즈에서 단축키(ShortCut)과 비슷한 것이다.
VS6.0에서 Ctrl + N키로 새로운 프로젝트나 새로운 파일들을 만들어 보았듯이 특수키를 사용해 메뉴를 빨리 접근하는 방법으로,
메뉴가 열린 상태에서만 사용가능한 Alt키를 쓰는 단축키(ShortCut)과 다르게 어떤 상태에서나 수행할 수 있다.

image

상기의 스크린샷에서 File메뉴의 F에 밑줄이 있다. 이렇게 밑줄이 있는 것을 단축키라고 하고,

image

더블클릭하여 속성창을 보면 File앞에 &가 붙여져 있다.
이 &의 의미는 Alt키와 F키를 동시에 눌러 File메뉴에 접근한다는 뜻이다.
액셀러레이터는 여기서 등록하는게 아니라 새로운 리소스를 만든다.

imageimage 

VS6.0메뉴 – Insert – Resource - Accelerator를 선택한 뒤 New버튼을 클릭하여 새로운 리소스를 만든다.
여기서도 Insert메뉴 앞에 I에 밑줄이 있다. 단축키로 접근이 가능하다는 뜻이다.

image 

리소스편집창이 뜨면 파란색막대를 더블클릭하여 액셀러레이터 속성창을 연다.

image 

ID에서 전에 만든 메뉴에 대한 ID를 찾고, Ctrl을 체크한 후에 Key값을 적으면,
Ctrl + A키로 해당메뉴를 접근할 수 있다.

image 

실행파일과 링크는..

HACCEL hAccel;


hAccel =LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
while(GetMessage(&Message, NULL, 0, 0)) {
    if(!TranslateAccelerator(hWnd, hAccel, &Message))         // 액셀러레이터인지 검사하여 맞으면,
    {                                                                      // WM_KEYDOWN메시지 없애고 WM_COMMAND발생.
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
}





● 메뉴편집기

//일단 생략




● 아이콘

image image 

메뉴 – Insert – Resource – Icon에서 New를 클릭하여 새로운 아이콘 리소스를 만든다.


image

사용법은 그림판과 비슷해 누구나 쉽게 그림을 그릴 수 있다.

실행파일과의 링크는…

WndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));






● 커서

image image

메뉴 – Insert – Resource – Cursor에서 New를 클릭하여 새로운 커서 리소스를 만든다.



image

사용법은 아이콘과 비슷한데 흑백이라 화려하진 못 하다.
위에 보니 Monochrome [32 x 32]라고 적혀 있는 것을 보니 흑백말고..
후에 칼라로 업그레이드 가능한 것을 알 수 있다. 지금은 안 된다.

실행파일과 링크는..

WndClass.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CURSOR1));


 

● 첨부 (전체소스코드)

   1: // 리소스.
   2: // 2011년 9월 6일 작성 
   3: #include <windows.h>        // 모든 API함수들의 원형과 사용하는 상수들이 정의되어 있음.
   4: #include "MsgProc.h"    //add
   5: #include "resource.h"    //자동으로 만들어지는 헤더파일.
   6:  
   7: LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);    //메시지처리함수
   8: HINSTANCE g_hlnst;    //핸들 인스턴스
   9: LPCTSTR lpszClass = TEXT("Menu");        //윈도우 제목으로 사용되는 const char * (문자열)
  10:  
  11: //add
  12: typedef struct MESSAGEMAP {
  13:     UINT iMessage;
  14:     LRESULT (*lpfnMsgProc)(HWND, WPARAM, LPARAM);
  15: } MESSAGEMAP;
  16:  
  17: //시작함수.
  18: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
  19: {
  20:     HWND hWnd;
  21:     MSG Message;
  22:     WNDCLASS WndClass;
  23:     g_hlnst = hInstance;
  24:     HACCEL hAccel;
  25:  
  26:     WndClass.cbClsExtra = 0;
  27:     WndClass.cbWndExtra = 0;
  28:     WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  29:     WndClass.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CURSOR1));
  30:     WndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
  31:     WndClass.hInstance = hInstance;
  32:     WndClass.lpfnWndProc = WndProc;
  33:     WndClass.lpszClassName = lpszClass;
  34:     WndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
  35:     WndClass.style = CS_HREDRAW | CS_VREDRAW;
  36:     RegisterClass(&WndClass);
  37:  
  38:     
  39:     hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,
  40:         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,        
  41:         NULL, (HMENU)NULL, hInstance, NULL);
  42:     
  43:     ShowWindow(hWnd, nCmdShow);
  44:  
  45:     hAccel =LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
  46:     while(GetMessage(&Message, NULL, 0, 0)) {
  47:         if(!TranslateAccelerator(hWnd, hAccel, &Message))
  48:         {
  49:             TranslateMessage(&Message);
  50:             DispatchMessage(&Message);
  51:         }
  52:     }
  53:  
  54:     return (int)Message.wParam;
  55: }
  56:  
  57: //운영체제가 호출하는 CALLBACK함수 (메시지 처리)
  58: LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
  59: {
  60:     //add
  61:     int i;
  62:  
  63:     static MESSAGEMAP MessageMaps[] = {
  64:         {WM_CREATE, OnCreate},
  65:         {WM_COMMAND, OnCommand},
  66:         {WM_LBUTTONDOWN, OnLButtonDown},
  67:         {WM_PAINT, OnPaint},
  68:         {WM_DESTROY, OnDestroy}
  69:     };
  70:  
  71:     for(i = 0 ; i < sizeof(MessageMaps) / sizeof(MessageMaps[0]) ; ++i)
  72:     {
  73:         if(MessageMaps[i].iMessage == iMessage)
  74:         {
  75:             return (*MessageMaps[i].lpfnMsgProc)(hWnd, wParam, lParam);
  76:         }
  77:     }
  78:     /////////////////////////////////
  79:  
  80:     return(DefWindowProc(hWnd, iMessage, wParam, lParam));
  81: }



   1: //MsgProc.cpp
   2:  
   3: #include "MsgProc.h"
   4: #include "resource.h"
   5:  
   6: LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
   7: {
   8:     return 0;
   9: }
  10:  
  11: LRESULT OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
  12: {
  13:     switch(LOWORD(wParam))
  14:     {
  15:     case ID_FILE_MENU1:
  16:         MessageBox(hWnd, TEXT("첫 번째 메뉴를 선택했습니다."), TEXT("Menu Demo"), MB_OK);
  17:         break;
  18:     case ID_FILE_MENU2:
  19:         MessageBox(hWnd, TEXT("두 번째 메뉴를 선택했습니다."), TEXT("Menu Demo"), MB_OK);
  20:         break;
  21:     case ID_FILE_EXIT:
  22:         DestroyWindow(hWnd);
  23:         break;
  24:     }
  25:  
  26:     return 0;
  27: }
  28:  
  29: LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
  30: {
  31:  
  32:     return 0;
  33: }
  34:  
  35: LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
  36: {
  37:     HDC hdc;
  38:     PAINTSTRUCT ps;
  39:  
  40:     hdc = BeginPaint(hWnd, &ps);
  41:  
  42:     EndPaint(hWnd, &ps);
  43:     return 0;
  44: }
  45:  
  46: LRESULT OnDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
  47: {
  48:     PostQuitMessage(0);
  49:     return 0;
  50: }
  51:  
   1: //MsgProc.h
   2: #ifndef __MSGPROC_H_
   3: #define    __MSGPROC_H_
   4:  
   5: #include <windows.h>
   6:  
   7: LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
   8: LRESULT OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
   9: LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam);
  10: LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam);
  11: LRESULT OnDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam);
  12:  
  13: extern HINSTANCE g_hInst;
  14:  
  15: #endif



<실행결과>

image image