window에서 키보드 입력을 받을때 문자는 유니코드 혹은 아스키코드로 받는다지만
엔터키등의 특수키는 VK 라는 가상키로 입력받게 된다.
단순히 문자만 출력해주는 처리로는 당연히 줄바꿈이나 백스페이스를 처리 할 수 없고
알 수 없는 오류 문자가 출력되게 된다.
또한 입력받은 문자를 적절히 처리하지 않으면 윈도우의 (0,0) 지점에서 한개의 문자만 계속해서 바뀌는 상태가 된다
그리고 윈도우를 최소화 했다가 다시 켜보면 작성한 문자가 깨끗하게 날아간 것을 볼 수 있다.
아래는 우리가 처리해야 할 것이다.
1. 줄바꿈(VK_RETURN)과 백스페이스(VK_BACK) 입력을 일반 문자입력과 다르게 처리해준다
2. 입력받은 문자를 배열에 저장해서 계속해서 전체를 출력해준다
3. 창이 최소화 되면 WM_PAINT가 화면을 깨끗하게 날려버리므로
해당하는 처리를 따로 생각해줄 것
#include <windows.h>
#include <TCHAR.H>
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS WndClass;
WndClass.style = CS_HREDRAW | CS_VREDRAW;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_QUESTION); //윈도우 아이콘
WndClass.hCursor = LoadCursor(NULL, IDC_IBEAM); //커서 모양
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //배경 색
WndClass.lpszMenuName = NULL; //메뉴 이름
WndClass.lpszClassName = _T("Window Class Name"); //윈도우 클래스 이름
RegisterClass(&WndClass);
hwnd = CreateWindow(_T("Window Class Name"),
_T("Cobaltbru's First Window"), //윈도우 타이틀 이름
WS_OVERLAPPEDWINDOW, //윈도우 스타일
200, //윈도우 위치 X
300, //윈도우 위치 Y
600, //윈도우 가로
400, //윈도우 세로
NULL,
NULL,
hInstance,
NULL
);
ShowWindow(hwnd, nCmdShow); //윈도우 기본 출력 함수
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) //메시지 처리 함수
{
HDC hdc;
PAINTSTRUCT ps;
static TCHAR str[1000];
static int count, yPos;
RECT rt = { 0,0,1000,1000 };
switch (iMsg)
{
case WM_CREATE:
count = 0;
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
DrawText(hdc, str, _tcslen(str), &rt, DT_TOP | DT_LEFT); //문자열을 출력해준다. 엔터키를 인식해 줄바꿈을 처리해준다
EndPaint(hwnd, &ps);
break;
case WM_CHAR:
if (wParam == VK_BACK && count > 0) count--;
else str[count++] = wParam; // 문자를 저장한 후 count 를 1늘리고
str[count] = NULL; // NULL로 초기화
InvalidateRgn(hwnd, NULL, TRUE); //즉시 WM_PAINT를 호출
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
} //처리할 메시지만 case문에 나열
return DefWindowProc(hwnd, iMsg, wParam, lParam); //나머지는 커널이 처리
}
위의 코드는 모든 경우를 처리해준 코드다.
문자를 출력하는데 TextOut을 쓰지 않고 DrawText 를 쓴 이유는
TextOut은 직접 y좌표의 커서를 이동시켜줘야 되고
문자열을 저장할 배열을 2차원 배열로 만들어 줘야 된다.
하지만 DrawText는 1차원 배열에 저장된 문자열에서 개행문자를 읽어
자동으로 줄바꿈 처리를 해준다.
단순한 문자열의 출력에도 꽤나 생각해야 할 부분이 많다.
'핵심 API로 배우는 윈도우 프로그래밍' 카테고리의 다른 글
핵심 API로 배우는 윈도우 프로그래밍 연습문제 2장 1~3 (2) | 2022.09.19 |
---|---|
윈도우에 그림 그리기 (0) | 2022.09.18 |
캐럿 생성하기 (0) | 2022.09.18 |
윈도우 창 생성 기본 (0) | 2022.09.14 |
들어가며 (0) | 2022.09.14 |