본문 바로가기
핵심 API로 배우는 윈도우 프로그래밍

핵심 API로 배우는 윈도우 프로그래밍 연습문제 2장 9번

by 딴짓거리 2022. 9. 22.

윈도우를 생성하는 WinMain 함수의 코드는 전부 중복이므로

WndProc 함수만 적는다.

 

작성자 본인이 공부 중 푼 문제로 모범답안이 아님을 밝힙니다.

 

8. 화면 하단 중앙에 문자열을 한 행 받을 수 있는 글상자를 배치

사각형에는 캐럿이 있어야 함.  사용자는

"Ellipse(int, int, int, int)"

"Line(int, int, int, int)"

"Rectangle(int, int, int, int)"

의 세가지 서식의 문자열을 입력하며

각각의 결과물은 위 문자열의 정수들을 좌표로 하는 도형이다.

 

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)	//메시지 처리 함수
{
	HDC				hdc;
	PAINTSTRUCT		ps;
	static TCHAR	str[1000];
	static int		pos_array[4]; // 입력받은 문자열을 정수로 바꿔 저장할 배열
	static int		count;
	static SIZE		size;
	static int		FLAG; // 그릴 도형을 나타내는 플래그
	
	switch (iMsg)
	{
	case WM_CREATE:
		CreateCaret(hwnd, NULL, 5, 15);
		ShowCaret(hwnd);
		count = 0;
		FLAG = -1; 
		break;
	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);
		GetTextExtentPoint(hdc, str, _tcslen(str), &size);
		Rectangle(hdc, 5, 330, 300, 354); // 문자열을 입력받을 장소의 사각형
		TextOut(hdc, 5, 332, str, _tcslen(str));
		SetCaretPos(size.cx + 5, 332);

		if (FLAG == 0) // 원
		{
			Ellipse(hdc, pos_array[0], pos_array[1], pos_array[2], pos_array[3]);
		}
		else if (FLAG == 1) // 선
		{
			MoveToEx(hdc, pos_array[0], pos_array[1],NULL);
			LineTo(hdc, pos_array[2], pos_array[3]);
		}
		else if (FLAG == 2) // 사각형
		{
			Rectangle(hdc, pos_array[0], pos_array[1], pos_array[2], pos_array[3]);
		}
		EndPaint(hwnd, &ps);
		break;
	case WM_CHAR:
		hdc = GetDC(hwnd);
		if (wParam == VK_BACK && count > 0) count--;
		else if (wParam == VK_RETURN)
		{
			if (_tcsstr(str, _T("Ellipse"))) // 문자열에 ~도형을 나타내는 단어를 검색
			{
				FLAG = 0;
				// _stscanf로 일정한 서식의 문자열 내의 필요한 값을 추출
				_stscanf(str, _T("Ellipse(%d, %d, %d, %d)"), &pos_array[0], &pos_array[1], &pos_array[2], &pos_array[3]);
			}
			else if (_tcsstr(str, _T("Line")))
			{
				FLAG = 1;
				_stscanf(str, _T("Line(%d, %d, %d, %d)"), &pos_array[0], &pos_array[1], &pos_array[2], &pos_array[3]);
			}
			else if (_tcsstr(str, _T("Rectangle")))
			{
				FLAG = 2;
				_stscanf(str, _T("Rectangle(%d, %d, %d, %d)"), &pos_array[0], &pos_array[1], &pos_array[2], &pos_array[3]);
			}


		}
		else str[count++] = wParam;
		str[count] = NULL;
		InvalidateRgn(hwnd, NULL, TRUE);
		break;
	case WM_DESTROY:
		HideCaret(hwnd);
		DestroyCaret();
		PostQuitMessage(0);
		break;
	}	//처리할 메시지만 case문에 나열
	return DefWindowProc(hwnd, iMsg, wParam, lParam);	//나머지는 커널이 처리
}

C언어로 문자열 내의 정수를 뽑아낸다는 처리를 어떻게 해야할지 엄청나게 고민했다

수시간동안 뒤진끝에 sscanf 를 찾아냈고 그것의 TCHAR 버전인 _stscanf 함수의 존재를 발견했다.

일정한 서식이 있는 문자열 내에서 필요한 문자열을 뽑아낼 수 있게 해주는 편리한 함수이다.

물론 사용자가 한글자라도 서식에서 벗어난 문자열을 입력하면 먹통이 된다.

 

그 뒤는 FLAG를 이용하여 어떤 도형을 그려줘야할지 WM_PAINT로 전달해줬는데 그 이상의 깔끔한 처리는 내머리로는 생각 할 수 없었다.

입력하는데로 잘 나온다.

 

 

중간에 답을 볼까 심각하게 고민했지만 온 인터넷을 다 뒤져봐도 본 9번문제는 푼사람도 없고 풀이를 올린사람도 없었기에 결국 직접 풀어서 올리게 되었다.