블로그 이미지
하루, 글. 그림. 영상매체. 표현을 도와주는 기기들. 도전 중. 동화다아아
    동화다아아

    카테고리

    분류 전체보기 (176)
    잡담 (1)
    IT 기기-리뷰&뉴스 (7)
    리뷰 - 도서 (1)
    리뷰 - 영상 (0)
    리뷰 - 그림/음악 (1)
    내장형 하드웨어 (163)
    Total
    Today
    Yesterday
     

    - WM_COMMAND

    ⇒ 프로그램 실행중에 사용자가 메뉴 항목을 선택하면 WM_COMMAND 메시지가 발생한다.

    ⇒ 이 때 어떤 메뉴 항목이 선택되었는가는 wParam의 하위 워드로 전달되므로 LOWORD(wParam)을 읽어 판단할 수 있다. 그래서 Menu.cpp의 WndProc에서는 WM_COMMAND 메시지를 받을 경우 switch 문으로 다시 LOWORD(wParam)의 값에 따라 분기를 하여 각 메뉴 항목에 따른 처리를 발생한다.

    ⇒ ID_FILE_MENU1 메뉴 항목(Menu1)이 선택되었을 경우 메시지 박스를 열어 메뉴 항목이 선택되었음을 알려주고 ID_FILE_EXIT메뉴 항목(Exit)이 선택되었을 경우 프로그램을 종료한다.

    ⇒ WM_COMMAND 메시지는 메뉴 항목을 선택할 뿐만 아니라 액셀러레이터를 누를 때도 발생하며 도한 버튼, 에디트 박스 등의 컨트롤이 부모 윈도우로 통지 메시지를 보낼 때도 발생한다. 이 메시지의 추가 정보는 다음과 같은 구조를 가진다.

    설명

    lParam

    LOWORD(wParam)

    HIWORD(wParam)

     

    통지 메시지를 발생시킨 컨트롤의 윈도우 핸들

    메뉴나 액셀러레이터, 컨트롤의 ID

    컨트롤이 보내는 통지 메시지, 메뉴가 선택된 경우는 0이 되며 액셀러레이터가 선택된 경우는 1이 된다.

    ⇒ WM_COMMAND 메시지가 워낙 여려가지 명령을 받아들이는 메시지이다 보니 추가 정보도 복잡하다. 여기서 우리가 사용한 값은 메뉴 ID가 전달되는 LOWORD(wParam)뿐이다. 기억할 것은 메뉴 선택시 WM_COMMAND 메시지가 전달되며 LOWORD(wParam)을 읽어 어떤 메뉴 항목이 선택되었는지를 판단할 수 있다는 것.


    - 메뉴 편집기

    ⇒ 메뉴 편집기는 사용자가 편집한 메뉴를 텍스트 형태로 리소스 파일에 기록한다.


    - 새 메뉴의 작성

    ⇒ 새로운 메뉴를 작성할 때는 리소스 뷰의 팝업 메뉴에서 리소스 추가(또는 Insert) 항목을 선택한다.

     

    ⇒ 위와 같이 자동으로 IDR_MENU2가 생성되었다.(위에 IDR_NENU1 이 이미 만들어져 있으므로 IDR_MENU2가 되었다.)

    - 메뉴 항목의 추가

    ⇒ 빈칸에 새로운 메뉴를 추가하려면 곧바로 캡션을 입력하거나 빈칸을 더블클릭하여 속성 편집기를 열고 캡션과 기타 속성들을 입력한다. 좌상단의 빈칸을 더블 클릭하여 File이라는 캡션을 주면 다음과 같이 된다.

     

    ⇒ 오른쪽과 아래쪽에 각각 빈칸이 나타나는데 이 빈칸들에 또 메뉴 항목을 만들 수 있으며 아래와 같은 식으로 메뉴 생성이 가능하다.

     

    - 메뉴 항목의 수정

    ⇒ 기존에 만들어져 있는 메뉴의 이름이나 속성을 변경하려면 속성 편집기에서 원하는 속성을 다시 입력하면 된다.


    - 메뉴 항목의 삽입

    ⇒ 기존에 작성되어 있는 메뉴 리스트에서 삽입할 위치에 커서를 위치한 후 키보드에서 Insert 키를 누르면 커서 위치에 빈카닝 새로 생성되며 이 빈칸에 원하는 항목을 입력한다.


    - 메뉴 항목의 삭제

    ⇒ 삭제하고자 하는 메뉴 항목에 커서를 위치한 후 Delete 키를 누른다. 단, 메뉴 리스트의 메뉴 항목은 그냥 삭제되지만 하위 메뉴를 거느린 팝업 메뉴를 삭제할 때는 바로 삭제하지 않고 경고 메시지 창이 출력된다.


    - 메뉴의 이동

    ⇒ 이동하고자 하는 메뉴를 마우스로 드래그하여 원하는 위치로 이동할 수 있다. 이 기능을 이용해 메뉴 바에 있는 메뉴를 하위 메뉴로 만들 수 있다.

    ⇒ 예로 Edit 메뉴를 File 메뉴의 Save와 Print 사이에 끼워 넣으면 다음과 같이 Edit 메뉴 전체가 File 메뉴의 하위 메뉴가 된다.

     

    - 복사 및 붙여넣기

    ⇒ 메뉴의 복사, 붙여넣기는 워드 프로세서에서 클립보드를 사용하여 문서의 일부분을 복사하는 것과 개념적으로 동일하다.


    기타 리소스

    - 아이콘, 커서

    ⇒ 아이콘이나 커서도 리소스의 일종이며 각각의 편집기를 사용하여 제작할 수 있다.

    ⇒ 메뉴의 Insert → resource 대화상자에서 ICON을 선택하여 새로운 아이콘을 만든다.

     

    ⇒ 다음으로 Insert → resource 대화상자에서 CURSOR을 선택하여 새로운 커서를 만든다.

     

    ⇒ 커서를 만든 후 커서 편집기를 닫고 이번에는 만들어 놓은 커서와 아이콘을 사용하도록 코드를 수정한다.

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


    ⇒ 아래와 같이 아이콘과 커서가 생성된 것을 확인 할 수 있다.

     


    - 액셀러레이터

    ⇒ 액셀러레이터(Accelerator)는 쉽게 말해 단축키이다. Ctrl+C는 Copy, Ctrl+V는 Paste 등이 있다.

    ⇒ 단, 윈도우wm에서 단축키와 Accelerator를 구별하는 이유는 윈도우즈에서 단축키(ShortCut)가 다른 의미로 사용되고 있기 때문이다. 메뉴 이름에 &를 넣어 Alt키와 함께 사용하는 키를 단축키라고 하며 액셀러레이터와는 의미가 조금 다르다.

    ⇒ 단축키는 반드시 Alt키와 함께 사용해야 하며 메뉴에 있는 항목을 키보드로 선택하는 빠른 방법이지만 액셀러레이터는 메뉴와 상관없이 언제든지 사용이 가능하다.


    - 실습

    ⇒ 리소스 뷰에서 IDR_MENU1을 더블클릭하면 메뉴 편집기가 열린다.

    ⇒ File 팝업 메뉴의 속성 윈도우에서 Caption을 &file로 바꾼다.

     

    ⇒ File 메뉴 아래 세 개의 메뉴 항목에서 각 항목의 캡션을 다음과 같이 수정한다.

    수정 전

    수정 후

    Menu1

    Menu&1\tCtrl+A

    Menu2

    Menu&1\tCtrl+B

    Exit

    &Exit\tCtrl+C

    ⇒ 아래는 수정중인 화면이다.

     

    ⇒ 메뉴를 만들 때와 같은 방법으로 리소스 추가 대화상자에서 Accelerator를 선택한다. 다음과 같은 액셀러레이터 편집기가 열린다. 각 란에 다음과 같이 입력한다.

     

     

    ⇒ 다음은 리소스를 코드에서 사용하도록 소스를 수정한다. WinMain의 선두에 hAccel 변수를 선언하고 메시지 루프만 다음과 같이 수정한다.

    HACCEL hAccel;



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

     

    ⇒ Accel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));

     → 이 함수는 리소스로부터 액셀러레이터 테이블을 읽어들인다. 두 번째 인수 lpTableName은 액셀러레이터 테이블의 이름 문자열 포인터이되 우리가 작성한 액셀러레이터 테이블 IDR_ACCELERATOR1은 정수값이므로 MAKEINTRESOURCE 매크로를 사용해야 한다.

     → 이 함수는 리소스에서 액셀러레이터 테이블을 읽은 후 그 핸들을 리턴한다. 이 핸들값을 hAccel이라는 변수에 대입해 두면 다음부터 hAccel을 통해 액셀러레이터 테이블을 읽을 수 있다.

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

     → 이 함수는 키보드 메시지를 WM_COMMAND 메시지로 변경하여 액셀러레이터가 동작할 수 있도록 한다. 액셀러레이터 Ctrl+A가 입력되었다고 해 보자. Ctrl+A는 액셀러레이터이기 이전에 키보드로부터의 입력이므로 먼저 WM_KEYDOWN 메시지가 발생할 것이고 그대로 내버려 주면 WndProc의 WM_KEYDOWN 메시지 처리 루틴에서 먼저 이 키값을 처리해 버릴 것이다.

     → TranslateAccelerator 함수는 lpMsg의 키보드 입력값을 읽어 이 키값이 hAccTable에 있는지 먼저 살펴보고 있을 경우 그 키에 해당하는 WM_COMMAND 메시지를 hWnd 윈도우로 전달하고 TRUE를 리턴해 버린다.

     → 그래서 액셀러레이터가 입력되었을 경우 TranslateMessage, DispatchMessage 함수가 실행되지 못하게 막아 버리며 다음 번의 WM_COMMAND 메시지가 처리되도록 한다.

     → WM_KEYDOWN 메시지는 중간에 다른 메시지로 변형되거나(WM_COMMAND) 추가로 메시지를 발생(WM_CHAR)시키는 경우가 빈번하다.



    Posted by 동화다아아
    , |

    최근에 달린 댓글

    최근에 받은 트랙백

    글 보관함