hyeonk lab

블로그 이미지

hyeonk

hello world! hyeonk lab.

svn 능력자를 위한 git 개념 가이드

reference 2015. 8. 20. 14:46


svn 능력자를 위한 git 개념 가이드


출처: http://www.slideshare.net/einsub/svn-git-17386752

저작자표시 (새창열림)

'reference' 카테고리의 다른 글

인생과 일 모두에서 성공하기 위해 반드시 일아야 할 것들  (0) 2014.08.17
Posted by hyeonk

[강좌/메시지] WM_NOTIFY 메시지에 대해서...(ON_NOTIFY) - 2편

mfc & winAPI 2015. 8. 19. 13:57

출처 : http://www.tipssoft.com/bulletin/tb.php/FAQ/65


4. MFC 프로그램에서 WM_NOTIFY 메시지 사용하기
 
    일반적인 방식으로 생각한다면 WM_NOTIFY 메시지에 대한 핸들러는 OnNotify 일것입니다. 
    CWnd 클래스를 살펴보시면 아시겠지만 OnNotify라는 멤버함수가 있습니다. 하지만, 우리는
    이 함수를 등록해서 사용하지는 않습니다. 왜냐하면 이 함수로는 모든 통보 메시지가
    전달되기 때문에 OnNotify 함수에서 코드를 작성하면 C++적인 의미가 다소 줄어들수 있으므로
    이 함수를 등록해서 사용하지 않고 개별적인 처리루틴을 사용하도록 권장하고 있습니다.
    ( OnNotify 함수를 등록하고 if문 또는 switch문을 사용해서 각 메시지를 분류하여 사용하기도
      하는데, 이런 형식은 C 방식에서 많이 사용하는 방법입니다. )
 
    MFC에서는 기본적으로 메시지별로 핸들러 함수를 사용하도록 되어있습니다. 따라서 각 
    통보 메시지별로 핸들러를 등록할수 있는데, 메시지 맵에 아래와 같이 등록하시면 됩니다.
 
    ON_NOTIFY( notify_code, control_id, HandlerFunction )
 
    위와 같이 정의하면 control_id를 가진 컨트롤에서 발생된 통보 메시지 중에 세부 코드가
    notify_code (NMHDR 구조체의 code 항목에 저장된 값) 인 경우, HandlerFunction 함수를
    수행하겠다는 뜻이 됩니다.
 
    예를 들어, 리스트 뷰 컨트롤이 있고 키를 눌렀을때 OnMyListViewKeyDown 이라는 함수를
    호출하고 싶다면 아래와 같이 사용하시면 됩니다.
    ( 해당 리스트 뷰 컨트롤의 아이디 :  IDC_MY_LIST_VIEW 로 가정 )
 
    ON_NOTIFY( LVN_KEYDOWN, IDC_MY_LIST_VIEW, OnMyListViewKeyDown )
 
    사실, 리스트 뷰, 트리 뷰 등과 같이 잘 알려진 컨트롤의 통보 메시지는 클래스위저드를
    이용해서 등록가능하기 때문에 위 사항을 직접 입력하실 필요는 없습니다. ^^;; 하지만,
    자신이 새롭게 만든 컨트롤인 경우에는 클래스위저드의 지원을 받을 수 없기 때문에
    직접 메시지맵에 입력하셔야 합니다.
 
    ON_NOTIFY 매크로의 3번째에 입력한 핸들러는 어떻게 구성되는지에 대해서 알아보겠습니다.
    먼저 함수의 원형은 아래와 같습니다.
 
    afx_msg void HandlerFunction( NMHDR * pNotifyStruct, LRESULT * result );
 
    일반적으로 클래스위저드를 사용해서 등록하게 되면 위 코드가 해당 클래스의 헤더파일 내에
    자동으로 추가됩니다. 그리고 아래와 같이 해당 클래스의 소스 파일에는 핸들러 코드가 추가됩니다.
 
    void 해당클래스::HandlerFunction( NMHDR * pNotifyStruct, LRESULT * result )
    {
        // TODO: Add your control notification handler
        //       code here
   
        *pResult = 0;
    }
 
    위에서 예를 든것처럼 리스트 뷰 컨트롤이 있고 키를 눌렀을때 OnMyListViewKeyDown 이라는 함수를
    호출하고 싶다고 선택했다면 아래와 같이 핸들러 루틴이 추가될 것입니다.
    ( 클래스위저드가 자동으로 추가해 줍니다.  )
 
    void 해당클래스::OnMyListViewKeyDown( NMHDR * pNotifyStruct, LRESULT * result )
    {
        LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNotifyStruct;
        // TODO: Add your control notification handler
        //       code here
   
        *pResult = 0;
    }
 
    위 코드에서 보시면 알수 있듯이 리스트 뷰 컨트롤의 LVN_KEYDOWN 통보 메시지는 NMHDR 구조체를
    확장해서 LV_KEYDOWN 이라는 구조체를 사용하고 있기 때문에 클래스위저드가 자동으로 형변환까지
    코드를 생성시켜 줍니다. 만약, 이 강좌의 1편에서처럼 자신이 만든 클래스에 통보 메시지를 보내는
    코드를 보냈고 해당 통보 메시지가 MyNotifyData 라는 구조체를 사용했다면 형변환을 아래처럼 직접
    하시면 됩니다.
 
    MyNotifyData *p_my_data = (MyNotifyData *)pNotifyStruct;
 
    당연한 이야기겠지만 통보 메시지 데이터 자체가 NMHDR을 이용한다면 형변환 없이 pNotifyStruct 변수를
    바로 사용하시면 됩니다.
 

