본문 바로가기

공부/MFC

Visual C++ 2008 MFC Chapter 5 의 실습예제

=============================

본 코드는 실습예제를 나름대로 짜본 코드로 책 원문이나 책의 저자가 가지고 있는 해답본은 없습니다.[저자가 카페를 통해 답안지는 없다 라고 했습니다.]

=============================


155페이지의 1번과 2번 문제

에 대한 코드는 한 프로젝트, 한 함수 에 코딩이 가능하므로  짜둔 코드를 그대로 긁어보았습니다.

이외의 코드는 챕터 5의 본문과 같습니다.


1번문제의 코딩 힌트는 앞서 적었던 left 나 right 처럼 VK_UP 과 DOWN을 써주고

그에 맞는 y값의 연산을 해주는 것이고.

2번문제의 코딩 힌트는 컨트롤 키 는 시스템 키 가 아니라는 것 과 

시스템 키 ALT와 SPACE키를 같이 눌러서 메시지를 출력하는 코드를 그대로 사용하는 것 입니다.


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

CPoint ptChild;// 차일드 윈도우의 좌표
CRect Rect; //차일드 윈도우의 좌표 및 크기

//차일드 윈도우의 두 좌표 정보(스크린 기준)을 알아온다.(두번 말하는 듯 하지만...자식 윈도우의 현재 위치를 다시 구하는 함수)
m_wndChild.GetWindowRect(&Rect);
ptChild.x = Rect.left;
ptChild.y = Rect.top;
//스크린 기준 좌표를 클라이언트 뷰 기준의 좌표로 환산한다.
ScreenToClient(&ptChild);// 두번 말하는 듯 하지만 상세히 풀어서 주석을 달면.... (이 줄에 중단점을 설정하고 
//작동 전과 작동 후로 보면 어떻게 작업 결과가 나오는지 알 수 있다.
//ptChild의 값을 스크린 기준 좌표(위에서 getwindowrect로 구한것)에서 뷰 기준의 좌표로 바꾸는 것.
//이를 하지 않으면 스크린 기준과 뷰 간의 거리만큼 자식 윈도우가 이동해버리면서 작동한다.

//실습예제 2번 , 1번,

WORD RResult = ::GetKeyState(VK_CONTROL);
BYTE byRHigh = HIBYTE(RResult);//이 부분을 따온 것 입니다.



if(byRHigh & 0x01) // if문을 통해 해당 키[Ctrl 키] 가 눌린 상태라면
{                         //아래의 스위치 문을, 아니라면 else쪽의 스위치 문을 사용하게 합니다.
switch(nChar)
{

case VK_LEFT:
ptChild.x -= 50;
break;
case VK_RIGHT:
ptChild.x += 50;
break;

//실습예제 코드 추가[상 하 로 이동하는 자식 윈도우.]
case VK_UP:
ptChild.y -= 50;
break;


case VK_DOWN:
ptChild.y += 50;
break;

//여기까지. 실습예제 1번.
}
}
else{
switch(nChar)
{


case VK_LEFT:
ptChild.x -= 10;
break;
case VK_RIGHT:
ptChild.x += 10;
break;

//실습예제 코드 추가[상 하 로 이동하는 자식 윈도우.]
case VK_UP:
ptChild.y -= 10;
break;
case VK_DOWN:
ptChild.y += 10;
break;
//여기까지. 실습예제 1번과 2번의 코드.
}
}


//변경된 새 좌표로 차일드 윈도우를 이동시킨다.(위치를 다시 정한다.)
m_wndChild.SetWindowPos(&CWnd::wndTop, ptChild.x, ptChild.y, 0, 0, SWP_SHOWWINDOW | SWP_NOZORDER |SWP_NOSIZE);





//이 위까지. 가 입력한 코드
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

 ============================================================
코딩을 하더라도 출력화면상의 변화는 없기 때문에 따로 스크린샷을 첨부하진 않습니다.

1번 2번 문제의 코드 파일




