피씨컴의 기울어진 공관

API 4장

프로그래밍/공부 2013. 4. 17. 00:24

● WM_CHAR메시지

윈도우즈 환경에서는 주로 마우스가 많이 사용되지만 아직까지도 컴퓨터의 가장 기본적인 입력 장치는 키보드이다. 키보드로부터 입력이 발생했을 경우 윈도우즈는 포커스를 가진 프로그램에게 키보드 메시지(WM_CHAR, WM_KEYDOWN)를 보내며 프로그램은 이런 메시지를 받아 키보드 입력을 처리한다.

 

즉 WM_CHAR 메시지는 입력된 문자의 코드를 wParam으로 전달하며 우리는 wParam의 값을 원어 사용자가 어떤 문자커를 눌렀는지를 알아낸다.

예를 들어 사용자가 ‘S’ 키를 눌렀으면 wParam은 S의문자 코드값인 0x53 이 전달되며 이 값을 그대로 화면으로 출력하면 문자 S가 출력될 것이다.lParam에는 비트별로 다음과 같은 복잡한 정보가 전달된다.

 

 

이 중 필요한 정보가 있으면 lParam을 참조하여 사용하고 필요없으면 wParam만 사용하되 WM CHAR 메시지에서 lParam의 정보들을 사용해야 할 경우는 드물므로 당장 관심을 가질 필요는없다. 메시지 별로 필요한 추가 정보는 함께 전달되는 wParamm,lParam을 통해 넘어오는데 wParam과
lParam을 사용하는 방법은 메시지별로 다르므로 추가 정보에 대한 사항은 따로 공부해야 한다.

 

 

포커스(Focus) : 입력 초점이라는 뜻이며 커보드 입력을 받아들일 수 있는 상태라는 뜻이다.

 

포커스를 가진 상태란 활성화되어 있고 현재 사용자가 쓰고 있다는 뜻인데 한 번에 오직 하나의 프로그램만 활성화된다 활성화된 윈도우는 타이틀 바의 색상이 다른 윈도우와 다르게 표시되는데 보통 파란색으로 표시된다 아무리 여러 개의 프로그램이 동시에 실행되는 멀티 태스킹 환경이라 하더라도 활성화될 수 있는 프로그램은 오직 하나밖에 없으며 활성화된 프로그램만 포커스를 가지고 키보드 입력을 받아들일 수 있다.

 

 

● 무효영역

WM_PAlNT 메시지 는 윈도우가 다시 그려져 야 할 필요가 있을 때마다 호출되는데 다시 그려져 야 할필요가 있다는 말은 무효영역(Invalid Region)이 있다는 뜻이다.

 

서로다른 윈도우가 겹쳐져있으며 어느 한 윈도우의 화면영역 일부가 다른 윈도우에 의하여 가려져있다 이상태에서 앞에서 가리고 있던 윈도우를 옮겨 가려졌던 부분이 드러나면 바로 이부분이 무효영역인것이다. 운영체제는 윈도우가 무효영역을 가지고 있으면 이 윈도우에게 WM_PAlNT 메시지 를 보내 다시 그리게 한다.

 

직접 복구하지 않는 대신 철저하게 신호를 보내 스스로 그리기 를 할 수 있도록 도움을 준다.

 

● BOOL InvalidateRect(HWND hWnd, const RECT * lpRect, BOOL bErase)

프로그램 의 내부에서 윈도우의 모습을 변경시켰을 때 변경된 부분을 다시 그리도록 강제로 무효화해야하며 이때사용하는 함수가 바로 InvalidateRect 이다. 이 함수는 윈도우의 작업영역을 무효화하여 운영체제로 하여금 WM_PAINT 메시지를 해당 윈도우로 보내도록 한다

 

● WM_KEYDOWN

