핵심 API로 배우는 윈도우 프로그래밍

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

딴짓거리 2022. 9. 22. 02:30

윈도우를 생성하는 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번문제는 푼사람도 없고 풀이를 올린사람도 없었기에 결국 직접 풀어서 올리게 되었다.