Я успешно открыл окно win32 (без контекста OpenGL). Открытие окна, а затем изменение его размера вызывает множество проблем. Как правильно обрабатывать изменение размера внутри win32 api? Я создаю окно с помощью WS_OVERLAPPEDWINDOW и изменяю размер окна. В основном я пытаюсь обрабатывать изменение размера с помощью обработчика событий WM_SIZE.

Image of C++ issue resizing

#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <iostream>
using namespace std;
HINSTANCE hInstanceGlobal;
LRESULT CALLBACK wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    PAINTSTRUCT ps;
    switch (message) {
    default:
        return DefWindowProcA(hWnd, message, wParam, lParam);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    case WM_PAINT:
        BeginPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        return 0;

    case WM_SIZE:
        SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
        PostMessage(hWnd, WM_PAINT, 0, 0);
        return 0;
    case WM_KEYDOWN:
        
        break;
    case WM_SETCURSOR:
        if (LOWORD(lParam) == HTCLIENT) {
            SetCursor(LoadCursor(NULL, IDC_ARROW));
            return TRUE;
        }
        break;
    }

    return DefWindowProcA(hWnd, message, wParam, lParam);
    
}
int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR     lpCmdLine,
    int       nShowCmd) {

#ifdef _DEBUG
    AllocConsole();
    //SetWindowPos(GetConsoleWindow(), 0, 1920, 200, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
    AttachConsole(GetCurrentProcessId());
    freopen("CON", "w", stdout);
    
#endif  
    hInstanceGlobal = hInstance;
    const char* CLASSNAME = "APIOPENGL";
    WNDCLASS cl = { };
    cl.lpfnWndProc = wndproc;
    cl.hCursor = LoadCursor(NULL, IDC_ARROW);
    cl.hInstance = hInstance;
    cl.lpszClassName = CLASSNAME;
    
    RegisterClass(&cl);

    HWND hWnd = CreateWindowEx(
        WS_EX_APPWINDOW|WS_EX_CLIENTEDGE,
        CLASSNAME,
        "Opengl Window",
        WS_OVERLAPPEDWINDOW |WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );
    if (hWnd == NULL)
    {
        return 0;
    }
    ShowWindow(hWnd, nShowCmd);

    MSG msg;
    MessageBox(NULL, (char*)GetLastError(), "Hello", NULL);
    bool bRet;
    while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
        
        if (GetKeyState(VK_RMENU) & 0x8000)
        {
            cout << "Pressed" << endl;
        }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        
    }
}
0
dudewritecodde 6 Янв 2021 в 03:14

2 ответа

Лучший ответ

Проблема на снимке экрана (черный фон) заключается в том, что вы не установили член hbrBackground класса окна. Согласно документу :

Когда этот член равен NULL , приложение должно нарисовать свой собственный background всякий раз, когда его просят нарисовать в своей клиентской области. Чтобы определить, нужно ли раскрашивать фон, приложение может либо обработать сообщение WM_ERASEBKGND, либо протестируйте fErase член PAINTSTRUCT структура, заполненная Функция BeginPaint .

Как и в случае с @Stra, используйте FillRect, чтобы заполнить фон.

Или инициализируйте hbrBackground:

hInstanceGlobal = hInstance;
const char CLASSNAME[] = "APIOPENGL";
WNDCLASS cl = { };
cl.lpfnWndProc = wndproc;
cl.hCursor = LoadCursor(NULL, IDC_ARROW);
cl.hInstance = hInstance;
cl.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
cl.lpszClassName = CLASSNAME;

RegisterClass(&cl);

Тогда вам не нужно обрабатывать сообщение WM_SIZE.

Кроме того, вам не нужно вызывать GetKeyState, чтобы получить событие нажатия клавиши VK_RMENU, просто обработайте сообщение WM_SYSKEYDOWN и укажите, является ли ключ расширенным:

/*case WM_SIZE:
    SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
    PostMessage(hWnd, WM_PAINT, 0, 0);
    return 0;*/
case WM_SYSKEYDOWN:
    if (VK_MENU == wParam)
    {
        BOOL bit = (lParam >> 24) & 1;
        if (bit)
            cout << "Pressed" << endl;
    }
    return 0;
0
Drake Wu - MSFT 6 Янв 2021 в 03:33

Проверьте это: Изменение размера окна с помощью Win32 API

В вашем обработчике WM_PAINT возможно, что вы получили такой странный результат, потому что вы не вызываете функцию FillRect.

    case WM_PAINT:
       PAINTSTRUCT ps;
       HDC hdc = BeginPaint(m_hwnd, &ps);
       FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 6));
       EndPaint(m_hwnd, &ps);
1
Stra 6 Янв 2021 в 01:50