WM KEYDOWN 메시지 는 키보드를 누를 때마다 윈도우로 전달되는데 문자가 아닌 모든 키에 대 해서도 발생한다 단, Alt키와 윈도우 키, 한영 전환 키 등의 특수 키 몇 가지는 제외된다. 이 때 wParam으로는 문자 코드가 아닌 가상 키코드라는 것이전달된다 가상 키코드(Virtual Key Code)란 시 스템 에 장착된 키보드의 종류에 상관없이 키를 입력받기 위해 만들어 진 범용적인 코드값이 며 다음과 같이 정의 되어 있다.

 

 

● TranslateMessage

TranslateMessage 함수는 전달된 메시지가 WM_KEYDOWN인지와 눌러진 키가 문자키인지 검사해 보고 조건이 맞을 경우 WM_CHAR 메시지 를 추가로 발생시킨다. 물론 문자 업력이 아닐 경우는 아무일도 하지 않으며 이 메시지는 DispatchMessage 함수에 의해 WndProc으로 보내진다. 만약 메시지 루프에서 TranslateMessage 함수를 빼 버리변 WM_CHAR 메시지는 절대로 WndProc으로 전달되지 않을것이다.

 

메시지 루프의 TranslateMessage 함수는 오로지 키보드로부터 문자키 입력 메시지인 WM_CHAR를 만들어 내기 위해 존재한다.

만약 WM_CHAR메시지를 전혀 받을 필요가 없는 프로그램이라면 TranslateMessage 를 빼도 된다.

 

● Mouse

여기서 마우스라고 함은 진짜 쥐 새 끼 처 럼 생 긴 마우스는 물론이 고 노트북의 터치패드, 트랙볼과 출판용 타블릿 등을 모두 포함하는 명칭이다.

키보드 입력 처리를 메시지 로 하는 것과 마찬가지 로 마우스 압 력 처 리 도 메 시지를 받아 처리 한다. 마우스 입력 에 관한 메시지 는 다읍과 같은 종
류가있다.

 

마우스 버 튼의 누름 메시지 외에 마우스가 이동할 때마다 전달되는 WM MOUSEMOVE 메시지가 있다. 이 메시지 도 다른 마우스 메시지와 마찬가지 로 lParam에 마우스 커서의 위치가 전달되며wParam에 조합카 상태가 전달된다. 또한 휠 마우스가 등장함으로써 WM MOUSEWHEEL이라는 메시지가 추가되었다.

 

● Mouse 메시지의 wparam / lparam

마우스 메시지는 IParam의 상위 워드에 마우스 버튼이 눌러진 y좌표, 하위 워드에 x좌표를 가지며 좌표값을 검출해 내기 위해 HIWORD, LOWORD 등의 매 크로 함수를 사용한다. 즉 마우스 메시지가 발생한 위치 의 좌표는 (LOWORD(lParam), HIWORD(lParam))이 된다

 

메시지의 추가 정보로 전달되는 wParam, lParam은 둘 다 32비트 크기를 가지므로 총 64비 트의 정보를 전달할 수 있다.

 

단, 좌표값은 당연히 양수지만 읍수가 되 는 특별 한 경 우도 있음을 주의해야 한다.

 

wParam에는 마우스 버튼의 상태와 키보드 조합 키 (Shift, Ctrl)의 상태 가 전달된다. 조합키 상태는 다음 값들과 비 트 연산을 해보면 알 수 있다. 이 값을 참조하면 쉬프트 클릭, 좌우 동시 누름 등의 조건을 검출할수 있다.

 

 

 

 

 

 

● Mouse 더블클릭

더 블클릭이란 짧은 시간 안에 마우스 버튼을 두 번 빠르게 누르는 동작인데 프로그램 실행, 확정적인
선택 등에 많이 사용된다. 왼쪽 마우스 더블클릭 메시지는 WM_LBUTTONDBLCLK 이다.

 

- 사용전 사전준비

 

WndClass.lpfnWndProc=WndProc;
WndClass.lpszClassName=lpszClass;
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAWI CS_VREDRAWI CS_DBLCLKS;        // 스타일에 등록한다
ReglsterClass( & WndClass)

 

