0
votes

I have successfully opened a win32 window(without OpenGL context). Opening the window, then resizing it causes a lot of issues. How do we properly handle resizing inside the win32 api? I create a window with WS_OVERLAPPEDWINDOW and making the window resizable. Mainly, I attempt to handle the resizing with the WM_SIZE event handler.

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);
        
    }
}
2
for what you call SetWindowPos on WM_SIZE ? this is mistake. and not need WM_PAINT post. call InvalidateRect instead. but usually we need handle WM_SIZE if we need move child windows (we are "frame")or recreate bitmaps, etc.. in your case you not need handle WM_SIZE at all. comment your case WM_SIZE: and seeRbMm
You can find many sample of the web: developer.microsoft.com/en-us/windows/samples. Win32 API is low level so starting either with a book or a sample will give you a huge start. You should also be able to find samples specific for OpenGL that already have the basic...Phil1970

2 Answers

1
votes

Check this out: Resize window with Win32 API

In your WM_PAINT handler, it's possible that your getting that strange result because you aren't calling the FillRect function.

    case WM_PAINT:
       PAINTSTRUCT ps;
       HDC hdc = BeginPaint(m_hwnd, &ps);
       FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 6));
       EndPaint(m_hwnd, &ps);
0
votes

The problem in the screenshot (black background) is because you have not set the hbrBackground member of the window class. According to the document:

When this member is NULL, an application must paint its own background whenever it is requested to paint in its client area. To determine whether the background must be painted, an application can either process the WM_ERASEBKGND message or test the fErase member of the PAINTSTRUCT structure filled by the BeginPaint function.

Like the answer of @Stra, use FillRect to fill the background.

Or initialize 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);

Then you don’t need to process the WM_SIZE message.

In addition, you don’t need to call GetKeyState to get the VK_RMENU key Presse event, just process the WM_SYSKEYDOWN message and Indicates whether the key is an extended key:

/*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;