5. 동일한 통보 메시지를 일괄 처리하기
 
    자신이 하나의 대화상자에 리스트 뷰 컨트롤을 3개를 만들고 각 아이디를 IDC_MY_LIST_VIEW1, 
    IDC_MY_LIST_VIEW2, IDC_MY_LIST_VIEW3로 부여했다고 합시다. ( 각 컨트롤의 번호는 
    resource.h 파일에서 확인했을 때, 순차적으로 배열되어있다고 가정하겠습니다. ) 대화상자에서
    각 컨트롤의 LVN_KEYDOWN 통보 메시지를 일괄적으로 처리해야 하는 경우, 핸들러를 3개
    등록하지 않고 1개만 등록해서 처리하는 방법에 대해서 알아보도록 하겠습니다.
 
    먼저 메시지 맵에 아래와 같은 메크로를 등록합니다.
 
    ON_NOTIFY_RANGE( notify_code, start_control_id, end_control_id, HandlerFunction )
 
    위 사항을 적용해서 등록한다면 아래와 같습니다.
 
    ON_NOTIFY_RANGE( LVN_KEYDOWN, IDC_MY_LIST_VIEW1, 
                                                           MY_LIST_VIEW3,  OnMyListViewKeyDown)
 
    Range 관련 메크로는 클래스위저등의 지원을 받지 못하기 때문에 직접 입력하셔야 합니다.
    해당 클래스의 헤더파일에 추가되는 OnMyListViewKeyDown 함수의 형식은 ON_NOTIFY 때와
    약간의 차이가 생기는 아래와 같습니다.
 
    afx_msg void HandlerFunction( UINT control_id, NMHDR * pNotifyStruct, LRESULT * result );
 

    위와 같이 control_id라는 인자가 하나 추가되는데, 그 이유는 3개의 컨트롤에서 발생된 
    통보 메시지가 일괄적으로  이 함수를 사용하기 때문에 어떤 컨트롤에서 이 메시지가
    전달되었는지 확인할수 있도록 통보 메시지를 발생시킨 컨트롤의 아이디가 추가된 것입니다.


저작자표시 (새창열림)

'mfc & winAPI' 카테고리의 다른 글

마우스 이벤트 중복 클릭 방지 함수  (0) 2017.05.29
[강좌/메시지] WM_NOTIFY 메시지에 대해서...(ON_NOTIFY) - 1편  (0) 2015.08.19
#import msado15.dll이 소스에서 OS등에 따라 컴파일이 되지 않을 때  (0) 2014.04.11
BOOL PreTranslateMessage(MSG* pMsg)  (0) 2014.03.21
분할 윈도우 중 하나에 접근하는 방법  (0) 2014.02.10
Posted by hyeonk

[강좌/메시지] WM_NOTIFY 메시지에 대해서...(ON_NOTIFY) - 1편

mfc & winAPI 2015. 8. 19. 13:56

출처: http://www.tipssoft.com/bulletin/tb.php/FAQ/63


WM_NOTIFY 메시지는 우리가 프로그램하면서 많이 사용하는 메시지 중에 하나입니다.:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

하지만 그 용법이나 의도를 제대로 이해하지 못하고 사용하는 사람들이 많아서

MSDN의 Technical note 61번의 내용을 근거로 간단한 소개글을 만들었습니다.

 

 

