본문 바로가기
프로그래밍/MFC

MFC-GetWindowRect(), ScreenToClient(), SetWindowPos()

by 리뷰하는 (게임)프로그래머_리프TV 2010. 5. 12.




CWnd 클래스에 포함되어 있는 함수들,

이 외에도 어마어마 하겠지만, 하나하나 생각나고 보이는 대로 그때 그때 매번 확인 하도록하자.

GetWindowRect는 CRect의 주소를 입력해 주면 대상 CRect에 윈도우의 두 좌표를 입력해 준다.

ScreenToClient는 클라이언트 뷰 기준의 좌표로 변환한다.
즉, 스크린 기준 작업영역에 대한 뷰 기준의 좌표로 변환 하게 되는데 CPoint를 인자로 받게 된다.

GetWindowPos는 대상 윈도우의 위치를 이동하기 위한 함수이다.
인자는 z축, 시작 x,y 와 크기 x, y, 플래그 값을 매개변수로 받는다.

대략 이정도로 살펴 보고 예제 코드를 살펴 보자.

먼저 CWnd를 하나 추가하고, (코드 생략)

적당한 위치에 생성해 주자.(OnCreate사용)

	m_wndChild.Create( TEXT("STATIC"), TEXT("What Funtion?"),
		WS_CHILD | WS_VISIBLE | WS_BORDER, 
		CRect( 50, 50, 300, 300), this, 1 );​


OnKeyDown 함수를 만들고,

void CTest1View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

	CString strText = TEXT("");
	CRect Rect;

	// 윈도우 좌표를 삽입.
	m_wndChild.GetWindowRect( &Rect );

	// 현재 윈도우가 어느 곳에 띄워져 있는 가에 따라서 키를 누를 때 마다 
	// 그 값이 갱신 되는 것을 확인 할 수 있다.
	strText.Format( TEXT(" left: %d\n top: %d\n right: %d\n bottom: %d"), 
		Rect.left, Rect.top, Rect.right, Rect.bottom );

	m_wndChild.SetWindowText( strText );

	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}​


코드 작성 후 실행하면, ChildClass 위치가 window좌표를 기준으로 확인이 가능하게 된다.




현재 창이 윈도우 기준으로 어느 위치에 떳는지 변경을 확인 할 수 있다.




이제 조금 예제를 변경해서, 윈도우 스크린으로 받은 좌표를 현재 윈도우의 작업영역에서 변경하기 위해서
ScreenToCilent를 사용해 보자.

void CTest1View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

	CString strText = TEXT("");
	CPoint ptChild;
	CRect Rect;

	// 윈도우 좌표를 삽입.
	m_wndChild.GetWindowRect( &Rect );

	// ptChild의 x,y에 좌측 상단 점을 찍어 주자.
	ptChild.x = Rect.left;
	ptChild.y = Rect.top;

	// 그 위치를 현재 작업 영역에 대한 좌표로 변경
	ScreenToClient( &ptChild );

	// 현재 윈도우가 어느 곳에 띄워져 있는 가에 따라서 키를 누를 때 마다 
	// 그 값이 갱신 되는 것을 확인 할 수 있다.
//	strText.Format( TEXT(" left: %d\n top: %d\n right: %d\n bottom: %d"), 
//		Rect.left, Rect.top, Rect.right, Rect.bottom );

	// 값의 확인
	strText.Format( TEXT("ptChild.x : %d\n ptChild.y: %d\n"), 
		ptChild.x, ptChild.y );

	m_wndChild.SetWindowText( strText );

	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}​

 


이제 윈도우가 어느 위치에 있던지 간에 작업영역을 기준으로 좌표가 보이게 된다.

마지막으로 키보드 입력에 대한 윈도우 이동을 해보자.

void CTest1View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

	CString strText = TEXT("");
	CPoint ptChild;
	CRect Rect;

	// 윈도우 좌표를 삽입.
	m_wndChild.GetWindowRect( &Rect );

	// ptChild의 x,y에 좌측 상단 점을 찍어 주자.
	ptChild.x = Rect.left;
	ptChild.y = Rect.top;

	// 그 위치를 현재 작업 영역에 대한 좌표로 변경
	ScreenToClient( &ptChild );

	// 현재 윈도우가 어느 곳에 띄워져 있는 가에 따라서 키를 누를 때 마다 
	// 그 값이 갱신 되는 것을 확인 할 수 있다.
//	strText.Format( TEXT(" left: %d\n top: %d\n right: %d\n bottom: %d"), 
//		Rect.left, Rect.top, Rect.right, Rect.bottom );

	// 키 입력에 따른 window 이동을 해보자.
	switch( nChar )
	{	
		// 좌우 방향에 대해 이동을 시켜 보자.
	case VK_LEFT:
		ptChild.x -= 10;
		break;
	case VK_RIGHT:
		ptChild.x += 10;
		break;
	}

	// 값의 확인
	strText.Format( TEXT("ptChild.x : %d\n ptChild.y: %d\n"), 
		ptChild.x, ptChild.y );

	m_wndChild.SetWindowText( strText );

	m_wndChild.SetWindowPos( &CWnd::wndTop, ptChild.x, ptChild.y, 0, 0, 
		SWP_SHOWWINDOW | SWP_NOSIZE );

	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}​


실행을 해보면 좌우 방향에 대해 이동을 하고 있다.
SetWindowPos에서 크기에 대한 값이 0, 0을 가르키고 있지만,
플래그 조정에서 사이즈 변경을 막고 있기 때문에(SWP_NOSIZE), 큰 문제가 되진 않는다.
플래그에 대한 옵션은 일일이 다 설명하는건 불가능 하기 때문에, 따로 설명을 하지 않겠다.

방향을 조정 할 때 마다 위치 변경과 표시가 되는 것이 확인 가능하다.

어떻게 보니 되게 소스가 거대해 진거 같지만, 하나하나 살펴 보면 그렇게 어렵지 않은 것 같다.

물론 여기서 y축에 대한 변경도 충분히 가능하지만, x축에서 종료를 하도록 하자.

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

MFC-마우스 입력  (0) 2010.05.16
MFC-GetKeyState()  (0) 2010.05.12
MFC-키보드 입력  (0) 2010.05.12
MFC-새로운 자식 클래스 생성하기  (0) 2010.05.12
MFC-기본적인 생성 방법  (0) 2010.05.12