CHAP. 12
컨트롤에서의 메시지 처리
1
2
컨트롤 윈도우에서 발생하는
일반 윈도우 메시지 처리
컨트롤 윈도우의 일반 사건
특정 사건은 11장에서 다룬
Notification 코드
메시지 처리 유형 Ⅳ
유형번호는 중요치 않다
유형 Ⅳ도 컨트롤 윈도우 때문에 생겼다
3
컨트롤 윈도우의 일반사건 처리
어디에서 사건이 발생하더라도 WM_COMMAND 발생하니까
이 메시지의 부가정보에 뭔가 있을 듯 하지만,
int wNofifyCode = HIWORD(wParam)
int wID = LOWORD(wParam);
HWND hWndCtrl = (HWND)lParam;
WM_COMMAND 부가정보
Notification Code는 미리 정의되어 있는 특정 사건
WM_COMMAND에는 답이 없다
WM_COMMAND를 통해
컨트롤의 WM_XXXX를 끄집어 낼 길이 없다
예들 들어, WM_MOUSEMOVE 같은 것
4
버튼 위에서 마우스 움직일 때 마우스 좌표 출력
문제는 버튼 윈도우에 대한
프로시저 소스코드가 없다는 것
버튼 윈도우, 마우스 움직임 처리
5
일단 버튼 만들고, 마우스 움직일 때 좌표 출력
마우스 움직임에 대한 메시지
WM_MOUSEMOVE
마우스 좌표 획득
int x = LOWORD(lParam)
int y = HIWORD(lParam)
화면 출력
HDC hdc;
hdc = GetDC(hWnd);
TextOut(hdc, x, y, "hello", 5);
ReleaseDC(hWnd, hdc);
6
LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, WPARAM wParam, LPARAM lParam)
{
static HWND hBtn;
switch(mesg) {
case WM_CREATE:
hBtn = CreateWindow("BUTTON", "button",
WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,
0, 0,100,100,hWnd,(HMENU)888,_hInstance, NULL);
break;
case WM_MOUSEMOVE:
HDC hdc;
char szPos[32];
sprintf(szPos, "%03d %03d", LOWORD(lParam),HIWORD(lParam));
hdc = GetDC(hWnd);
TextOut(hdc, 102, 0, szPos, strlen(szPos));
ReleaseDC(hWnd, hdc);
break;
case WM_DESTROY:
PostQuitMessage(0); return FALSE;
}
return DefWindowProc(hWnd, mesg, wParam, lParam);
}
부모 윈도우의 윈도우 프로시저
부모 윈도우에서 발생하는
마우스 움직임 처리
7
실행시켜 보면,
버튼 위에서 움직일 때는 좌표 변화가 없다
부모 윈도우 프로시저에서만 WM_MOUSEMOVE
처리했으니까 이는 당연지사. 그럼 해결책은 ?
버튼 윈도우 프로시저에서 이벤트 처리
8
버튼 윈도우에서의 WM_MOUSEMOVE 이벤트 처리
버튼 윈도우도 어디엔가
윈도우 프로시저 존재
한다
9
버튼 윈도우에서의 WM_MOUSEMOVE 이벤트 처리
처리하는 것이 있기
는 하다. 그러나 내가 원
하는 것을 처리하고 있지는
않다
10
버튼 윈도우에서의 WM_MOUSEMOVE 이벤트 처리
내가 원하는 처리를 하는
프로시저를 구현하고
새로운
버튼윈도우
프로시저
WM_MOUSEMOVE 이벤트 처리
를 구현한 프로시저 (함수)
함수니까 그냥 구현하면 되지. 프로토타입 다 알고 있는데
11
버튼 윈도우에서의 WM_MOUSEMOVE 이벤트 처리
내가 원하는 처리를 하는
프로시저를 구현하고
기존 것을 대체하자
새로운
버튼윈도우
프로시저
12
윈도우 프로시저 대체에 필요한 작업
① 새로운 프로시저 구현
② 기존 윈도우의 프로시저 대체
그냥 하고
해주는 함수가 있겠지
그런데
LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, WPARAM wParam, LPARAM lParam)
{
switch(mesg)
{
case WM_MOUSEMOVE:
break;
}
return DefWindowProc(hWnd, mesg, wParam, lParam);
}
SetWindowLong()
요건 뒤에서 더 자세히
13
기존 프로시저가
처리하는 것이 있다
버튼의 경우 마우스 눌림, 뗌에 대한 화면 처리를 하고 있다
이것을 새로 구현할 수는 없으니까
들어간 느낌, 튀어나온 느낌
①을 구현할 때 끝에 대신 기존 프로시저 호출
return DefWindowProc(hWnd, mesg, wParam, lParam);
LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, WPARAM wParam, LPARAM lParam)
{
switch(mesg)
{
case WM_MOUSEMOVE:
break;
}
return
}
CallWindowProc( …);
그럼 기존 윈도우 프로시저 주소 있어야겠다
이거
14
기존 프로시저의
주소 알아오기
GetWindowLong()
버튼 윈도우 만든 후에 윈도우 핸들 이용해서 주소 획득
15
윈도우 프로시저 대체에 필요한 작업 정리하면
① 새로운 프로시저 구현
② 기존 윈도우의 프로시저 대체
- 기존 프로시저 주소 확보
- 새로운 프로시저로 대체
CallWindowProc()
GetWindowLong()
SetWindowLong()
끝 부분에 이 함수
호출 추가
함수 주소는 여기서 획득
자~함수 사용법은 코드에서 직접
16
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK BtnProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE _hInstance;
WNDPROC _fpOldBtnProc;
LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, WPARAM wParam, LPARAM lParam)
{
static HWND hBtn;
switch(mesg)
{
case WM_CREATE:
hBtn = CreateWindow(…);
_fpOldBtnProc =
(WNDPROC)GetWindowLong(hBtn, GWL_WNDPROC);
SetWindowLong(hBtn1, GWL_WNDPROC, (LONG)BtnProc);
break;
…
}
기존 버튼 프로시저 주소 저장
윈도우 핸들이 가리키는 윈도우에서
Get Window Long
윈도우 프로시저 정보
가져와라
프로시저 함수의 타입은 WNDPROC
지정한 윈도우 프로시저로
윈도우 프로시저를설정해라
17
LRESULT CALLBACK BtnProc(HWND hWnd, UINT mesg, WPARAM wParam,LPARAM lParam)
{
switch(mesg)
{
case WM_MOUSEMOVE:
HDC hdc;
HWND hParent;
hParent = GetParent(hWnd);
char szPos[32];
sprintf(szPos, "%03d %03d", LOWORD(lParam),HIWORD(lParam));
hdc = GetDC(hParent);
TextOut(hdc, 102, 32, szPos, strlen(szPos));
ReleaseDC(hParent, hdc);
break;
}
return CallWindowProc(_fpOldBtnProc,hWnd,mesg,wParam,lParam);
}
부모 윈도우 핸들 획득
호출해라 지정 프로시저 함수를
이러한 파라미터를 가지고
18
LONG GetWindowLong(HWND hWnd, int nIndex);
LRESULT CallWindowProc(WNDPROC lpPrevWndFunc,
HWND hWnd, UINT Msg, WPARAM wParam,
LPARAM lParam);
LONG SetWindowLong(HWND hWnd, int nIndex,
LONG dwNewLong);
관련 함수 프로토타입
GWL_EXSTYLE 확장 윈도우 스타일
GWL_STYLE 윈도우 스타일
GWL_WNDPROC 윈도우 프로시저 주소
GWL_HINSTANCE 인스턴스 핸들
GWL_HWNDPARENT 부모 윈도우 핸들
GWL_ID 윈도우 식별자
CreateWindowEx()로 생성된 윈도우
nIndex

12 컨트롤에서의 메세지 처리

  • 1.
  • 2.
    2 컨트롤 윈도우에서 발생하는 일반윈도우 메시지 처리 컨트롤 윈도우의 일반 사건 특정 사건은 11장에서 다룬 Notification 코드 메시지 처리 유형 Ⅳ 유형번호는 중요치 않다 유형 Ⅳ도 컨트롤 윈도우 때문에 생겼다
  • 3.
    3 컨트롤 윈도우의 일반사건처리 어디에서 사건이 발생하더라도 WM_COMMAND 발생하니까 이 메시지의 부가정보에 뭔가 있을 듯 하지만, int wNofifyCode = HIWORD(wParam) int wID = LOWORD(wParam); HWND hWndCtrl = (HWND)lParam; WM_COMMAND 부가정보 Notification Code는 미리 정의되어 있는 특정 사건 WM_COMMAND에는 답이 없다 WM_COMMAND를 통해 컨트롤의 WM_XXXX를 끄집어 낼 길이 없다 예들 들어, WM_MOUSEMOVE 같은 것
  • 4.
    4 버튼 위에서 마우스움직일 때 마우스 좌표 출력 문제는 버튼 윈도우에 대한 프로시저 소스코드가 없다는 것 버튼 윈도우, 마우스 움직임 처리
  • 5.
    5 일단 버튼 만들고,마우스 움직일 때 좌표 출력 마우스 움직임에 대한 메시지 WM_MOUSEMOVE 마우스 좌표 획득 int x = LOWORD(lParam) int y = HIWORD(lParam) 화면 출력 HDC hdc; hdc = GetDC(hWnd); TextOut(hdc, x, y, "hello", 5); ReleaseDC(hWnd, hdc);
  • 6.
    6 LRESULT CALLBACK WndProc(HWNDhWnd, UINT mesg, WPARAM wParam, LPARAM lParam) { static HWND hBtn; switch(mesg) { case WM_CREATE: hBtn = CreateWindow("BUTTON", "button", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON, 0, 0,100,100,hWnd,(HMENU)888,_hInstance, NULL); break; case WM_MOUSEMOVE: HDC hdc; char szPos[32]; sprintf(szPos, "%03d %03d", LOWORD(lParam),HIWORD(lParam)); hdc = GetDC(hWnd); TextOut(hdc, 102, 0, szPos, strlen(szPos)); ReleaseDC(hWnd, hdc); break; case WM_DESTROY: PostQuitMessage(0); return FALSE; } return DefWindowProc(hWnd, mesg, wParam, lParam); } 부모 윈도우의 윈도우 프로시저 부모 윈도우에서 발생하는 마우스 움직임 처리
  • 7.
    7 실행시켜 보면, 버튼 위에서움직일 때는 좌표 변화가 없다 부모 윈도우 프로시저에서만 WM_MOUSEMOVE 처리했으니까 이는 당연지사. 그럼 해결책은 ? 버튼 윈도우 프로시저에서 이벤트 처리
  • 8.
    8 버튼 윈도우에서의 WM_MOUSEMOVE이벤트 처리 버튼 윈도우도 어디엔가 윈도우 프로시저 존재 한다
  • 9.
    9 버튼 윈도우에서의 WM_MOUSEMOVE이벤트 처리 처리하는 것이 있기 는 하다. 그러나 내가 원 하는 것을 처리하고 있지는 않다
  • 10.
    10 버튼 윈도우에서의 WM_MOUSEMOVE이벤트 처리 내가 원하는 처리를 하는 프로시저를 구현하고 새로운 버튼윈도우 프로시저 WM_MOUSEMOVE 이벤트 처리 를 구현한 프로시저 (함수) 함수니까 그냥 구현하면 되지. 프로토타입 다 알고 있는데
  • 11.
    11 버튼 윈도우에서의 WM_MOUSEMOVE이벤트 처리 내가 원하는 처리를 하는 프로시저를 구현하고 기존 것을 대체하자 새로운 버튼윈도우 프로시저
  • 12.
    12 윈도우 프로시저 대체에필요한 작업 ① 새로운 프로시저 구현 ② 기존 윈도우의 프로시저 대체 그냥 하고 해주는 함수가 있겠지 그런데 LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, WPARAM wParam, LPARAM lParam) { switch(mesg) { case WM_MOUSEMOVE: break; } return DefWindowProc(hWnd, mesg, wParam, lParam); } SetWindowLong() 요건 뒤에서 더 자세히
  • 13.
    13 기존 프로시저가 처리하는 것이있다 버튼의 경우 마우스 눌림, 뗌에 대한 화면 처리를 하고 있다 이것을 새로 구현할 수는 없으니까 들어간 느낌, 튀어나온 느낌 ①을 구현할 때 끝에 대신 기존 프로시저 호출 return DefWindowProc(hWnd, mesg, wParam, lParam); LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, WPARAM wParam, LPARAM lParam) { switch(mesg) { case WM_MOUSEMOVE: break; } return } CallWindowProc( …); 그럼 기존 윈도우 프로시저 주소 있어야겠다 이거
  • 14.
    14 기존 프로시저의 주소 알아오기 GetWindowLong() 버튼윈도우 만든 후에 윈도우 핸들 이용해서 주소 획득
  • 15.
    15 윈도우 프로시저 대체에필요한 작업 정리하면 ① 새로운 프로시저 구현 ② 기존 윈도우의 프로시저 대체 - 기존 프로시저 주소 확보 - 새로운 프로시저로 대체 CallWindowProc() GetWindowLong() SetWindowLong() 끝 부분에 이 함수 호출 추가 함수 주소는 여기서 획득 자~함수 사용법은 코드에서 직접
  • 16.
    16 #include <windows.h> LRESULT CALLBACKWndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK BtnProc(HWND, UINT, WPARAM, LPARAM); HINSTANCE _hInstance; WNDPROC _fpOldBtnProc; LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, WPARAM wParam, LPARAM lParam) { static HWND hBtn; switch(mesg) { case WM_CREATE: hBtn = CreateWindow(…); _fpOldBtnProc = (WNDPROC)GetWindowLong(hBtn, GWL_WNDPROC); SetWindowLong(hBtn1, GWL_WNDPROC, (LONG)BtnProc); break; … } 기존 버튼 프로시저 주소 저장 윈도우 핸들이 가리키는 윈도우에서 Get Window Long 윈도우 프로시저 정보 가져와라 프로시저 함수의 타입은 WNDPROC 지정한 윈도우 프로시저로 윈도우 프로시저를설정해라
  • 17.
    17 LRESULT CALLBACK BtnProc(HWNDhWnd, UINT mesg, WPARAM wParam,LPARAM lParam) { switch(mesg) { case WM_MOUSEMOVE: HDC hdc; HWND hParent; hParent = GetParent(hWnd); char szPos[32]; sprintf(szPos, "%03d %03d", LOWORD(lParam),HIWORD(lParam)); hdc = GetDC(hParent); TextOut(hdc, 102, 32, szPos, strlen(szPos)); ReleaseDC(hParent, hdc); break; } return CallWindowProc(_fpOldBtnProc,hWnd,mesg,wParam,lParam); } 부모 윈도우 핸들 획득 호출해라 지정 프로시저 함수를 이러한 파라미터를 가지고
  • 18.
    18 LONG GetWindowLong(HWND hWnd,int nIndex); LRESULT CallWindowProc(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); LONG SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong); 관련 함수 프로토타입 GWL_EXSTYLE 확장 윈도우 스타일 GWL_STYLE 윈도우 스타일 GWL_WNDPROC 윈도우 프로시저 주소 GWL_HINSTANCE 인스턴스 핸들 GWL_HWNDPARENT 부모 윈도우 핸들 GWL_ID 윈도우 식별자 CreateWindowEx()로 생성된 윈도우 nIndex