본문 바로가기
스터디 하드/방통대 컴퓨터과학과

2016년 1학기 방통대 Visual C++ 프로그래밍 대체과제 문제 및 답안

by 피타칩스 2016. 10. 8.

Visual C++ 대체시험 과제는 제가 느끼기에 좀 난이도가 있었습니다.


교재 1.5장에 나온 내용을 기반으로 조금만 추가, 수정, 삭제, 변형하면 해결할 수 있는 과제라고 교수님이 힌트까지 주었고 그 소스코드도 모두 공개되어있었지만, 그게 말로만 쉽지... 해당 내용을 전후방적으로 이해하고 있어야만 했습니다. 상대적으로 긴 길이의 소스코드에서 어디를 수정하고 무엇을 추가해야하는지 판단하려면 그냥 대충 알아서는 무지하게 헷갈리거든요.


사실 제가 내용을 충분히 이해하지 못한 상황에서 문제를 풀려고 해봤는데.. 어려웠습니다 ㅋㅋ


그래서 강의랑 워크북 열심히 공부했는데요, 이해하고 나니 문제도 쉽게 풀렸고, 해결과정에서 윈도우프로그래밍 메커니즘도 숙지하게 되었습니다. 


그리고 교수님은 1.5장의 코드를 주로 참고하라고 써놓으셨는데, 저는 워크북에 있는 내용이 더 큰 힌트가 되었어요. 혹시라도 나중에 Visaul C++ 뿐만 아니라 다른 과목들 과제나 공부를 하다가 본교재의 내용이 충분하지 않다고 생각되면 워크북을 참고하는 것도 좋겠습니다.


그럼 이번학기 Visual C++ 문제입니다. 문제도 길고 작성 요구사항까지도 꽤 길어요~! 정신 바짝차리고 하나하나 챙기지 않으면 요건미충족으로 삐끗해서 감점 당할 수 있습니다. 눈 크게 뜨고 보셔야해요 ㅎ




<문제>

교재 1 장의 1.5절 버튼사용하기 프로그램에서 다음의 조건을 만족하도록 프로그램을 수정하시오.


<조건>

(1) 다음 그림과 같이 메인 윈도우 타이틀은 “Visual C++ 프로그래밍 과제물” 이라 하고 메인 윈도우에는 “본인의 학번과 이름”이 출력된다. (설명을 위하여 편의상, 서울지역대학 소속이며 컴퓨터과학과 2학년 이름: 홍길동, 학번: 201234-123456 으로 가정한다)



(2) 다음 그림과 같이 타이틀이 보이도록 두 개의 서로 다른 크기의 차일드 윈도우를 만드는데, 첫 번째 차일드 윈도우 타이틀은 “소속지역대학” 이고 차일드 윈도우에는 본인의 소속지역대학 이름인 “서울지역대학”이 출력된다. 또한 하나의 버튼을 만들고 캡션이름은 “안내전화”로 한다. 두 번째 차일드 윈도우 타이틀은 “학과” 이고 차일드 윈도우에는 본인의 소속학과인 “컴퓨터과학과”가 출력된다.


(3) 다음 그림과 같이 메인 윈도우에 두 개의 버튼을 만들고, 각각의 버튼 캡션 이름을 [대체과제물]과 [학번]으로 한다.


(4) [대체과제물] 버튼을 클릭했을 때는 다음 그림과 같이 메시지 박스에는 “대체과제물 제출일 6월12일”, 캡션은 “제출일”이 나타난다.


(5) [학번]버튼을 클릭했을 때는 다음 그림과 같이 메시지 박스에는 “201234-123456”, 캡션은 “학번”이 나타난다.


(6) [안내전화]버튼을 클릭했을 때는 다음 그림과 같이 메시지 박스에는 소속지역대학의 전화번호 “02-8403-725”, 캡션은 “지역대학 전화” 가 나타난다. (안내전화는 편의상 02-8403-725로 가정했다)(그림은 생략)


<작성방법>

(1) 먼저, HelloAPI.cpp 파일(WinMain 함수가 들어간 프로그램) 을 프린트해서 제출한다.

(2) 둘째, 프로그램을 실행했을 때 나타나는 초기 윈도우 화면, [대체과제물],[학번],[안내전화] 버튼을 각각 클릭 했을 때 나타나는 각각의 윈도우화면 전체를 캡쳐하여 프린트하여 제출한다. 따라서 제출하는 윈도우 화면은 그림에서 보듯이 모두 4개이다.

(3) 과제물은 CD로 받지 않으며 MFC를 사용하면 안 된다.


<제출 과제물 순서>

(1) 프로그램

(2) 출력결과


