본문 바로가기

프로젝트/MFC 프로그래밍

3. MFC Programming : 쉽게 배우는 MFC 윈도우 프로그래밍(CH 5)

반응형

 공부 중 정리하면서 적은 글입니다. 중간 중간 누락되어 있는 부분이 있을 수 있으니 그 점 유의해 주시길  바랍니다.

 

 윈도우에서 대표적으로 사용하는 입력 장치에는 마우스와 키보드가 있다. CH 5에서는 이 두 장치를 다루는 방법에 대해서 다루고자 한다.

 마우스는 기본적으로 시스템에 한 개만 있는 자원이다. 즉 하나의 프로그램만이 마우스에서 발생하는 메시지를 받아 동작할 수 있다는 것이다. 원칙적으로 마우스 메시지는 마우스 커서가 위치해 있는 윈도우에 우선권이 있다. 예를 들어 마우스가 프레임 윈도우 위에 있다면 프레임 윈도우가 메시지를 받을 것이고, 뷰 윈도우 위에 마우스 커서가 위치해 있다면 뷰 윈도우가 메시지를 받을 것이다.

 다음은 마우스에서 발생하는 메시지를 정리한 것이다.

 

WM_LBUTTONDOWN 왼쪽 버튼 누름
WM_LBUTTONUP 왼쪽 버튼에서 뗌
WM_LBUTTONDBLCLK 왼쪽 버튼 더블 클릭
WM_MBUTTONDOWN 가운데 버튼 누름
WM_MBUTTONUP 가운데 버튼에서 뗌
WM_MBUTTONDBLCLK 가운데 버튼 더블 클릭
WM_RBUTTONDOWN 오른쪽 버튼 누름
WM_RBUTTONUP 오른쪽 버튼에서 뗌
WM_RBUTTONUP 오른쪽 버튼 더블 클릭
WM_MOUSEMOVE 마우스 움직임

 

 각각의 메시지에 대해 MFC 함수는 각각의 메시지를 다루기 쉽게 하도록 연관성있는 가상 메서드를 제공하고 있다. 프로그래머는 이를 재정의하여 사용하게 된다. 

 마우스 메시지 핸들러 관련 메서드는 2 개의 매개 변수를 가지고 있다. 하나는 메시지 발생 당시 키보드 혹은 마우스의 상태를 나타내고, 두 번째는 마우스 커서 위치를 나타낸다. 다음은 마우스 메시지를 사용하는 예시이다.

 

//BOOL m_bDrawMode : 그리기 모드를 결정하는 변수
//int m_x1, m_x2, m_y1, m_y2 : 좌상단, 우하단 좌표를 저장하기 위해 사용하는 변수
void CChildView::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	m_bDrawMode = false;
}

void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
	m_bDrawMode = true;

	m_x1 = m_x2 =  point.x;
	m_y1 = m_y2 = point.y;
}

void CChildView::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	if (m_bDrawMode) {
		CClientDC dc(this);

		dc.SelectStockObject(NULL_BRUSH);

		dc.SetROP2(R2_NOT);
		dc.Ellipse(m_x1, m_y1, m_x2, m_y2);

		dc.SetROP2(R2_NOT);
		m_x2 = point.x;
		m_y2 = point.y;
		dc.Ellipse(m_x1, m_y1, m_x2, m_y2);
	}
}

void CChildView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	CClientDC dc(this);
	dc.SelectStockObject(NULL_BRUSH);
	dc.SetROP2(R2_COPYPEN);
	m_x2 = point.x;
	m_y2 = point.y;
	dc.Ellipse(m_x1, m_y1, m_x2, m_y2);
	m_bDrawMode = false;
}

 

비클라이언트 영역에 대해서 마우스 동작이 있으면 본래의 메시지에 WM_NC* 형태의 메시지가 발생한다. 대응되는 메서드 함수의 매개변수는 2개이다. 하나는 메시작 생성될 당시의 마우스 커서 위치를 나타나낸다. 다른 하나는 메시지 발생 당시 마우스 커서 좌표를 나타낸다.(기준은 스크린 좌표이다.)

 다음은 마우스 커서와 관련된 함수들이다.

  • HCURSOR SetCursor(HCURSOR hCursor)
  • BOOL TrackMouseEvent(LPTRACK MOUSEEVENT lpEventTrack)

 키보드는 마우스와 더불어 전통적인 입력 매체 중 하나이다. 사용방법 자체는 마우스를 다루는 것과 크게 다르지는 않다.

 운영체제에서 어느 윈도우에 키보드 메시지를 전달할 것인가에 대해 WM_SETFOCUS 메시지를 전달받은 윈도우가 우선권을 가지고, WM_KILLFOCUS 메시지를 받은 윈도우는 우선권을 잃는다고 할 수 있다.

 키보드 커서를 윈도우에서는 Caret이라고 한다. Caret이 들어간 함수는 키보드 커서와 관련이 있다고 생각하면 된다.(개인적으로는 커서가 더 익숙하다.)

 다음은 키보드와 관련한 메시지이다.

 

  • WM_KEYDOWN : F10, Alt 이외의 키를 누를 때
  • WM_KEYUP : F10, Alt 이외의 키에서 손을 뗄 때
  • WM_SYSTEMKEYDOWN : F10, Alt, Alt+other key를 누를 때
  • WM_SYSTEMKEYUP : F10, Alt, Alt+other key에서 손을 뗄 때

 

 키 누름 메시지 핸들러는 3개의 매개 변수를 가진다. 하나는 가상 키 코드값, 다른 하나는 계속 누르고 있는 경우에 대해 값을 부여하는 것이고, 마지막은 키와 관련된 부가적인 정보이다.

WM_CHAR 메시지 핸들러는 단순한 키누름이 아닌 입력한 정확한 문자를 처리하고 싶을 때 사용하는 메시지이다. 핸들러는 앞서서 키보드 핸들러와 유사한 구조를 가지고 있다.

반응형