1. 통보(Notify) 메시지의 필요성

 

    WM_NOTIFY 메시지는 일반적으로 자식윈도우(예, 컨트롤-버튼,에디트박스, ...)가 자신에게

    일어난 여러가지 상황을 부모윈도우(예, 대화상자)에게 전달할때 사용합니다.

 

   예를 들어, 대화상자에 버튼을 하나 만들었다고 하면 해당 버튼을 눌렀을때 WM_COMMAND 라는

   메시지가 발생합니다. 이 메시지는 단순한 통보(notify)를 목적으로 구성되었기 때문에

   WPARAM에 BN_CLICKED(HI WORD)와 해당 컨트롤의 ID(LOW WORD)가 저장되고

   LPARAM에 해당 버튼 컨트롤의 핸들이 저장된 상태로 전달됩니다.

 

   위 구성에서 본것처럼 이미 WPARAM, LPARAM을 모두 사용해버렸기 때문에 버튼 컨트롤 입장에서는

   추가적인 정보(마우스 클릭 좌표와 같은 정보)를 전달하고 싶어도 전달할 방법이 없습니다.

 

   컨트롤의 종류가 다양해지고 요구사항이 복잡해짐에 따라서 윈도우즈 시스템은 추가적인 정보를

   포함할수 있는 메시지가 필요하게 되었고 아래와 같은 메시지가 추가되었습니다.

 

   WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM,

   WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEM, ...

 

 

2. Win32 시스템에서의 통보 메시지에 대하여...

 

    Win32 시스템은 하위 시스템의 호환성을 유지하기 위해 기존 Windows 3.x에서 사용하던 메시지들을

    대부분 수용하고 있습니다. 즉, 위에서 언급한 메시지들은 모두 사용할수 있습니다.

    그리고 프로그램이 복잡해지고 컨트롤이 다양해짐에 따라, 이미 많은 메시지가 있음에도 불구하고,

    메시지 추가에 대한 요구 사항이 늘어나게 되었고 윈도우즈 시스템은 필요할때마다 WM_ 메시지를

    추가해서 문제를 해결하는데 한계가 있다는것 알고 통보 메시지에 대한 새로운 표준을 정했고

    그것이 WM_NOTIFY 메시지로 구체화 되었습니다.  WM_NOTIFY 메시지의 형식은 아래와 같습니다.

 

 

    WM_NOTIFY 메시지의 LPARAM에 사용된 구조체의 형식은 아래와 같습니다.

 

    typedef struct tagNMHDR {

        HWND hwndFrom;

        UINT idFrom;

        UINT code;

    } NMHDR;

 

    NMHDR 구조체를 보시면 아시겠지만 항목이 너무 간단해서 다양한 정보를 수용할만한 구조가

    아닙니다.

    그렇다면 어떻게 컨트롤의 다양한 정보를 이 구조체를 이용해서 전달할수 있을까요?

    그건 LPARAM에 전달되는 정보의 형식을 살펴보면 의문이 풀립니다.

    LPARAM에 저장된 정보는 NMHDR 구조체의 주소입니다. 즉, 구조체의 크기가 한정되지 않다는

    뜻입니다. WM_NOTIFY 메시지는 전달되는 정보의 시작형식을 NMHDR 구조체 형식으로 정한것이지

    꼭 저 구조체를 사용하라는 뜻이 아닙니다.

 

    예를 들어, 자신이 컨트롤을 하나 만들었고 해당 컨트롤이 x, y 좌표정보를 부모에게 통보해야 한다면

    아래와 같이 구조체를 정의하고 사용하시면 됩니다.

 

    typedef struct tagMyNotifyData {

        HWND hwndFrom;    // 변경불가

        UINT idFrom;           // 변경불가

        UINT code;              // 변경불가

        // 자신이 추가하고 싶은 정보를 추가하면 됩니다.

        int x_pos;

        int y_pos;

    } MyNotifyData;

 

   위 구조체를 아래와 같이 선언해도 마찬가지 입니다.

 

    typedef struct tagMyNotifyData {

        NMHDR hdr;   // 변경불가

        // 자신이 추가하고 싶은 정보를 추가하면 됩니다.

        int x_pos;

        int y_pos;

    } MyNotifyData;

 

    WM_NOTIFY 관련 처리기는 LPARAM으로 전달되는 메시지의 시작형식만 NMHDR 구조를 만족하면

    아무런 문제 없이 동작하도록 구성되어있기 때문에, 자신이 정의하는 구조체의 시작 부분만 정확하게

    NMHDR 구조체 형식으로 구성해주시면 됩니다.

 

    대부분의 통보 메시지를 사용하는 컨트롤들은 자신의 정보를 전달하기 위해서 NMHDR 구조체보다

    더 복잡한 형태의 구조체를 사용할 것입니다.  ( 툴팁 컨트롤이 통보하는 메시지 중에 TTN_SHOW,

    TTN_POP 같은 메시지는 특별한 추가 정보가 없어서 NMHDR 구조를 그대로 사용하고 있습니다. )

 

    WM_NOTIFY 메시지는 통보 메시지의 대표 메시지이고, 자신이 전달하고 싶은 통보 메시지 코드는

    NMHDR 구조체의 code 항목에 저장해서 전달하면 된다. 따라서 받는 쪽에서는 해당 통보 메시지가

    어떤 구조체인지는 모르지만 구조체의 앞부분이 NMHDR 구조체와 형식이 같기 때문에 일단 해당

    주소를 NMHDR 구조체로 형변환(casting)을 한 후에 code 항목을 체크하여 어떤 통보 메시지인지를

    구분하고 다시 정확한 구조체로 형변환(casting)을 해서 사용하게 됩니다.

 

    예를들어, 자신이 위에서 이야기한 MyNotifyData 구조체를 사용했다고 가정하고 code에 MN_DATA

    라는 메시지 코드를 넣어서 부모 윈도우로 WM_NOTIFY 형식으로 전달했다면 받는 쪽에서는 아래와

    같이 처리할 것입니다.

 

    // 통보 메시지는 일괄적으로 NM_NOTIFY 로 전달되기 때문에 어떤 통보메시지 인지를 확인해야

    // 한다.

    // 따라서 LPARAM 에 전달된 주소를 NMHDR로 형변환해서 code값을 확인해야 한다.

    NMHDR *p_hdr = (NMHDR *)lParam;

    if( p_hdr->code == MN_DATA ){

        // 전달된 통보 메시지가 MN_DATA인 경우       

        MyNotifyData *p_my_data =  (MyNotifyData *)lParam;

        // p_my_data 를 사용...

    } else {

        // 다른 통보 메시지인지를 체크

    }

 

 

