윈도우를 생성하는 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번문제는 푼사람도 없고 풀이를 올린사람도 없었기에 결국 직접 풀어서 올리게 되었다.
'핵심 API로 배우는 윈도우 프로그래밍' 카테고리의 다른 글
[windowAPI] 마우스 클릭&드래그로 고무줄 직선 그리기 (2) | 2022.09.24 |
---|---|
[windowAPI] 마우스 클릭이벤트 & 드래그 이벤트 (0) | 2022.09.23 |
핵심 API로 배우는 윈도우 프로그래밍 연습문제 2장 7, 8 (2) | 2022.09.22 |
핵심 API로 배우는 윈도우 프로그래밍 연습문제 2장 4~6 (0) | 2022.09.19 |
핵심 API로 배우는 윈도우 프로그래밍 연습문제 2장 1~3 (2) | 2022.09.19 |