※ 참고사항

교수 홈페이지(http://cs.knou.ac.kr/~khkim/) => VC++프로그래밍=> 학습정보=> VC++프로젝트 소스코드-1장(4강) 에서 “04.HelloAPI_메시지박스 (4강).zip” 프로젝트파일을 수정하면 도움이 된다.




여기까지가 대체시험 시행공고에 나온 문제였습니다. 지금까지 봤던 대체시험 과제들 중 가장 길고, 가장 까다롭게 요구하는게 많은 그런 문제였어요.



이 문제에 대한 저의 답안은 다음과 같았습니다. 


(1) 프로그램

#include <windows.h>


#define ID_COLLEGE 1000

#define ID_DEPT 2000


#define ID_TEL_BTN 1100

#define ID_HW_BTN 3000

#define ID_HAKBUN_BTN 4000


HINSTANCE g_hInst;

LPCTSTR lpszClass = L"HelloAPI";

LPCTSTR ChildClassName1 = L"ChildWin1";

LPCTSTR ChildClassName2 = L"ChildWin2";


LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

LRESULT CALLBACK ChildWndProc1(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

LRESULT CALLBACK ChildWndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


int APIENTRY WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpszCmdParam,

int nCmdShow)

{

HWND hWnd;

MSG Message;

WNDCLASS WndClass;

g_hInst=hInstance;

WndClass.cbClsExtra=0;

WndClass.cbWndExtra=0;

WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); 

WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);    

WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);

WndClass.hInstance=hInstance;

WndClass.lpfnWndProc=(WNDPROC)WndProc;

WndClass.lpszClassName=lpszClass;

WndClass.lpszMenuName=NULL;

WndClass.style=CS_HREDRAW | CS_VREDRAW;

RegisterClass(&WndClass);     //메인윈도우 클래스 등록


WndClass.lpfnWndProc =ChildWndProc1;      //차일드 윈도우 프로시저

WndClass.lpszClassName =ChildClassName1; //차일드 윈도우 클래스이름

RegisterClass(&WndClass); 


WndClass.lpfnWndProc = ChildWndProc2;      //차일드 윈도우 프로시저

WndClass.lpszClassName = ChildClassName2; //차일드 윈도우 클래스이름

RegisterClass(&WndClass);


hWnd=CreateWindow(lpszClass, //윈도우클래스 이름

L"Visual C++ 프로그래밍 과제물", //윈도우타이틀

WS_OVERLAPPEDWINDOW | WS_VISIBLE,   //윈도우스타일

200, 200, //윈도우가 보일때 X Y좌표

700, 450, //윈도우의 폭과 높이

(HWND)NULL, //부모윈도우 핸들

(HMENU)NULL, //윈도우가 가지는 메뉴핸들

hInstance, //인스턴스핸들

NULL); //여분의 데이터


    ShowWindow(hWnd,nCmdShow);

while(GetMessage(&Message,0,0,0)) {

TranslateMessage(&Message);

DispatchMessage(&Message);

}

return Message.wParam;

}


LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage,

WPARAM wParam, LPARAM lParam)