3. WM_NOTIFY를 사용하는 컨트롤에서 공통적으로 사용되는 메시지들에 대하여..

통보 메시지 코드

통보 내용

  NM_CLICK  사용자가  해당 컨트롤에 마우스 왼쪽 버튼을 클릭한 경우 발생
  NM_DBLCLK  사용자가  해당 컨트롤에 마우스 왼쪽 버튼을 더블 클릭한 경우 발생
  NM_RCLICK  사용자가  해당 컨트롤에 마우스 오른쪽 버튼을 클릭한 경우 발생
  NM_RDBLCLK  사용자가  해당 컨트롤에 마우스 오른쪽 버튼을 더블 클릭한 경우 발생
  NM_RETURN
  해당 컨트롤이 포커스를 가지고 있는 상태에서 ENTER 키를 누른
  경우 발생
  NM_SETFOCUS  해당 컨트롤이 입력 포커스를 획득한 경우 발생
  NM_KILLFOCUS  해당 컨트롤이 입력 포커스를 잃어버린 경우 발생
  NM_OUTOFMEMORY    해당 컨트롤이 메모리 부족으로 명령 수행에 실패한 경우 발생

 

 

[ 2 편에서 계속하겠습니다. ]

저작자표시 (새창열림)

'mfc & winAPI' 카테고리의 다른 글

마우스 이벤트 중복 클릭 방지 함수  (0) 2017.05.29
[강좌/메시지] WM_NOTIFY 메시지에 대해서...(ON_NOTIFY) - 2편  (0) 2015.08.19
#import msado15.dll이 소스에서 OS등에 따라 컴파일이 되지 않을 때  (0) 2014.04.11
BOOL PreTranslateMessage(MSG* pMsg)  (0) 2014.03.21
분할 윈도우 중 하나에 접근하는 방법  (0) 2014.02.10
Posted by hyeonk
이전페이지 다음페이지
블로그 이미지

hello world! hyeonk lab.

by hyeonk

공지사항

    최근...

  • 포스트
  • 댓글
  • 트랙백
  • 더 보기

태그

글 보관함

«   2025/12   »
일 월 화 수 목 금 토
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

링크

카테고리

전체 (44)
ios (1)
mfc & winAPI (17)
c & c++ (4)
java (1)
eclipse (1)
visual_studio (2)
javascript (3)
asp (1)
oracle (3)
개발이야기 (5)
윈도우 일반 (2)
etc (2)
reference (2)
personal_reference (0)

카운터

Total
Today
Yesterday
방명록 : 관리자 : 글쓰기
hyeonk's Blog is powered by daumkakao
Skin info material T Mark3 by 뭐하라
favicon

hyeonk lab

hello world! hyeonk lab.

  • 태그
  • 링크 추가
  • 방명록

관리자 메뉴

  • 관리자 모드
  • 글쓰기
  • 전체 (44)
    • ios (1)
    • mfc & winAPI (17)
    • c & c++ (4)
    • java (1)
    • eclipse (1)
    • visual_studio (2)
    • javascript (3)
    • asp (1)
    • oracle (3)
    • 개발이야기 (5)
    • 윈도우 일반 (2)
    • etc (2)
    • reference (2)
    • personal_reference (0)

카테고리

PC화면 보기 티스토리 Daum

티스토리툴바