// 그리고 Proc함수에 추가하여 사용함 된다.

case WM LBUTTONDBLCLK:
InvalidateRect(hWnd, NULL, TRUE);
return 0;

 

● 타이머

대표 적으로 타이머 메시지인 WM_TIMER 이 메시지는 한 번 지정해 놓기만 하면 일정한 시간 간격을 두고 연속적으로 계속 발생한다. 주기적으로 같은 동작을 반복해야 한다거나 여러 번 나누어 해야 할 일이 있을 때 이 메시지 를 이용한다.

 

- UINT SetTimer(HWND hWnd,UINT nIDEvent, Uint uElapse, TIMERPROC lpTimerFunc);

1. 단위는 1/1000초이다

2. 타이머의 최대 해상도는95/98에서는 0.055초이며 NT/2000에서는 0.01초에 불과하다 (1초에 100회 /98에서는 18회)

 

- BOOL KiIITimer( HWND hWnd, UINT ulDEvent);

1. 설치된 타이머를 제거하는 것이며

 

-현재 시간을 구하기

SYSTEMTIME구조체와 GetLocalTime함수를 이용

 

 

● Send Message

LRESULT SendMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

메시지는 사용자의 동작이나 시스템상황에 의해 발생하는 것이 원칙이지만 강제로 메시지가 발생한 것처럼 만들어야 할 때는 이 함수를 사용하여 hWnd 윈도우로 Msg 메시지 를 보내면 된다. 그러면 hWnd는 Msg 메시지가 발생한 것으로 인식하고 필요한 처리 를 하게 될 것이다.

 

● 콜백함수

VOID CALLBACK TimerProc(HWND hWnd, UINT umsg, UINT idEvent,DWORD dwTime);

아무튼 중요한 사실은 이런 원형을 가지는 함수를 만든 후 SetTimer 함수의 네 번째 인수에 이 함수명을 전달하면 지정한 시간 간격으로 이 함수가 호출된다는 점이다.

 

1. API 함수들은 운영체제가 제공하며 프로그램에서는 이 함수들을 호출하여 운영체제의 서비스를 받는 다.

2. 콜백함수는 응용 프로그램이 제공하며 운영체제가 필요할때 호출하는 함수이다

3. 호출되는 방향이 거꾸로 되었기 때문에 콜백이라 부르는 것이다.

4. 콜백함수의 예는 메시지 처리함수인 WndProc이다 이 함수는 메시지가 발생할 때마다 윈도우즈가 호출하며 응용프로그램 내부에 있지만 응용프

    로그램에서 직접 이 함수를 호출하지 않는다 오직 운영체제만이 이 함수를 호출한다.

 

타이머의 경우 콜백함수를 사용하는 것과 WM TIMER 메시지 를 받는 것은 사실상 거의 통일한 기법이라고 할 수 있으며 상황에 따라 편리한 방법을 사용하면 된다. 차이점이라면 WM TIMER 메시지는 다른 메시 지 가 있을 경우 실행 순서에 밀려 늦게 호출되는 경우가 있지만 콜백함수를 사용하
면 절활한꺼낸에 후출된다는결,0 1 다 그래서 정확도를 요하는 작업은 타이머 메시지보다는 콜백함수를 사용하는 것이 더 좋다고 되어 있다. 하지만 Win32 환경에서 는 사실상 별 차이가 없다.

 

-일회용 타이머

Sleep() : 이 함수는 도스의 delay와 기능상 동일하며 지정한 동안 프로그램의 실행을 잠시 정지시킨다

Sleep 함수는 지정한 시간동안 프로그램을 완전히 정지시켜 버리므로 대기하는 동안에는 다른 일체의 작업을 할 수 없다. 문자열을 표시하는 3초 동안은 윈도우를 이동할 수도 없고 키 입력에도 반응하지 않는다. 심지어 WMPAINT 메시지도 처리하지 못하기 때문에 3초 내에 다른 윈도우가 이 윈도우를 가리면 문자열을 다시 그리지도 못한다.

 

