본문 바로가기

API

메뉴의 단축키, 액셀러레이터 생성

728x90
반응형

전 포스트에 이어서 메뉴 관련하여 기능을 알아보도록 하겠습니다. 우선 메뉴는 리소스 파일을 사용해서 만들어야 하고 실제 코드에서는 리소스 파일 생성 때 자동으로 생성되는 resource.h 파일을 include 해야하고 lpszMenuName = MAKEINTRESOURCE(해당 메뉴이름) 이렇게 대입해야 메뉴가 생성이 가능하게 되는 것입니다. 혹시 메뉴 생성 방법을 모르신다면 이전 포스팅을 먼저 보시고 이 포스팅을 보시기 바랍니다
링크 : http://darkangelus.tistory.com/entry/메뉴-만들기
위 링크로 가시면 리소스를 이용하여 메뉴를 생성하는 것을 알수 있을 것입니다.

그럼 이번에는 액셀러레이터와 단축키에 대해서 알아보죠. 액셀러레이터란 일종의 단축키 입니다. 하지만 단축키라는 말은 윈도우에서는 다른 것을 뜻하기 때문에 액셀러레이터라고 한다고 하더군요. 액셀러레이터란 Ctrl + P 같이 어떠한 기능이 곧바로 실행되는 키보드 조합키를 말하는 것입니다. 그리고 윈도우에서 말하는 단축키는 메뉴 이름에 &를 넣어 Alt 키와 함께 사용하는 키를 단축키라고 하죠.

그럼 단축키와 액셀러레이터를 만들어 보도록 하겠습니다. 이것도 상당히 간단히 만들수 있으니 혹시 '어려운거아냐??'라는 생각을 가지신 분은 전혀 걱정 안하셔도 됩니다 ^^

단축키는 속성창에서 Caption에서  메뉴의 원하는 글자앞에 &를 붙이면 됩니다. 저는 File, Capture 에서 첫글짜를 따서 &File, &Capture 로 단축키를 만들었습니다. 하위 메뉴 항목은 &Save, E&xit, F&ullScreenCapture, F&ocusScreenCaputre 이런식으로 주었습니다. 최상위 메뉴가 여러개 있을 때 이것들 중에서 같은 문자가 단축키로 되면 안되고 하위 메뉴에서도 같은 단위 메뉴끼리는 같은 문자가 단축키로 주어지면 안된다는거 기억해 두시기 바랍니다.
액셀러레이터 생성 방법은 Caption에서 뒤에 Ctrl + p 이런식으로 입력해 주면 됩니다. 이때 팁이라면 캡션 뒤에 \t를 주어 적당히 칸을 띄워 적는다는 것입니다. 이렇게 되면 가지런히 오른쪽으로 정렬이 되기 때문이죠. 메뉴의 모습을 살짝보도록 하죠.


다음과 같이 등록이 되는것을 볼수 있죠. 이제 실행을 시키게 되면 단축키가 잘 눌러지는 것을 볼 수가 있죠. 마우스 없이 키보드의 단축키로만으로 이것 저것 실행시킬 수 있는 걸 볼 수 있을 것입니다. 하지만 현재 아무리 액셀러레이터 키를 눌러 보아도 전혀 동작을 하지 않는 것을 볼 수가 있지요. 이것은 액셀러레이터는 따로 리소스를 추가 하여야만 하기 때문입니다. 그럼 액셀러레이터 추가를 위해 리소스를 추가 해 보도록 하죠 리소스 추가 대화 상자에서 Accelerator를 선택을 합니다.
그러면 Accelerator에 속성이 4가지가 나오는데 ID, Key, Modifiers, Type 이 있는데 ID 메뉴 항목과 일대일로 대응되기 때문에 드롭다운 리스트에서 맡는 아이디를 설정해줍니다. Key는 원하는 키를 넣어주면 되고요. Modifiers는 조합키를 선택하면 되고요. Type 아스키인지 가상키 코드인지 설정하는 것입니다. 해당 메뉴를 다 넣어주고 저장해주면 되죠. 엑셀러레이터를 다 등록 되어있어 WM_COMMAND는 수정할 필요가 없습니다. WinMain에서만 수정이 되면 됩니다.

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)

{

  HWND hWnd;

  MSG Message;

  WNDCLASS WndClass;

  g_hInst = hInstance;

  HACCEL hAccel;

 

  WndClass.cbClsExtra = 0;

  WndClass.cbWndExtra = 0;

  WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

  WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);

  WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);

  WndClass.hInstance = hInstance;

  WndClass.lpfnWndProc = WndProc;

  WndClass.lpszClassName = lpszClass;

  WndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);

  WndClass.style = CS_HREDRAW | CS_VREDRAW;

  RegisterClass(&WndClass);

 

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

  ShowWindow(hWnd, nCmdShow);

 

  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;

}

빨간색으로 쓴 부분이 액셀러레이터를 설정하는 부분입니다. 우선 HACCEL 핸들러를 받을 변수를 준비하고 LoadAccelerators()함수로 엑셀러레이터 테이블을 읽어 들입니다. IDR_ACCELERATOR1이 정수값으로 존재하기 때문에 역시 MAKEINTRESOURCE 매크로를 사용해야 되고요. TranslateAccelerator()함수는 키보드 메시지를 WM_COMMAND 메시지로 변경하여 엑셀러레이터가 동작할 수 있도록 만들어 주는 역할을 합니다. 설명을 하자면 Ctrl + A가 입력되었다면 액셀러레이터이기 전에 키보드 입력 메시지인 WM_KEYDOWN 메시지가 발생할 것입니다. 이걸 그냥 냅두면 당연히 WinProc에서 WM_KEYDOWN 메시지 루틴이 이 키값을 처리하게 될 것이고요. 하지만 TranslateAccelerator() 함수를 쓰면 hAccTable에 있는지 먼저 검사하고 처리를 하게 만드는 것이지요. 그래서 액셀러레이터 처리를 할 수 있게 되는 것입니다.

또 속성에 보면 메뉴의 스타일을 줄수 있는 속성들이 몇개가 있습니다. ID, Caption은 항목의 아이디와 보여줄 부분을 써주는것이고 Separator, Checked, Grayed, Inactive, Help, Popup, Break 등의 속성을 정할 수 있습니다. 이 속성들은 이름만 봐도 대충 뭐에 쓰는건지 알 수 있기에 있다는것만 알고 넘어가도록 하겠습니다.

메뉴에 대해서 두개의 포스트로 알아 보았는데요. 어려운 부분은 없었지만, 메뉴를 설정하는 것도 상당히 노가다가 필요한 부분인 것 같다는 생각이 들더군요. 여러분은 어떠신지요? ㅎ

그럼 메뉴에 대한 포스트는 이것으로 마치도록 하겠습니다
감사합니다.

728x90
반응형

'API' 카테고리의 다른 글

1초에 한번씩 캡쳐 화면 파일로 저장하기  (0) 2010.03.27
디렉토리 생성  (0) 2010.03.27
Win API Timer  (0) 2010.03.21
캡쳐 화면 BMP로 저장하기  (0) 2010.03.14
메뉴 만들기  (1) 2010.03.11
포커스가 있는 윈도우 캡쳐  (0) 2010.03.10
API로 구현한 전체화면 캡쳐 소스  (0) 2010.03.09
DC 구조체에 관해....  (1) 2010.03.09
버튼 생성  (0) 2010.03.06
API의 첫 시작  (0) 2010.03.05