SetCapture

원형

HWND SetCapture(HWND hWnd);

MFC 원형

CWnd* CWnd::SetCapture( );

인수

▶hWnd : 마우스를 캡처할 윈도우의 핸들

리턴

이전에 마우스를 캡처하고 있던 윈도우의 핸들을 리턴하되 캡처한 윈도우가 없으면 NULL을 리턴한다.

설명

마우스 버튼의 누름, 이동, 뗌 등의 마우스 메시지는 보통 커서 바로 아래쪽에 있는 윈도우로 전달된다. 이는 지극히 정상적이며 상식적이나 가끔 커서가 영역밖을 벗어나도 계속적으로 마우스 메시지를 받아야 하는 경우도 있다. 이런 경우는 마우스 커서를 캡처해야 한다. SetCapture 함수는 hWnd 윈도우가 마우스 커서를 캡처하도록 하며 이렇게 되면 커서가 윈도우의 영역밖을 벗어나더라도 계속해서 마우스 메시지를 보내준다. 이 상태는 ReleaseCapture 함수로 캡처를 풀기 전까지 계속된다. 주로 드래그 동작을 할 때 캡처가 필요하다.

현재 스레드에 속한 윈도우만 캡처를 할 수 있으며 한번에 하나의 윈도우만 마우스를 캡처할 수 있다. 마우스를 캡처한 윈도우는 모든 마우스 메시지를 전달받는데 단 예외적으로 다른 스레드에 속한 윈도우를 누를 경우는 캡처 여부에 상관없이 커서 아래쪽의 윈도우로 메시지가 전달되며 이 경우 해당 윈도우는 포그라운드 상태가 된다. 마우스 버튼 누름은 작업의 전환을 의미하므로 캡처 여부에 상관없이 해당 윈도우로 전달된다. 그러나 보통 마우스 버튼을 누른 상태에서 커서를 캡처하기 때문에 이런 경우는 극히 드물다.

포그라운드 윈도우가 마우스를 캡처하는 것이 보통이지만 백그라운드 윈도우도 마우스를 캡처할 수 있다. 이 경우 커서가 백그라운드 윈도우의 보이는 부분에 있을 때만 마우스 메시지가 전달된다. 캡처 상태에서는 메뉴의 핫키, 액셀러레이터 등은 동작하지 않는다.

예제 1

다음 예제는 마우스가 이동하는대로 자유 곡선을 그린다.

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	static int x, y;

	switch(iMessage) {
	case WM_LBUTTONDOWN:
		x=short(LOWORD(lParam));
		y=short(HIWORD(lParam));
		SetCapture(hWnd);
		return 0;
	case WM_MOUSEMOVE:
		if (GetCapture()==hWnd) {
			hdc=GetDC(hWnd);
			MoveToEx(hdc,x,y,NULL);
			x=short(LOWORD(lParam));
			y=short(HIWORD(lParam));
			LineTo(hdc,x,y);
			ReleaseDC(hWnd,hdc);
		}
		return 0;
	case WM_LBUTTONUP:
		ReleaseCapture();
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

마우스 버튼을 누른 상태에서 이동하면 선을 연결하여 계속 그리는데 커서가 작업 영역밖을 벗어나더라도 좌표 갱신을 계속 해 주어야 한다. 물론 영역밖으로 선이 그려지는 것은 아니지만 캡처를 하지 않으면 커서가 갑자기 영역안으로 들어왔을 때 영역밖으로 나간 지점과 선이 연결되어 연속적인 자유 곡선을 그릴 수 없다. 또한 커서를 캡처하지 않은 상태에서 영역 바깥에서 버튼을 놓았을 때 이 윈도우는 그리기가 끝났다는 사실을 알 수 없게 된다. 실행중의 모습은 다음과 같다.

만약 캡처를 하지 않고 전역 변수로 그리기 상태인지를 판단하도록 한다면 작업 영역 바깥으로 벗어날 때의 처리를 제대로 할 수가 없다.

참고함수

ReleaseCapture, GetCapture

플랫폼

95이상

참조

 


written by http://www.winapi.co.kr