● 생성 및 파괴

WM_CREATE와 WM_DESTROY 두 가지가 있다. WM_CREATE 메시지 는 윈도우가 생성될 때 보내지므로 각종 초기화를 하기에 적합한 장소이며
반대로 윈도우가 파괴될 때 보내지는 WM_DESTROY 메시지는 종료처리를 하기에 적합하다 두 메시지는 윈도우의 일생을 통틀어 딱 한 번씩만 전달되는 특성이 있어 일회적인 작업인 초기, 종료 처리에 사용할 수 있다.

 

WM_DESTROY에서 주의할 것은 메 인 윈도우의 경우 반드시 PostQuitMessage 함수를 호출해야 한다는 점이다.

메인 윈도우는 응용 프로그램이 처음 만드는 윈도우인데 자신이 파괴될 때 응용 프로그램을 종료해야 하는 막중한 임무가 부여되어 있다. PostQuitMessage 함수는 메시지 큐에 WM_QUIT를 넣음으로써 WinMain에 있는 메시지 루프를 종료시카고 WinMain 함수 자체를 종료하여 운영체제로 복귀 시키는 역할을 한다.

 

● 작업영역

윈도우는 작업영역(Client Area)과 비작업영역이(Non Client Area) 두 부분으로 구성되어 있다

작업영역 이란 쉽게 말해서 윈도우 중앙의 흰 부분을 말하며 비작업영역이란 그 외의 영역을 말한다. 비작업영역 에 속하는 부분은 일단 타이틀 바와 경계선이 있고 메뉴가 있을 경우 메뉴도 비작업영역에 속한다. 작업/비 작업영역의 구분은 윈도우를 이해하는데 중요한 비 중을 차지하는데 왜냐하면 프로그래밍 대상이 되 는 것은 작업영역 에 한정되 기 때문이다.

 

- BOOL GetClientRect(HWND hWnd, LPRECT lpRect); ※ 사용할수 있는 진정한 영역

원하는 위치에 정확하게 출력 하려면 윈도우가 차지 하고 있는 영역의 좌표를 조사해 야 하는 것 이 아니라 작업 영역의 좌표를 조사해야 한다.

이를 위해 사용하는것이 바로 이함수다.

 

● WM_SIZE

문자열을 계 속 작업영역 중앙에 두고 싶으면 윈도우의 크기가 변경될 때마다 다시 춤력해야 하는데 이때 사용되는 메시지가 WM_SIZE이다. 이 메시지는 윈도우의 크기가 변경될 때 전달되 는데 lParam의 하위 워드에는 변경된 후의 윈도우 폭이 상위 워드에는 높이가 전달되며 wParam에는 이 메시지가 발생한 이유를 나타내는 플래그가 전달된다.

 

 

 

다음과 같이 사용될 수 있다.

case WM SIZE:
    rt.right=LOWORD(IParam);
    rt.bottom=HIWORD(IParam);
    InvalidateRect(hWnd, NULL, TRUE);
return 0;

 

 

 

● WM_MOVE

이 메시지는 윈도우의 위치가 변경될때마다 보내지는데 lParam의 하위 워드에 윈도우의 새 X좌표 상위 워드에 윈도우의 새 Y 좌표가 전달된다.

그러나 현실적으로 이 메시지는 잘 사용되지 않는다. 왜냐하면 위치 는 크기와 달리 응용 프로그램에 별다른 영향을 주지 않기 때문이다.

 

 

 

'프로그래밍 > 공부' 카테고리의 다른 글

DX 기본수학 (2)  (0) 2013.06.19
Dx 기본 수학 (1)  (0) 2013.06.19
API 3장  (0) 2013.04.16
API 2장  (0) 2013.04.16
AIP 1장  (0) 2013.04.16
Posted by 피씨컴