posted by nsakura 2010. 7. 20. 23:31

잠시 언급을 했지만 액셀러레이터는 단축키이다.

그럼 어떻게 설정하는지 보자.

리소스 메뉴 소스를 열어서  추가할것이다.




ID에는 액셀러레이터의 아이디인데. 지금 소스는 매뉴도 있으니 매뉴의 NSAKURA와 같은 아이디를 부여했다.

Modifiers에서 조합키를 설정한다 모두 체크되면 or이 아니라 and이기때문에 컨트롤 알트 쉬프트를 누른상태에서 h키를 눌러야 한다.

지금 설정은 컨트롤+h가 되겠다.

Type는 어떤탑으로 키를 쓸것인가 가상키인가 아스키코드인가 선택인데.

가상코드가 종류가 다양함으로 가상코드를 주로 많이 쓴다.

이렇게만 해두면 왠지 모르게 코드 수정없이 해도 동작이 될것 같은데 그건 아니다.

코드도 수정을 해야하는데.

다음과 같이 수정을 한다.

#include <windows.h>
#include "resource.h"

HINSTANCE g_Inst;
LPCTSTR wndName=TEXT("GFP MENU");

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);


int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 HACCEL hAccel;
 g_Inst=hInstance;

 WndClass.cbClsExtra=0;
 WndClass.cbWndExtra=0;
 WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
 WndClass.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(IDC_CURSOR1));
 WndClass.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
 WndClass.hInstance=hInstance;
 WndClass.lpfnWndProc=WndProc;
 WndClass.lpszClassName=wndName;
 WndClass.lpszMenuName=(TCHAR*)IDR_MENU1;
 WndClass.style=CS_HREDRAW|CS_VREDRAW;
 RegisterClass(&WndClass);

 hWnd=CreateWindow(wndName,wndName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL);

 ShowWindow(hWnd,nShowCmd);
 
 hAccel=LoadAccelerators(hInstance,MAKEINTRESOURCE(IDR_ACCELERATOR1));
 while(GetMessage(&Message,NULL,0,0)){
  if(!TranslateAccelerator(hWnd,hAccel,&Message)){
   TranslateMessage(&Message);
   DispatchMessage(&Message);
  }
 }


 return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam){
 switch(iMessage){
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 case WM_COMMAND:
  switch(LOWORD(wParam)){
  case ID_NSAKURA:
   MessageBox(hWnd,TEXT("Nsakura 입니다."),TEXT("NSAKURA"),MB_OK);
   break;
  case ID_EXIT:
   MessageBox(hWnd,TEXT("종료 합니다.."),TEXT("EXIT"),MB_OK);
   DestroyWindow(hWnd);
  }
  return 0;
 }
 
 return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}


일단 액셀러레이터를 사용하기위해서는 액셀러레이터 변수가 필요하다.

HACCEL hAccel;

갑자기 뜸금없이 못보던 함수가 2개가 등장했다. 당황하지 말자.

hAccel=LoadAccelerators(hInstance,MAKEINTRESOURCE(IDR_ACCELERATOR1));

이 함수의 원형을 알아보자

HACCEL LoadAccelerators(HINSTANCE hInstance, LPCTSTR lpTableName);

이 함수로 리소스로로부터 액셀러레이터를 불러온다.

첫 번째 인수는 굳이 설명할 필요가 없을 것같고..

두 번째 인수는 엑셀레이터 테이블을 지정한다.

리소스는 기본적으로 할당할때 정수로 할당하기때문에 MAKEINTRESOURCE사용 하였다.

두 번째 함수는 TranslateAccelerator(hWnd,hAccel,&Message) 인데.

원형을 보자.

int TranslateAccelerator(HWND hWnd, HACCEL hAccTable,LPMSG lpMsg);

이 함수는 키보드 메세지를 WM_COMMAnd 메세지로 변경하여 액셀러레이터가 동작 할 수 있도록 한다. 액셀러레이터가 컨트롤 +H

입력된다고 치면 컨트로+H는 액셀러레이터 이전에 키보드에서 입력을 받았기 때문에 WM_KEYDOWN을 발생할것이다. 그대로 내버려

놔둬버리게 되면 WndProc의 WM_KEYDOWN 메세지 처리 루틴에서 먼저 이 키 값을 처리해버릴 것이다[위의 소스는  WM_KEYDOWN

은 없지만 있다고 생각하자] 즉 TranslateAccelerator함수로 받은 키가 액셀러레이터이라면 리턴으로 1 리턴 [if에선 1이상은

참으로 인식] WM_COMMAND를 발생시킨다.

즉.   if(!TranslateAccelerator(hWnd,hAccel,&Message)){

이부분은 액셀러레이터가 아니라면 기본 작업을 수행한다.

라고 생각하면 간단하다.

ps : TranslateAccelerator가 리턴이 확실히 1인지는 안해봐서 확신이 안서지만 리눅스 기반의 저런기능의
 
함수라면 성공시1 실패시 0

이기 때문에 아마 같지 않을까? 라고 생각한거다 복잡하면 성공하면 TRUE 실패하면 FALSE라고 생각하면 됨.

'Computer > Win API' 카테고리의 다른 글

WinApi 그래픽 [GetStockObject]  (0) 2010.07.21
WinApi 리소스 [String Table]  (0) 2010.07.21
WinApi 리소스 [아이콘][커서]  (2) 2010.07.20
WinApi 리소스 [메뉴]  (0) 2010.07.20
WinApi WM_SIZE  (0) 2010.07.20