====================================================

 3번문제, 키 입력으로 차일드 윈도우의 사이즈를 변경하는 법.





#include "stdafx.h"
#include "KeyMove.h"

#include "KeyMoveDoc.h"
#include "KeyMoveView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

int a= 100;
int b= 100;

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

위는 반복에 영향을 받아 값이 바뀌는 a와 b값을 지정한 것이고

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 


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

CPoint ptChild;// 차일드 윈도우의 좌표
CRect Rect; //차일드 윈도우의 좌표 및 크기



//차일드 윈도우의 두 좌표 정보(스크린 기준)을 알아온다.(두번 말하는 듯 하지만...자식 윈도우의 현재 위치를 다시 구하는 함수)
m_wndChild.GetWindowRect(&Rect);
ptChild.x = Rect.left;
ptChild.y = Rect.top;

//스크린 기준 좌표를 클라이언트 뷰 기준의 좌표로 환산한다.
ScreenToClient(&ptChild);// 두번 말하는 듯 하지만 상세히 풀어서 주석을 달면.... (이 줄에 중단점을 설정하고 
//작동 전과 작동 후로 보면 어떻게 작업 결과가 나오는지 알 수 있다.
//ptChild의 값을 스크린 기준 좌표(위에서 getwindowrect로 구한것)에서 뷰 기준의 좌표로 바꾸는 것.
//이를 하지 않으면 스크린 기준과 뷰 간의 거리만큼 자식 윈도우가 이동해버리면서 작동한다.

//실습예제 3


switch(nChar)
{
case VK_LEFT:
a -= 10;
break;
case VK_RIGHT:
a += 10;
break;
case VK_UP:
b -= 10;
break;
case VK_DOWN:
b += 10;
break;
}

m_wndChild.SetWindowPos(&CWnd::wndTop, ptChild.x, ptChild.y, a, b, SWP_SHOWWINDOW | SWP_NOZORDER ); //변경된 새 크기[a나 b의 위치로] 윈도우의 크기를 다시 정한다.
 

//이 위까지. 가 입력한 코드
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}


\\\\\\\\\\\\\\\\\\\\\\\\\

여기서는 그 두 값을 키입력에 따라 변경하면서 setwindowpos에 넣어주는 코드를 사용하였다. 

3번 문제의 경우  내가 짠 것이기 때문에 다른 사람의 코드와 다를 수 있고

본인이 보기에도 별로 잘 짯다기 보다는 이런 방법으로도 풀 수 있다 정도라고 보지만

어떻게 풀어야 하는지 잘 모르는 이를 위해 적어두었다.

여기서 함수 밖의 변수를 사용하지 않으면 조정된 크기가 유지되지 않고 다시 초기화 되는 문제가 발생한다.

그래서 공용 변수 a와 b를 사용한 것이다.

\\\\\\\\\\\\\\\\\\\\\\\\\\\

마지막으로 마지막 문제 4번의 경우

책에 하라고 만 되어있지 아무 힌트도 없음을 알 수 있다.

구글링을 해서 다른 한국 블로그에서 그 해결방법을 얻었다.

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

CView::OnSysChar(nChar, nRepCnt, nFlags);

if(nChar == VK_RETURN)
AfxMessageBox(TEXT("Alt + Enter"));
else if(nChar == 's' || nChar == 'S')
AfxMessageBox(TEXT("Alt + S"));
else if(nChar == 'x' || nChar == 'X')
{

AfxMessageBox(TEXT("Alt + X"));
//4번문제 관련 코드를 위해 if문의 위치를 아래로 내렸다.
 ASSERT(AfxGetMainWnd() != NULL);
      AfxGetMainWnd()->SendMessage(WM_CLOSE);
//여기까지가 종료하는 코드.
}
}


주석 사이에 있는 코드가 윈도우 종료 메시지를 전송하는 코드이다.

주의점은  CView::OnSysChar(nChar, nRepCnt, nFlags);

의 아래에 코드를 입력해야 한다는 것.


3 번 4번 문제의 코드 파일