{

LPCTSTR text = L"201534-010101 피타칩스";

switch(iMessage) 

{

case WM_PAINT:

{

PAINTSTRUCT ps;

HDC hdc = BeginPaint(hWnd, &ps);

TextOut(hdc, 100, 100, text, lstrlen(text));

EndPaint(hWnd, &ps);

return 0;

}

case WM_CREATE:

{

HWND hChildWnd = CreateWindow( 

ChildClassName1,     // 차일드 윈도우 클래스 이름 

L"소속지역대학",             // 윈도우 타이틀 

WS_OVERLAPPEDWINDOW | WS_CHILD,  // 윈도우  스타일 

50,       // 윈도우 보일 때 x 좌표 

150,       // 윈도우 보일 때 y 좌표 

250,       // 윈도우 폭

150,       // 윈도우 높이

hWnd,         // 부모 윈도우

(HMENU) ID_COLLEGE,         // 차일드 윈도우ID 

g_hInst,           // 인스턴스 핸들 

(LPVOID) NULL);       // 여분의 데이터


ShowWindow(hChildWnd, SW_SHOW); 




HWND hChildWnd = CreateWindow( 

ChildClassName2,      // 차일드 윈도우 클래스 이름 

L"학과",             // 윈도우 타이틀 

WS_OVERLAPPEDWINDOW | WS_CHILD,  // 윈도우  스타일 

350,        // 윈도우 보일 때 x 좌표 

150,        // 윈도우 보일 때 y 좌표 

150,        // 윈도우 폭

150,        // 윈도우 높이

hWnd,          // 부모 윈도우

(HMENU) ID_DEPT,         // 차일드 윈도우ID 

g_hInst,            // 인스턴스 핸들 

(LPVOID) NULL);       // 여분의 데이터


ShowWindow(hChildWnd, SW_SHOW);



hChildWnd = CreateWindow(

L"button",         // 윈도우 클래스 이름 

L"대체 과제물", // 윈도우 타이틀 

WS_CHILD|WS_VISIBLE, // 윈도우 스타일 

50,       // 윈도우 보일 때 x 좌표 

350,       // 윈도우 보일 때 y 좌표 

100,       // 윈도우 폭

30,       // 윈도우 높이

hWnd,         // 부모 윈도우

(HMENU) ID_HW_BTN,   // 컨트롤 ID

g_hInst,           // 인스턴스 핸들 

(LPVOID) NULL);       // 여분의 데이터


hChildWnd = CreateWindow(

L"button",         // 윈도우 클래스 이름 

L"학번", // 윈도우 타이틀 

WS_CHILD | WS_VISIBLE, // 윈도우 스타일 

300,       // 윈도우 보일 때 x 좌표 

350,       // 윈도우 보일 때 y 좌표 

100,       // 윈도우 폭

30,       // 윈도우 높이

hWnd,         // 부모 윈도우

(HMENU)ID_HAKBUN_BTN,   // 컨트롤 ID

g_hInst,           // 인스턴스 핸들 

(LPVOID)NULL);       // 여분의 데이터


if (!hChildWnd) return -1;

return 0;

}

case WM_COMMAND:

{

if(LOWORD(wParam) == ID_HW_BTN)

{

MessageBox(hWnd, L"대체과제물 제출일 6월 12일", L"제출일", MB_OK);

}

if (LOWORD(wParam) == ID_HAKBUN_BTN)

{

MessageBox(hWnd, L"201534-010101", L"학번", MB_OK);

}

return 0;

}

case WM_DESTROY:

PostQuitMessage(0);

return 0;

}

return(DefWindowProc(hWnd,iMessage,wParam,lParam));

}


LRESULT CALLBACK ChildWndProc1(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

LPCTSTR text = L"서울지역대학";


switch(message)

{

case WM_PAINT:

{

PAINTSTRUCT ps;

HDC hdc = BeginPaint(hWnd, &ps);

TextOut(hdc, 10, 10, text, lstrlen(text));

EndPaint(hWnd, &ps);

return 0;

}

case WM_CREATE:

{

// 차일드 윈도우에 버튼을 생성한다.

HWND hChildWnd = CreateWindow(

L"button", // 윈도우 클래스 이름

L"안내전화", // 윈도우 타이틀

WS_CHILD | WS_VISIBLE, // 윈도우 스타일

30, // 윈도우 보일 때 x좌표

50, // 윈도우 보일 때 y좌표

80, // 윈도우 폭

30, // 윈도우 높이

hWnd, // 부모 윈도우

(HMENU)ID_TEL_BTN, // 컨트롤 ID

g_hInst, // 인스턴스 핸들

(LPVOID)NULL); // 여분의 데이터

if (!hChildWnd)

return -1;

return 0;

case WM_COMMAND:

{

if (LOWORD(wParam) == ID_TEL_BTN)

{

MessageBox(hWnd, L"서울지역대학 전화 02-8403-725", L"지역대학 전화", MB_OK);

}

return 0;

}

}

return DefWindowProc(hWnd, message, wParam, lParam);

}


LRESULT CALLBACK ChildWndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

LPCTSTR text = L"컴퓨터과학과";


switch (message)

{

case WM_PAINT:

{

PAINTSTRUCT ps;

HDC hdc = BeginPaint(hWnd, &ps);

TextOut(hdc, 10, 10, text, lstrlen(text));

EndPaint(hWnd, &ps);

return 0;

}

}

return DefWindowProc(hWnd, message, wParam, lParam);

}


윈도우 프로그래밍은 한번도 접해보지 않은 분이라면 눈이 핑핑 돌 수도 있는데, 자연스러운 현상입니다. 저도 그랬어요. 



(2) 출력결과



네! 완성된 모습입니다. 위의 소스코드를 실행하고 학번 버튼을 누르면 이런 모습이 나와요. 학번 뒷자리 0101010에 이름 피타칩스 보이시나요?


어렵게 만들어낸 결과물이 좀 조잡해서 아쉬웠지만, 나름 유익하고 보람있는 과제였던거 같아요. 흥미가 생긴다면 Visual C++ 한번 수강해보세요 ㅎ



공감♥은 제게 큰 힘이 됩니다 감사합니다.


댓글