윈도우 api 질문

조회수 501회

키보드 메시지를 처리하는 문제 중 enter 키 입력에 따른 처리에 대한 코드를 실행했는데 결과가 조금 다르게 나옵니다. enter 키 입력 시 줄바꿈을 하긴 하나 이전의 입력들이 다 사라지는데 왜 이런건가요? 어떻게 하면 이전의 입력들을 유지하며 줄바꿈을 하나요? str 배열 변수를 static으로 선언했으니까 저장한 내용들이 유지가 되어야하는거 아닌가요??

#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_APPLICATION);

    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);     // 커서 지정

    WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.lpszMenuName = NULL;
    WndClass.lpszClassName = _T("Window Class Name");
    RegisterClass(&WndClass);
    hwnd = CreateWindow(_T("Window Class Name"),
        _T("Window Title Name"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        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[100];
    static int count, yPos;

    switch (iMsg)
    {
    case WM_CREATE:
        yPos = 0;
        count = 0;
        break;

    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);
        TextOut(hdc, 0, yPos, str, _tcslen(str));
        EndPaint(hwnd, &ps);
        break;

    case WM_CHAR:

        if (wParam == VK_RETURN) {
            yPos = yPos + 20;
            count = 0;
        }
        else 
            str[count++] = wParam;

        str[count] = NULL;

        InvalidateRgn(hwnd, NULL, TRUE);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 문제는 InvalidateRgn 함수를 사용하고 있고, 그 함수의 두번째 인수로 NULL을 넣었기 때문에 화면전체가 갱신되기 때문입니다. 화면 전체가 갱신되면서 이전 값이 지워지고, 그 후 TextOut함수로 한줄을 새로 쓴겁니다.

    TextOut함수는 한줄만 쓸수 있는 반면에, DrawText함수는 여러줄을 한번에 쓸수 있습니다.

    해결방법은 다양하게 있습니다. 그리고 현재 코드에는 문제가 많습니다.

    어쨋든 질문한 것을 해결하려면 아래와 같이 수정하시면 됩니다.

    • 코드
    #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_APPLICATION);
    
        WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);     // 커서 지정
    
        WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        WndClass.lpszMenuName = NULL;
        WndClass.lpszClassName = _T("Window Class Name");
        RegisterClass(&WndClass);
        hwnd = CreateWindow(_T("Window Class Name"),
            _T("Window Title Name"),
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            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[100] = { 0 };
        static int count, yPos;
        RECT rect{ 0,0,300,300 };
    
        switch (iMsg)
        {
        case WM_CREATE:
            yPos = 0;
            count = 0;
            break;
    
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
            DrawText(hdc, str, _tcslen(str), &rect, DT_LEFT | DT_EXTERNALLEADING | DT_WORDBREAK);
            EndPaint(hwnd, &ps);
            break;
    
        case WM_CHAR:
    
            if (wParam == VK_RETURN) {
                str[count++] = '\n';
            }
            else
                str[count++] = wParam;
    
            str[count] = NULL;
    
            InvalidateRgn(hwnd, NULL, TRUE);
            break;
    
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        }
        return DefWindowProc(hwnd, iMsg, wParam, lParam);
    }
    
    • 결과

    이미지

    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)