RegisterClassA winuser.h

Tried various approaches, keeps failing at registering my WNDCLASSA. Prefer not to use any external libraries to begin with. here where my code end up. else { const errorCode = win32.GetLastError(); print(“Error registering class: {d}\n”, .{errorCode}); } I suspect i need some other approach with lpfnWndProc = but im out of bubblegum and ideas.

As for the errormessage. Error registering class: os.windows.win32error.Win32Error.INVALID_PARAMETER

const std = @import("std");
const win32 = std.os.windows;
const print = std.debug.print;

pub fn wWinMain(instance: win32.HINSTANCE, hPrevInstance: ?win32.HINSTANCE, lpCmdLine: [*:0]u16, nCmdShow: i32) callconv(win32.WINAPI) i32 {
    _ = hPrevInstance;
    _ = lpCmdLine;
    _ = nCmdShow;

    const CS_CLASSDC = 0x0040;
    const CS_HREDRAW = 0x0002;
    const CS_VREDRAW = 0x0001;

    const className: [*c]const u8 = "BengtsBullar";

    var w: WNDCLASSA = undefined;
    w.lpfnWndProc = @ptrCast(@constCast(&mainWindowCallback));
    w.style = CS_CLASSDC | CS_HREDRAW | CS_VREDRAW;
    w.hInstance = instance;
    w.lpszClassName = className;
    w.lpszMenuName = className;
    w.cbClsExtra = 0;
    w.cbWndExtra = 0;

    const cid = RegisterClassA(&w);

    if (cid != 0) {
        print("yes.\n", .{});
    } else {
        const errorCode = win32.GetLastError();
        print("Error registering class: {d}\n", .{errorCode});
    }

    return 0;
}

const WNDCLASSA = extern struct {
    style: win32.DWORD,
    lpfnWndProc: win32.PROC,
    cbClsExtra: win32.INT,
    cbWndExtra: win32.INT,
    hInstance: win32.HINSTANCE,
    //hIcon: win32.HICON,
    //hCursor: win32.HCURSOR,
    //hbrBackground: win32.HBRUSH,
    lpszMenuName: ?*const u8,
    lpszClassName: ?*const u8,
};

extern "user32" fn RegisterClassA(class: [*c]const WNDCLASSA) callconv(win32.WINAPI) win32.ATOM;

extern "user32" fn DefWindowProcA(hWnd: win32.HWND, Msg: win32.UINT, wParam: win32.WPARAM, lParam: win32.LPARAM) win32.LRESULT;

pub fn mainWindowCallback(window: win32.HWND, message: win32.UINT, wParam: win32.WPARAM, lParam: win32.LPARAM) callconv(win32.WINAPI) win32.LRESULT {
    return DefWindowProcA(window, message, wParam, lParam);
}

It worked correctly in my case :slight_smile:
But I am cross compiling and run using wine on linux.

❯ zig-dev build-exe test.zig -target x86_64-windows
❯ wine test.exe
yes.

The missing fields in WNDCLASSA are the problem:

    hIcon: win32.HANDLE,
    hCursor: win32.HANDLE,
    hbrBackground: win32.HANDLE,

You can use HANDLE and you must initialize the fields to null.

    w.hIcon = null;
    w.hCursor = null;
    w.hbrBackground = null;

thank you! :100: this did the trick.

i had to do with ?
hIcon: ?win32.HANDLE,

and so on.
otherwise getting error: expected type ‘*anyopaque’, found ‘@TypeOf(null)’
w.hIcon = null;

1 Like

FWIW using A version APIs are problematic in modern Windows. Fine for learning basics and personal/toy programs, but not if you’re wanting an app for general use. Windows is fundamentally a W platform (like it or not), and you’ll eventually run into intractable issues using the A APIs. Some areas of functionality are hamstrung in A versions, and you run into codepage-dependent issues with text input and display.

1 Like