Home > Blockchain >  GetLastError returns 998 when CreateWindow failed and returns 0
GetLastError returns 998 when CreateWindow failed and returns 0

Time:03-27

In main.cpp:

#include "window.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    Window main_window(hInstance, nCmdShow);
    main_window.Intitialize(CS_HREDRAW, NULL, LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW), (WIDE_CHAR) "Application", (WIDE_CHAR) "WindowName");
    return main_window.Show();
}

In window.h:

#include <stdio.h>

#ifndef _WINDOW_H_
    #define _WINDOW_H_

#include <windows.h>

typedef wchar_t* WIDE_CHAR;
typedef HINSTANCE INSTANCE;
typedef HWND HANDLE_WINDOW;
typedef tagWNDCLASSEXW WINDOW_CLASS;

LRESULT Procedure(HANDLE_WINDOW, UINT, WPARAM, LPARAM);

class Window {
  private:
    INSTANCE instance;
    int show_command;
    WINDOW_CLASS window_object;
    HANDLE_WINDOW handle;

  public:
    Window(INSTANCE instance, int show_command) {
        this->instance = instance;
        this->show_command = show_command;
    }

    void Intitialize(UINT style, HICON icon, HCURSOR cursor, HBRUSH background, WIDE_CHAR class_name, WIDE_CHAR title) {
        window_object.cbSize = sizeof(WINDOW_CLASS);
        window_object.cbClsExtra = 0;
        window_object.cbWndExtra = 0;
        window_object.hInstance = instance;
        window_object.lpfnWndProc = Procedure;

        window_object.style = style;
        window_object.hIcon = icon;
        window_object.hCursor = cursor;
        window_object.hbrBackground = background;
        window_object.lpszMenuName = NULL;
        window_object.lpszClassName = class_name;
        window_object.hIconSm = NULL;

        RegisterClassExW(&window_object);
        printf("%lld", GetLastError());

        handle = CreateWindowExW(WS_EX_CLIENTEDGE, class_name, title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1080, 720, NULL, NULL, instance, NULL);
    }

    int Show() {
        ShowWindow(handle, show_command);
        UpdateWindow(handle);

        MSG message;
        while (GetMessageW(&message, NULL, 0, 0)) {
            TranslateMessage(&message);
            DispatchMessageW(&message);
        }

        return message.wParam;
    }
};

LRESULT Procedure(HANDLE_WINDOW handle, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
        case WM_CLOSE:
            DestroyWindow(handle);
            break;

        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(handle, message, wParam, lParam);
            break;
    }
    return 0;
}

#endif

I tried to wrap the Win32 interface and tried to make a window, but I always got stuck in some weird places, like the Unicode...

First of all, I can't fully understand the use and conversion of wide characters. I think a large part of the reason for the failure of window registration and window creation is in the use of wide and normal characters. Secondly, I don't understand why I can't use the namespace "std", once I use it, even window registration fails.

CodePudding user response:

You are passing (WIDE_CHAR) "Application" and (WIDE_CHAR) "WindowName" to Intitialize.

As you defined

typedef wchar_t* WIDE_CHAR;

the parameters are NARROW characters cast to WIDE characters. When CreateWindowExW tries to access them, it goes out-of-bounds (because wide string is twice as long as narrow), resulting in error:

ERROR_NOACCESS

998 (0x3E6)

Invalid access to memory location.

according to https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--500-999-

Do this instead:

main_window.Intitialize(CS_HREDRAW, NULL, LoadCursor(NULL, IDC_ARROW), 
    (HBRUSH)(COLOR_WINDOW), L"Application", L "WindowName");
  • Related