From fcf3f61c287eb07a5a9587c6fc3d4c7aa47def11 Mon Sep 17 00:00:00 2001 From: Aransentin Date: Sun, 22 Nov 2020 13:00:57 +0000 Subject: [PATCH 1/4] user32 cleanup, added wrappers and additional functions --- lib/std/os/windows/bits.zig | 13 + lib/std/os/windows/kernel32.zig | 1 + lib/std/os/windows/user32.zig | 708 +++++++++++++++++++++++++++----- 3 files changed, 617 insertions(+), 105 deletions(-) diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index fa98d15b1932..edd137b6c158 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -37,6 +37,7 @@ pub const UCHAR = u8; pub const FLOAT = f32; pub const HANDLE = *c_void; pub const HCRYPTPROV = ULONG_PTR; +pub const ATOM = u16; pub const HBRUSH = *opaque {}; pub const HCURSOR = *opaque {}; pub const HICON = *opaque {}; @@ -770,6 +771,13 @@ pub const FILE_FLAG_SESSION_AWARE = 0x00800000; pub const FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000; pub const FILE_FLAG_WRITE_THROUGH = 0x80000000; +pub const RECT = extern struct { + left: LONG, + top: LONG, + right: LONG, + bottom: LONG, +}; + pub const SMALL_RECT = extern struct { Left: SHORT, Top: SHORT, @@ -777,6 +785,11 @@ pub const SMALL_RECT = extern struct { Bottom: SHORT, }; +pub const POINT = extern struct { + x: LONG, + y: LONG, +}; + pub const COORD = extern struct { X: SHORT, Y: SHORT, diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index 444234876c34..659dba53971d 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -115,6 +115,7 @@ pub extern "kernel32" fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u1 pub extern "kernel32" fn GetModuleHandleW(lpModuleName: ?[*:0]const WCHAR) callconv(WINAPI) ?HMODULE; pub extern "kernel32" fn GetLastError() callconv(WINAPI) Win32Error; +pub extern "kernel32" fn SetLastError(dwErrCode: Win32Error) callconv(WINAPI) void; pub extern "kernel32" fn GetFileInformationByHandle( hFile: HANDLE, diff --git a/lib/std/os/windows/user32.zig b/lib/std/os/windows/user32.zig index f4533faaa661..479ac8653245 100644 --- a/lib/std/os/windows/user32.zig +++ b/lib/std/os/windows/user32.zig @@ -4,45 +4,79 @@ // The MIT license requires this copyright notice to be included in all copies // and substantial portions of the software. usingnamespace @import("bits.zig"); +const std = @import("std"); +const builtin = @import("builtin"); +const assert = std.debug.assert; +const windows = @import("../windows.zig"); +const unexpectedError = windows.unexpectedError; +const GetLastError = windows.kernel32.GetLastError; +const SetLastError = windows.kernel32.SetLastError; -// PM -pub const PM_REMOVE = 0x0001; -pub const PM_NOREMOVE = 0x0000; -pub const PM_NOYIELD = 0x0002; +fn selectSymbol(comptime function_static: anytype, function_dynamic: anytype, comptime os: std.Target.Os.WindowsVersion) @TypeOf(function_static) { + comptime { + const sym_ok = builtin.Target.current.os.isAtLeast(.windows, os); + if (sym_ok == true) return function_static; + if (sym_ok == null) return function_dynamic; + if (sym_ok == false) @compileError("Target OS range does not support function, at least " ++ @tagName(os) ++ " is required"); + } +} + +// === Messages === + +pub const WNDPROC = fn (hwnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM) callconv(WINAPI) LRESULT; + +pub const MSG = extern struct { + hWnd: ?HWND, + message: UINT, + wParam: WPARAM, + lParam: LPARAM, + time: DWORD, + pt: POINT, + lPrivate: DWORD, +}; -// WM pub const WM_NULL = 0x0000; pub const WM_CREATE = 0x0001; pub const WM_DESTROY = 0x0002; +pub const WM_NCDESTROY = WM_DESTROY; pub const WM_MOVE = 0x0003; pub const WM_SIZE = 0x0005; - pub const WM_ACTIVATE = 0x0006; -pub const WM_PAINT = 0x000F; -pub const WM_CLOSE = 0x0010; -pub const WM_QUIT = 0x0012; pub const WM_SETFOCUS = 0x0007; - pub const WM_KILLFOCUS = 0x0008; pub const WM_ENABLE = 0x000A; pub const WM_SETREDRAW = 0x000B; - -pub const WM_SYSCOLORCHANGE = 0x0015; +pub const WM_SETTEXT = 0x000C; +pub const WM_GETTEXT = 0x000D; +pub const WM_GETTEXTLENGTH = 0x000E; +pub const WM_PAINT = 0x000F; +pub const WM_CLOSE = 0x0010; +pub const WM_QUIT = 0x0012; +pub const WM_ERASEBKGND = 0x0014; pub const WM_SHOWWINDOW = 0x0018; - -pub const WM_WINDOWPOSCHANGING = 0x0046; +pub const WM_CTLCOLOR = 0x0019; +pub const WM_NEXTDLGCTL = 0x0028; +pub const WM_DRAWITEM = 0x002B; +pub const WM_MEASUREITEM = 0x002C; +pub const WM_DELETEITEM = 0x002D; +pub const WM_VKEYTOITEM = 0x002E; +pub const WM_CHARTOITEM = 0x002F; +pub const WM_SETFONT = 0x0030; +pub const WM_GETFONT = 0x0031; +pub const WM_COMPAREITEM = 0x0039; pub const WM_WINDOWPOSCHANGED = 0x0047; -pub const WM_POWER = 0x0048; - -pub const WM_CONTEXTMENU = 0x007B; -pub const WM_STYLECHANGING = 0x007C; -pub const WM_STYLECHANGED = 0x007D; -pub const WM_DISPLAYCHANGE = 0x007E; -pub const WM_GETICON = 0x007F; -pub const WM_SETICON = 0x0080; - -pub const WM_INPUT_DEVICE_CHANGE = 0x00fe; -pub const WM_INPUT = 0x00FF; +pub const WM_NOTIFY = 0x004E; +pub const WM_NCCALCSIZE = 0x0083; +pub const WM_NCHITTEST = 0x0084; +pub const WM_NCPAINT = 0x0085; +pub const WM_GETDLGCODE = 0x0087; +pub const WM_NCMOUSEMOVE = 0x00A0; +pub const WM_NCLBUTTONDOWN = 0x00A1; +pub const WM_NCLBUTTONUP = 0x00A2; +pub const WM_NCLBUTTONDBLCLK = 0x00A3; +pub const WM_NCRBUTTONDOWN = 0x00A4; +pub const WM_NCRBUTTONUP = 0x00A5; +pub const WM_NCRBUTTONDBLCLK = 0x00A6; pub const WM_KEYFIRST = 0x0100; pub const WM_KEYDOWN = 0x0100; pub const WM_KEYUP = 0x0101; @@ -52,13 +86,21 @@ pub const WM_SYSKEYDOWN = 0x0104; pub const WM_SYSKEYUP = 0x0105; pub const WM_SYSCHAR = 0x0106; pub const WM_SYSDEADCHAR = 0x0107; -pub const WM_UNICHAR = 0x0109; -pub const WM_KEYLAST = 0x0109; - +pub const WM_KEYLAST = 0x0108; +pub const WM_INITDIALOG = 0x0110; pub const WM_COMMAND = 0x0111; pub const WM_SYSCOMMAND = 0x0112; pub const WM_TIMER = 0x0113; - +pub const WM_HSCROLL = 0x0114; +pub const WM_VSCROLL = 0x0115; +pub const WM_ENTERIDLE = 0x0121; +pub const WM_CTLCOLORMSGBOX = 0x0132; +pub const WM_CTLCOLOREDIT = 0x0133; +pub const WM_CTLCOLORLISTBOX = 0x0134; +pub const WM_CTLCOLORBTN = 0x0135; +pub const WM_CTLCOLORDLG = 0x0136; +pub const WM_CTLCOLORSCROLLBAR = 0x0137; +pub const WM_CTLCOLORSTATIC = 0x0138; pub const WM_MOUSEFIRST = 0x0200; pub const WM_MOUSEMOVE = 0x0200; pub const WM_LBUTTONDOWN = 0x0201; @@ -71,105 +113,561 @@ pub const WM_MBUTTONDOWN = 0x0207; pub const WM_MBUTTONUP = 0x0208; pub const WM_MBUTTONDBLCLK = 0x0209; pub const WM_MOUSEWHEEL = 0x020A; -pub const WM_XBUTTONDOWN = 0x020B; -pub const WM_XBUTTONUP = 0x020C; -pub const WM_XBUTTONDBLCLK = 0x020D; +pub const WM_MOUSELAST = 0x020A; +pub const WM_HOTKEY = 0x0312; +pub const WM_CARET_CREATE = 0x03E0; +pub const WM_CARET_DESTROY = 0x03E1; +pub const WM_CARET_BLINK = 0x03E2; +pub const WM_FDINPUT = 0x03F0; +pub const WM_FDOUTPUT = 0x03F1; +pub const WM_FDEXCEPT = 0x03F2; +pub const WM_USER = 0x0400; -// WA -pub const WA_INACTIVE = 0; -pub const WA_ACTIVE = 0x0006; +pub extern "user32" fn GetMessageA(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) callconv(WINAPI) BOOL; +pub fn getMessageA(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: u32, wMsgFilterMax: u32) !void { + const r = GetMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); + if (r == 0) return error.Quit; + if (r != -1) return; + return switch (GetLastError()) { + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} -// WS -pub const WS_OVERLAPPED = 0x00000000; -pub const WS_CAPTION = 0x00C00000; -pub const WS_SYSMENU = 0x00080000; -pub const WS_THICKFRAME = 0x00040000; -pub const WS_MINIMIZEBOX = 0x00020000; -pub const WS_MAXIMIZEBOX = 0x00010000; +pub extern "user32" fn GetMessageW(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) callconv(WINAPI) BOOL; +pub var pfnGetMessageW: @TypeOf(GetMessageW) = undefined; +pub fn getMessageW(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: u32, wMsgFilterMax: u32) !void { + const function = selectSymbol(GetMessageW, pfnGetMessageW, .win2k); -// PFD -pub const PFD_DRAW_TO_WINDOW = 0x00000004; -pub const PFD_SUPPORT_OPENGL = 0x00000020; -pub const PFD_DOUBLEBUFFER = 0x00000001; -pub const PFD_MAIN_PLANE = 0; -pub const PFD_TYPE_RGBA = 0; + const r = function(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); + if (r == 0) return error.Quit; + if (r != -1) return; + return switch (GetLastError()) { + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} -// CS -pub const CS_HREDRAW = 0x0002; -pub const CS_VREDRAW = 0x0001; -pub const CS_OWNDC = 0x0020; +pub const PM_NOREMOVE = 0x0000; +pub const PM_REMOVE = 0x0001; +pub const PM_NOYIELD = 0x0002; -// SW -pub const SW_HIDE = 0; -pub const SW_SHOW = 5; +pub extern "user32" fn PeekMessageA(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT, wRemoveMsg: UINT) callconv(WINAPI) BOOL; +pub fn peekMessageA(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: u32, wMsgFilterMax: u32, wRemoveMsg: u32) !bool { + const r = PeekMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); + if (r == 0) return false; + if (r != -1) return true; + return switch (GetLastError()) { + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn PeekMessageW(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT, wRemoveMsg: UINT) callconv(WINAPI) BOOL; +pub var pfnPeekMessageW: @TypeOf(PeekMessageW) = undefined; +pub fn peekMessageW(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: u32, wMsgFilterMax: u32, wRemoveMsg: u32) !bool { + const function = selectSymbol(PeekMessageW, pfnPeekMessageW, .win2k); + + const r = function(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); + if (r == 0) return false; + if (r != -1) return true; + return switch (GetLastError()) { + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn TranslateMessage(lpMsg: *const MSG) callconv(WINAPI) BOOL; +pub fn translateMessage(lpMsg: *const MSG) bool { + return if (TranslateMessage(lpMsg) == 0) false else true; +} + +pub extern "user32" fn DispatchMessageA(lpMsg: *const MSG) callconv(WINAPI) LRESULT; +pub fn dispatchMessageA(lpMsg: *const MSG) LRESULT { + return DispatchMessageA(lpMsg); +} + +pub extern "user32" fn DispatchMessageW(lpMsg: *const MSG) callconv(WINAPI) LRESULT; +pub var pfnDispatchMessageW: @TypeOf(DispatchMessageW) = undefined; +pub fn dispatchMessageW(lpMsg: *const MSG) LRESULT { + const function = selectSymbol(DispatchMessageW, pfnDispatchMessageW, .win2k); + return function(lpMsg); +} -pub const WNDPROC = fn (HWND, UINT, WPARAM, LPARAM) callconv(WINAPI) LRESULT; +pub extern "user32" fn PostQuitMessage(nExitCode: i32) callconv(WINAPI) void; +pub fn postQuitMessage(nExitCode: i32) void { + PostQuitMessage(nExitCode); +} + +pub extern "user32" fn DefWindowProcA(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) callconv(WINAPI) LRESULT; +pub fn defWindowProcA(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) LRESULT { + return DefWindowProcA(hWnd, Msg, wParam, lParam); +} + +pub extern "user32" fn DefWindowProcW(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) callconv(WINAPI) LRESULT; +pub var pfnDefWindowProcW: @TypeOf(DefWindowProcW) = undefined; +pub fn defWindowProcW(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) LRESULT { + const function = selectSymbol(DefWindowProcW, pfnDefWindowProcW, .win2k); + return function(hWnd, Msg, wParam, lParam); +} + +// === Windows === + +pub const CS_VREDRAW = 0x0001; +pub const CS_HREDRAW = 0x0002; +pub const CS_DBLCLKS = 0x0008; +pub const CS_OWNDC = 0x0020; +pub const CS_CLASSDC = 0x0040; +pub const CS_PARENTDC = 0x0080; +pub const CS_NOCLOSE = 0x0200; +pub const CS_SAVEBITS = 0x0800; +pub const CS_BYTEALIGNCLIENT = 0x1000; +pub const CS_BYTEALIGNWINDOW = 0x2000; +pub const CS_GLOBALCLASS = 0x4000; pub const WNDCLASSEXA = extern struct { cbSize: UINT = @sizeOf(WNDCLASSEXA), style: UINT, lpfnWndProc: WNDPROC, - cbClsExtra: i32, - cbWndExtra: i32, + cbClsExtra: i32 = 0, + cbWndExtra: i32 = 0, hInstance: HINSTANCE, hIcon: ?HICON, hCursor: ?HCURSOR, hbrBackground: ?HBRUSH, - lpszMenuName: ?LPCSTR, - lpszClassName: LPCSTR, + lpszMenuName: ?[*:0]const u8, + lpszClassName: [*:0]const u8, hIconSm: ?HICON, }; -pub const POINT = extern struct { - x: c_long, y: c_long +pub const WNDCLASSEXW = extern struct { + cbSize: UINT = @sizeOf(WNDCLASSEXW), + style: UINT, + lpfnWndProc: WNDPROC, + cbClsExtra: i32 = 0, + cbWndExtra: i32 = 0, + hInstance: HINSTANCE, + hIcon: ?HICON, + hCursor: ?HCURSOR, + hbrBackground: ?HBRUSH, + lpszMenuName: ?[*:0]const u16, + lpszClassName: [*:0]const u16, + hIconSm: ?HICON, }; -pub const MSG = extern struct { - hWnd: ?HWND, - message: UINT, - wParam: WPARAM, - lParam: LPARAM, - time: DWORD, - pt: POINT, - lPrivate: DWORD, -}; +pub extern "user32" fn RegisterClassExA(*const WNDCLASSEXA) callconv(WINAPI) ATOM; +pub fn registerClassExA(window_class: *const WNDCLASSEXA) !ATOM { + const atom = RegisterClassExA(window_class); + if (atom != 0) return atom; + return switch (GetLastError()) { + .CLASS_ALREADY_EXISTS => error.AlreadyExists, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} -pub extern "user32" fn CreateWindowExA( - dwExStyle: DWORD, - lpClassName: LPCSTR, - lpWindowName: LPCSTR, - dwStyle: DWORD, - X: i32, - Y: i32, - nWidth: i32, - nHeight: i32, - hWindParent: ?HWND, - hMenu: ?HMENU, - hInstance: HINSTANCE, - lpParam: ?LPVOID, -) callconv(WINAPI) ?HWND; +pub extern "user32" fn RegisterClassExW(*const WNDCLASSEXW) callconv(WINAPI) ATOM; +pub var pfnRegisterClassExW: @TypeOf(RegisterClassExW) = undefined; +pub fn registerClassExW(window_class: *const WNDCLASSEXA) !ATOM { + const function = selectSymbol(RegisterClassExW, pfnRegisterClassExW, .win2k); + const atom = function(window_class); + if (atom != 0) return atom; + return switch (GetLastError()) { + .CLASS_ALREADY_EXISTS => error.AlreadyExists, + .CALL_NOT_IMPLEMENTED => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn UnregisterClassA(lpClassName: LPCSTR, hInstance: HINSTANCE) callconv(.Stdcall) BOOL; +pub fn unregisterClassA(lpClassName: [*:0]const u8, hInstance: HINSTANCE) !void { + if (UnregisterClassA(lpClassName, hInstance) == 0) { + return switch (GetLastError()) { + .CLASS_DOES_NOT_EXIST => error.ClassDoesNotExist, + else => |err| return windows.unexpectedError(err), + }; + } +} + +pub extern "user32" fn UnregisterClassW(lpClassName: LPCWSTR, hInstance: HINSTANCE) callconv(.Stdcall) BOOL; +pub var pfnUnregisterClassW: @TypeOf(UnregisterClassW) = undefined; +pub fn unregisterClassW(lpClassName: [*:0]const u16, hInstance: HINSTANCE) !void { + const function = selectSymbol(UnregisterClassW, pfnUnregisterClassW, .win2k); + if (function(lpClassName, hInstance) == 0) { + return switch (GetLastError()) { + .CLASS_DOES_NOT_EXIST => error.ClassDoesNotExist, + else => |err| return windows.unexpectedError(err), + }; + } +} + +pub const WS_OVERLAPPED = 0x00000000; +pub const WS_POPUP = 0x80000000; +pub const WS_CHILD = 0x40000000; +pub const WS_MINIMIZE = 0x20000000; +pub const WS_VISIBLE = 0x10000000; +pub const WS_DISABLED = 0x08000000; +pub const WS_CLIPSIBLINGS = 0x04000000; +pub const WS_CLIPCHILDREN = 0x02000000; +pub const WS_MAXIMIZE = 0x01000000; +pub const WS_CAPTION = WS_BORDER | WS_DLGFRAME; +pub const WS_BORDER = 0x00800000; +pub const WS_DLGFRAME = 0x00400000; +pub const WS_VSCROLL = 0x00200000; +pub const WS_HSCROLL = 0x00100000; +pub const WS_SYSMENU = 0x00080000; +pub const WS_THICKFRAME = 0x00040000; +pub const WS_GROUP = 0x00020000; +pub const WS_TABSTOP = 0x00010000; +pub const WS_MINIMIZEBOX = 0x00020000; +pub const WS_MAXIMIZEBOX = 0x00010000; +pub const WS_TILED = WS_OVERLAPPED; +pub const WS_ICONIC = WS_MINIMIZE; +pub const WS_SIZEBOX = WS_THICKFRAME; +pub const WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW; +pub const WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; +pub const WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU; +pub const WS_CHILDWINDOW = WS_CHILD; + +pub const WS_EX_DLGMODALFRAME = 0x00000001; +pub const WS_EX_NOPARENTNOTIFY = 0x00000004; +pub const WS_EX_TOPMOST = 0x00000008; +pub const WS_EX_ACCEPTFILES = 0x00000010; +pub const WS_EX_TRANSPARENT = 0x00000020; +pub const WS_EX_MDICHILD = 0x00000040; +pub const WS_EX_TOOLWINDOW = 0x00000080; +pub const WS_EX_WINDOWEDGE = 0x00000100; +pub const WS_EX_CLIENTEDGE = 0x00000200; +pub const WS_EX_CONTEXTHELP = 0x00000400; +pub const WS_EX_RIGHT = 0x00001000; +pub const WS_EX_LEFT = 0x00000000; +pub const WS_EX_RTLREADING = 0x00002000; +pub const WS_EX_LTRREADING = 0x00000000; +pub const WS_EX_LEFTSCROLLBAR = 0x00004000; +pub const WS_EX_RIGHTSCROLLBAR = 0x00000000; +pub const WS_EX_CONTROLPARENT = 0x00010000; +pub const WS_EX_STATICEDGE = 0x00020000; +pub const WS_EX_APPWINDOW = 0x00040000; +pub const WS_EX_LAYERED = 0x00080000; +pub const WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE); +pub const WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST); + +pub const CW_USEDEFAULT = @bitCast(i32, @as(u32, 0x80000000)); + +pub extern "user32" fn CreateWindowExA(dwExStyle: DWORD, lpClassName: [*:0]const u8, lpWindowName: [*:0]const u8, dwStyle: DWORD, X: i32, Y: i32, nWidth: i32, nHeight: i32, hWindParent: ?HWND, hMenu: ?HMENU, hInstance: HINSTANCE, lpParam: ?LPVOID) callconv(WINAPI) ?HWND; +pub fn createWindowExA(dwExStyle: u32, lpClassName: [*:0]const u8, lpWindowName: [*:0]const u8, dwStyle: u32, X: i32, Y: i32, nWidth: i32, nHeight: i32, hWindParent: ?HWND, hMenu: ?HMENU, hInstance: HINSTANCE, lpParam: ?*c_void) !HWND { + const window = CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWindParent, hMenu, hInstance, lpParam); + if (window) |win| return win; + + return switch (GetLastError()) { + .CLASS_DOES_NOT_EXIST => error.ClassDoesNotExist, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn CreateWindowExW(dwExStyle: DWORD, lpClassName: [*:0]const u16, lpWindowName: [*:0]const u16, dwStyle: DWORD, X: i32, Y: i32, nWidth: i32, nHeight: i32, hWindParent: ?HWND, hMenu: ?HMENU, hInstance: HINSTANCE, lpParam: ?LPVOID) callconv(WINAPI) ?HWND; +pub var pfnCreateWindowExW: @TypeOf(RegisterClassExW) = undefined; +pub fn createWindowExW(dwExStyle: u32, lpClassName: [*:0]const u16, lpWindowName: [*:0]const u16, dwStyle: u32, X: i32, Y: i32, nWidth: i32, nHeight: i32, hWindParent: ?HWND, hMenu: ?HMENU, hInstance: HINSTANCE, lpParam: ?*c_void) !HWND { + const function = selectSymbol(CreateWindowExW, pfnCreateWindowExW, .win2k); + const window = function(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWindParent, hMenu, hInstance, lpParam); + if (window) |win| return win; + + return switch (GetLastError()) { + .CLASS_DOES_NOT_EXIST => error.ClassDoesNotExist, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn DestroyWindow(hWnd: HWND) callconv(WINAPI) BOOL; +pub fn destroyWindow(hWnd: HWND) !void { + if (DestroyWindow(hWnd) == 0) { + return switch (GetLastError()) { + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; + } +} + +pub const SW_HIDE = 0; +pub const SW_SHOWNORMAL = 1; +pub const SW_NORMAL = 1; +pub const SW_SHOWMINIMIZED = 2; +pub const SW_SHOWMAXIMIZED = 3; +pub const SW_MAXIMIZE = 3; +pub const SW_SHOWNOACTIVATE = 4; +pub const SW_SHOW = 5; +pub const SW_MINIMIZE = 6; +pub const SW_SHOWMINNOACTIVE = 7; +pub const SW_SHOWNA = 8; +pub const SW_RESTORE = 9; +pub const SW_SHOWDEFAULT = 10; +pub const SW_FORCEMINIMIZE = 11; +pub const SW_MAX = 11; + +pub extern "user32" fn ShowWindow(hWnd: HWND, nCmdShow: i32) callconv(WINAPI) BOOL; +pub fn showWindow(hWnd: HWND, nCmdShow: i32) bool { + return (ShowWindow(hWnd, nCmdShow) == TRUE); +} + +pub extern "user32" fn UpdateWindow(hWnd: HWND) callconv(WINAPI) BOOL; +pub fn updateWindow(hWnd: HWND) !void { + if (ShowWindow(hWnd, nCmdShow) == 0) { + return switch (GetLastError()) { + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; + } +} + +pub extern "user32" fn AdjustWindowRectEx(lpRect: *RECT, dwStyle: DWORD, bMenu: BOOL, dwExStyle: DWORD) callconv(WINAPI) BOOL; +pub fn adjustWindowRectEx(lpRect: *RECT, dwStyle: u32, bMenu: bool, dwExStyle: u32) !void { + assert(dwStyle & WS_OVERLAPPED == 0); + + if (AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle) == 0) { + return switch (GetLastError()) { + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; + } +} + +pub const GWL_WNDPROC = -4; +pub const GWL_HINSTANCE = -6; +pub const GWL_HWNDPARENT = -8; +pub const GWL_STYLE = -16; +pub const GWL_EXSTYLE = -20; +pub const GWL_USERDATA = -21; +pub const GWL_ID = -12; + +pub extern "user32" fn GetWindowLongA(hWnd: HWND, nIndex: i32) callconv(WINAPI) LONG; +pub fn getWindowLongA(hWnd: HWND, nIndex: i32) !i32 { + const value = GetWindowLongA(hWnd, nIndex); + if (value != 0) return value; + + return switch (GetLastError()) { + .SUCCESS => 0, + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn GetWindowLongW(hWnd: HWND, nIndex: i32) callconv(WINAPI) LONG; +pub var pfnGetWindowLongW: @TypeOf(GetWindowLongW) = undefined; +pub fn getWindowLongW(hWnd: HWND, nIndex: i32) !i32 { + const function = selectSymbol(GetWindowLongW, pfnGetWindowLongW, .win2k); + + const value = function(hWnd, nIndex); + if (value != 0) return value; + + return switch (GetLastError()) { + .SUCCESS => 0, + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn GetWindowLongPtrA(hWnd: HWND, nIndex: i32) callconv(WINAPI) LONG_PTR; +pub fn getWindowLongPtrA(hWnd: HWND, nIndex: i32) !isize { + // "When compiling for 32-bit Windows, GetWindowLongPtr is defined as a call to the GetWindowLong function." + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowlongptrw + if (@sizeOf(LONG_PTR) == 4) return getWindowLongA(hWnd, nIndex); + + const value = GetWindowLongPtrA(hWnd, nIndex); + if (value != 0) return value; + + return switch (GetLastError()) { + .SUCCESS => 0, + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn GetWindowLongPtrW(hWnd: HWND, nIndex: i32) callconv(WINAPI) LONG_PTR; +pub var pfnGetWindowLongPtrW: @TypeOf(GetWindowLongPtrW) = undefined; +pub fn getWindowLongPtrW(hWnd: HWND, nIndex: i32) !isize { + if (@sizeOf(LONG_PTR) == 4) return getWindowLongW(hWnd, nIndex); + const function = selectSymbol(GetWindowLongPtrW, pfnGetWindowLongPtrW, .win2k); + + const value = function(hWnd, nIndex); + if (value != 0) return value; + + return switch (GetLastError()) { + .SUCCESS => 0, + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn SetWindowLongA(hWnd: HWND, nIndex: i32, dwNewLong: LONG) callconv(WINAPI) LONG; +pub fn setWindowLongA(hWnd: HWND, nIndex: i32, dwNewLong: i32) !i32 { + // [...] you should clear the last error information by calling SetLastError with 0 before calling SetWindowLong. + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowlonga + SetLastError(.SUCCESS); + + const value = SetWindowLongA(hWnd, nIndex, dwNewLong); + if (value != 0) return value; + + return switch (GetLastError()) { + .SUCCESS => 0, + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn SetWindowLongW(hWnd: HWND, nIndex: i32, dwNewLong: LONG) callconv(WINAPI) LONG; +pub var pfnSetWindowLongW: @TypeOf(SetWindowLongW) = undefined; +pub fn setWindowLongW(hWnd: HWND, nIndex: i32, dwNewLong: i32) !i32 { + const function = selectSymbol(SetWindowLongW, pfnSetWindowLongW, .win2k); + + SetLastError(.SUCCESS); + const value = function(hWnd, nIndex, dwNewLong); + if (value != 0) return value; + + return switch (GetLastError()) { + .SUCCESS => 0, + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn SetWindowLongPtrA(hWnd: HWND, nIndex: i32, dwNewLong: LONG_PTR) callconv(WINAPI) LONG_PTR; +pub fn setWindowLongPtrA(hWnd: HWND, nIndex: i32, dwNewLong: isize) !isize { + // "When compiling for 32-bit Windows, GetWindowLongPtr is defined as a call to the GetWindowLong function." + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowlongptrw + if (@sizeOf(LONG_PTR) == 4) return setWindowLongA(hWnd, nIndex, dwNewLong); + + SetLastError(.SUCCESS); + const value = SetWindowLongPtrA(hWnd, nIndex, dwNewLong); + if (value != 0) return value; + + return switch (GetLastError()) { + .SUCCESS => 0, + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn SetWindowLongPtrW(hWnd: HWND, nIndex: i32, dwNewLong: LONG_PTR) callconv(WINAPI) LONG_PTR; +pub var pfnSetWindowLongPtrW: @TypeOf(SetWindowLongPtrW) = undefined; +pub fn setWindowLongPtrW(hWnd: HWND, nIndex: i32, dwNewLong: isize) !isize { + if (@sizeOf(LONG_PTR) == 4) return setWindowLongW(hWnd, nIndex, dwNewLong); + const function = selectSymbol(SetWindowLongPtrW, pfnSetWindowLongPtrW, .win2k); + + SetLastError(.SUCCESS); + const value = function(hWnd, nIndex, dwNewLong); + if (value != 0) return value; + + return switch (GetLastError()) { + .SUCCESS => 0, + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} -pub extern "user32" fn RegisterClassExA(*const WNDCLASSEXA) callconv(WINAPI) c_ushort; -pub extern "user32" fn DefWindowProcA(HWND, Msg: UINT, WPARAM, LPARAM) callconv(WINAPI) LRESULT; -pub extern "user32" fn ShowWindow(hWnd: ?HWND, nCmdShow: i32) callconv(WINAPI) bool; -pub extern "user32" fn UpdateWindow(hWnd: ?HWND) callconv(WINAPI) bool; pub extern "user32" fn GetDC(hWnd: ?HWND) callconv(WINAPI) ?HDC; +pub fn getDC(hWnd: ?HWND) !HDC { + const hdc = GetDC(hWnd); + if (hdc) |h| return h; -pub extern "user32" fn PeekMessageA( - lpMsg: ?*MSG, - hWnd: ?HWND, - wMsgFilterMin: UINT, - wMsgFilterMax: UINT, - wRemoveMsg: UINT, -) callconv(WINAPI) bool; + return switch (GetLastError()) { + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} -pub extern "user32" fn GetMessageA( - lpMsg: ?*MSG, - hWnd: ?HWND, - wMsgFilterMin: UINT, - wMsgFilterMax: UINT, -) callconv(WINAPI) bool; +pub extern "user32" fn ReleaseDC(hWnd: ?HWND, hDC: HDC) callconv(WINAPI) i32; +pub fn releaseDC(hWnd: ?HWND, hDC: HDC) bool { + return if (ReleaseDC(hWnd, hDC) == 1) true else false; +} -pub extern "user32" fn TranslateMessage(lpMsg: *const MSG) callconv(WINAPI) bool; -pub extern "user32" fn DispatchMessageA(lpMsg: *const MSG) callconv(WINAPI) LRESULT; -pub extern "user32" fn PostQuitMessage(nExitCode: i32) callconv(WINAPI) void; +// === Modal dialogue boxes === + +pub const MB_OK = 0x00000000; +pub const MB_OKCANCEL = 0x00000001; +pub const MB_ABORTRETRYIGNORE = 0x00000002; +pub const MB_YESNOCANCEL = 0x00000003; +pub const MB_YESNO = 0x00000004; +pub const MB_RETRYCANCEL = 0x00000005; +pub const MB_CANCELTRYCONTINUE = 0x00000006; +pub const MB_ICONHAND = 0x00000010; +pub const MB_ICONQUESTION = 0x00000020; +pub const MB_ICONEXCLAMATION = 0x00000030; +pub const MB_ICONASTERISK = 0x00000040; +pub const MB_USERICON = 0x00000080; +pub const MB_ICONWARNING = MB_ICONEXCLAMATION; +pub const MB_ICONERROR = MB_ICONHAND; +pub const MB_ICONINFORMATION = MB_ICONASTERISK; +pub const MB_ICONSTOP = MB_ICONHAND; +pub const MB_DEFBUTTON1 = 0x00000000; +pub const MB_DEFBUTTON2 = 0x00000100; +pub const MB_DEFBUTTON3 = 0x00000200; +pub const MB_DEFBUTTON4 = 0x00000300; +pub const MB_APPLMODAL = 0x00000000; +pub const MB_SYSTEMMODAL = 0x00001000; +pub const MB_TASKMODAL = 0x00002000; +pub const MB_HELP = 0x00004000; +pub const MB_NOFOCUS = 0x00008000; +pub const MB_SETFOREGROUND = 0x00010000; +pub const MB_DEFAULT_DESKTOP_ONLY = 0x00020000; +pub const MB_TOPMOST = 0x00040000; +pub const MB_RIGHT = 0x00080000; +pub const MB_RTLREADING = 0x00100000; +pub const MB_TYPEMASK = 0x0000000F; +pub const MB_ICONMASK = 0x000000F0; +pub const MB_DEFMASK = 0x00000F00; +pub const MB_MODEMASK = 0x00003000; +pub const MB_MISCMASK = 0x0000C000; + +pub const IDOK = 1; +pub const IDCANCEL = 2; +pub const IDABORT = 3; +pub const IDRETRY = 4; +pub const IDIGNORE = 5; +pub const IDYES = 6; +pub const IDNO = 7; +pub const IDCLOSE = 8; +pub const IDHELP = 9; +pub const IDTRYAGAIN = 10; +pub const IDCONTINUE = 11; + +pub extern "user32" fn MessageBoxA(hWnd: ?HWND, lpText: [*:0]const u8, lpCaption: [*:0]const u8, uType: UINT) callconv(WINAPI) i32; +pub fn messageBoxA(hWnd: ?HWND, lpText: [*:0]const u8, lpCaption: [*:0]const u8, uType: u32) !i32 { + const value = MessageBoxA(hWnd, lpText, lpCaption, uType); + if (value != 0) return value; + return switch (GetLastError()) { + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} + +pub extern "user32" fn MessageBoxW(hWnd: ?HWND, lpText: [*:0]const u16, lpCaption: ?[*:0]const u16, uType: UINT) callconv(WINAPI) i32; +pub var pfnMessageBoxW: @TypeOf(MessageBoxW) = undefined; +pub fn messageBoxW(hWnd: ?HWND, lpText: [*:0]const u16, lpCaption: [*:0]const u16, uType: u32) !i32 { + const function = selectSymbol(pfnMessageBoxW, MessageBoxW, .win2k); + const value = function(hWnd, lpText, lpCaption, uType); + if (value != 0) return value; + return switch (GetLastError()) { + .INVALID_WINDOW_HANDLE => unreachable, + .INVALID_PARAMETER => unreachable, + else => |err| return windows.unexpectedError(err), + }; +} From bbc2c7c268bae51c5cafc1c44f82eb056839ae1a Mon Sep 17 00:00:00 2001 From: Jens Goldberg Date: Sun, 22 Nov 2020 14:24:36 +0000 Subject: [PATCH 2/4] Ensure the dynamic function has the same type as the static one Co-authored-by: daurnimator --- lib/std/os/windows/user32.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/os/windows/user32.zig b/lib/std/os/windows/user32.zig index 479ac8653245..96b7c1e04a66 100644 --- a/lib/std/os/windows/user32.zig +++ b/lib/std/os/windows/user32.zig @@ -12,7 +12,7 @@ const unexpectedError = windows.unexpectedError; const GetLastError = windows.kernel32.GetLastError; const SetLastError = windows.kernel32.SetLastError; -fn selectSymbol(comptime function_static: anytype, function_dynamic: anytype, comptime os: std.Target.Os.WindowsVersion) @TypeOf(function_static) { +fn selectSymbol(comptime function_static: anytype, function_dynamic: @TypeOf(function_static), comptime os: std.Target.Os.WindowsVersion) @TypeOf(function_static) { comptime { const sym_ok = builtin.Target.current.os.isAtLeast(.windows, os); if (sym_ok == true) return function_static; From 6fd536a50c087f4297f87034ef8891fbd41aa356 Mon Sep 17 00:00:00 2001 From: Aransentin Date: Sun, 22 Nov 2020 14:51:32 +0000 Subject: [PATCH 3/4] Fixed bugs, style suggestions --- lib/std/os/windows/user32.zig | 137 +++++++++++++++++----------------- 1 file changed, 69 insertions(+), 68 deletions(-) diff --git a/lib/std/os/windows/user32.zig b/lib/std/os/windows/user32.zig index 96b7c1e04a66..97de924eeb88 100644 --- a/lib/std/os/windows/user32.zig +++ b/lib/std/os/windows/user32.zig @@ -86,7 +86,8 @@ pub const WM_SYSKEYDOWN = 0x0104; pub const WM_SYSKEYUP = 0x0105; pub const WM_SYSCHAR = 0x0106; pub const WM_SYSDEADCHAR = 0x0107; -pub const WM_KEYLAST = 0x0108; +pub const WM_UNICHAR = 0x0109; +pub const WM_KEYLAST = 0x0109; pub const WM_INITDIALOG = 0x0110; pub const WM_COMMAND = 0x0111; pub const WM_SYSCOMMAND = 0x0112; @@ -128,11 +129,11 @@ pub fn getMessageA(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: u32, wMsgFilterMax: const r = GetMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); if (r == 0) return error.Quit; if (r != -1) return; - return switch (GetLastError()) { + switch (GetLastError()) { .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn GetMessageW(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) callconv(WINAPI) BOOL; @@ -143,11 +144,11 @@ pub fn getMessageW(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: u32, wMsgFilterMax: const r = function(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); if (r == 0) return error.Quit; if (r != -1) return; - return switch (GetLastError()) { + switch (GetLastError()) { .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub const PM_NOREMOVE = 0x0000; @@ -159,11 +160,11 @@ pub fn peekMessageA(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: u32, wMsgFilterMax: const r = PeekMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); if (r == 0) return false; if (r != -1) return true; - return switch (GetLastError()) { + switch (GetLastError()) { .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn PeekMessageW(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT, wRemoveMsg: UINT) callconv(WINAPI) BOOL; @@ -174,11 +175,11 @@ pub fn peekMessageW(lpMsg: *MSG, hWnd: ?HWND, wMsgFilterMin: u32, wMsgFilterMax: const r = function(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); if (r == 0) return false; if (r != -1) return true; - return switch (GetLastError()) { + switch (GetLastError()) { .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn TranslateMessage(lpMsg: *const MSG) callconv(WINAPI) BOOL; @@ -263,46 +264,46 @@ pub extern "user32" fn RegisterClassExA(*const WNDCLASSEXA) callconv(WINAPI) ATO pub fn registerClassExA(window_class: *const WNDCLASSEXA) !ATOM { const atom = RegisterClassExA(window_class); if (atom != 0) return atom; - return switch (GetLastError()) { - .CLASS_ALREADY_EXISTS => error.AlreadyExists, + switch (GetLastError()) { + .CLASS_ALREADY_EXISTS => return error.AlreadyExists, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn RegisterClassExW(*const WNDCLASSEXW) callconv(WINAPI) ATOM; pub var pfnRegisterClassExW: @TypeOf(RegisterClassExW) = undefined; -pub fn registerClassExW(window_class: *const WNDCLASSEXA) !ATOM { +pub fn registerClassExW(window_class: *const WNDCLASSEXW) !ATOM { const function = selectSymbol(RegisterClassExW, pfnRegisterClassExW, .win2k); const atom = function(window_class); if (atom != 0) return atom; - return switch (GetLastError()) { - .CLASS_ALREADY_EXISTS => error.AlreadyExists, + switch (GetLastError()) { + .CLASS_ALREADY_EXISTS => return error.AlreadyExists, .CALL_NOT_IMPLEMENTED => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } -pub extern "user32" fn UnregisterClassA(lpClassName: LPCSTR, hInstance: HINSTANCE) callconv(.Stdcall) BOOL; +pub extern "user32" fn UnregisterClassA(lpClassName: [*:0]const u8, hInstance: HINSTANCE) callconv(WINAPI) BOOL; pub fn unregisterClassA(lpClassName: [*:0]const u8, hInstance: HINSTANCE) !void { if (UnregisterClassA(lpClassName, hInstance) == 0) { - return switch (GetLastError()) { - .CLASS_DOES_NOT_EXIST => error.ClassDoesNotExist, + switch (GetLastError()) { + .CLASS_DOES_NOT_EXIST => return error.ClassDoesNotExist, else => |err| return windows.unexpectedError(err), - }; + } } } -pub extern "user32" fn UnregisterClassW(lpClassName: LPCWSTR, hInstance: HINSTANCE) callconv(.Stdcall) BOOL; +pub extern "user32" fn UnregisterClassW(lpClassName: [*:0]const u16, hInstance: HINSTANCE) callconv(.Stdcall) BOOL; pub var pfnUnregisterClassW: @TypeOf(UnregisterClassW) = undefined; pub fn unregisterClassW(lpClassName: [*:0]const u16, hInstance: HINSTANCE) !void { const function = selectSymbol(UnregisterClassW, pfnUnregisterClassW, .win2k); if (function(lpClassName, hInstance) == 0) { - return switch (GetLastError()) { - .CLASS_DOES_NOT_EXIST => error.ClassDoesNotExist, + switch (GetLastError()) { + .CLASS_DOES_NOT_EXIST => return error.ClassDoesNotExist, else => |err| return windows.unexpectedError(err), - }; + } } } @@ -354,8 +355,8 @@ pub const WS_EX_CONTROLPARENT = 0x00010000; pub const WS_EX_STATICEDGE = 0x00020000; pub const WS_EX_APPWINDOW = 0x00040000; pub const WS_EX_LAYERED = 0x00080000; -pub const WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE); -pub const WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST); +pub const WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE; +pub const WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST; pub const CW_USEDEFAULT = @bitCast(i32, @as(u32, 0x80000000)); @@ -364,11 +365,11 @@ pub fn createWindowExA(dwExStyle: u32, lpClassName: [*:0]const u8, lpWindowName: const window = CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWindParent, hMenu, hInstance, lpParam); if (window) |win| return win; - return switch (GetLastError()) { - .CLASS_DOES_NOT_EXIST => error.ClassDoesNotExist, + switch (GetLastError()) { + .CLASS_DOES_NOT_EXIST => return error.ClassDoesNotExist, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn CreateWindowExW(dwExStyle: DWORD, lpClassName: [*:0]const u16, lpWindowName: [*:0]const u16, dwStyle: DWORD, X: i32, Y: i32, nWidth: i32, nHeight: i32, hWindParent: ?HWND, hMenu: ?HMENU, hInstance: HINSTANCE, lpParam: ?LPVOID) callconv(WINAPI) ?HWND; @@ -378,21 +379,21 @@ pub fn createWindowExW(dwExStyle: u32, lpClassName: [*:0]const u16, lpWindowName const window = function(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWindParent, hMenu, hInstance, lpParam); if (window) |win| return win; - return switch (GetLastError()) { - .CLASS_DOES_NOT_EXIST => error.ClassDoesNotExist, + switch (GetLastError()) { + .CLASS_DOES_NOT_EXIST => return error.ClassDoesNotExist, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn DestroyWindow(hWnd: HWND) callconv(WINAPI) BOOL; pub fn destroyWindow(hWnd: HWND) !void { if (DestroyWindow(hWnd) == 0) { - return switch (GetLastError()) { + switch (GetLastError()) { .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } } @@ -420,11 +421,11 @@ pub fn showWindow(hWnd: HWND, nCmdShow: i32) bool { pub extern "user32" fn UpdateWindow(hWnd: HWND) callconv(WINAPI) BOOL; pub fn updateWindow(hWnd: HWND) !void { if (ShowWindow(hWnd, nCmdShow) == 0) { - return switch (GetLastError()) { + switch (GetLastError()) { .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } } @@ -433,10 +434,10 @@ pub fn adjustWindowRectEx(lpRect: *RECT, dwStyle: u32, bMenu: bool, dwExStyle: u assert(dwStyle & WS_OVERLAPPED == 0); if (AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle) == 0) { - return switch (GetLastError()) { + switch (GetLastError()) { .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } } @@ -453,12 +454,12 @@ pub fn getWindowLongA(hWnd: HWND, nIndex: i32) !i32 { const value = GetWindowLongA(hWnd, nIndex); if (value != 0) return value; - return switch (GetLastError()) { - .SUCCESS => 0, + switch (GetLastError()) { + .SUCCESS => return 0, .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn GetWindowLongW(hWnd: HWND, nIndex: i32) callconv(WINAPI) LONG; @@ -469,12 +470,12 @@ pub fn getWindowLongW(hWnd: HWND, nIndex: i32) !i32 { const value = function(hWnd, nIndex); if (value != 0) return value; - return switch (GetLastError()) { - .SUCCESS => 0, + switch (GetLastError()) { + .SUCCESS => return 0, .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn GetWindowLongPtrA(hWnd: HWND, nIndex: i32) callconv(WINAPI) LONG_PTR; @@ -486,12 +487,12 @@ pub fn getWindowLongPtrA(hWnd: HWND, nIndex: i32) !isize { const value = GetWindowLongPtrA(hWnd, nIndex); if (value != 0) return value; - return switch (GetLastError()) { - .SUCCESS => 0, + switch (GetLastError()) { + .SUCCESS => return 0, .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn GetWindowLongPtrW(hWnd: HWND, nIndex: i32) callconv(WINAPI) LONG_PTR; @@ -503,12 +504,12 @@ pub fn getWindowLongPtrW(hWnd: HWND, nIndex: i32) !isize { const value = function(hWnd, nIndex); if (value != 0) return value; - return switch (GetLastError()) { - .SUCCESS => 0, + switch (GetLastError()) { + .SUCCESS => return 0, .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn SetWindowLongA(hWnd: HWND, nIndex: i32, dwNewLong: LONG) callconv(WINAPI) LONG; @@ -520,12 +521,12 @@ pub fn setWindowLongA(hWnd: HWND, nIndex: i32, dwNewLong: i32) !i32 { const value = SetWindowLongA(hWnd, nIndex, dwNewLong); if (value != 0) return value; - return switch (GetLastError()) { - .SUCCESS => 0, + switch (GetLastError()) { + .SUCCESS => return 0, .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn SetWindowLongW(hWnd: HWND, nIndex: i32, dwNewLong: LONG) callconv(WINAPI) LONG; @@ -537,12 +538,12 @@ pub fn setWindowLongW(hWnd: HWND, nIndex: i32, dwNewLong: i32) !i32 { const value = function(hWnd, nIndex, dwNewLong); if (value != 0) return value; - return switch (GetLastError()) { - .SUCCESS => 0, + switch (GetLastError()) { + .SUCCESS => return 0, .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn SetWindowLongPtrA(hWnd: HWND, nIndex: i32, dwNewLong: LONG_PTR) callconv(WINAPI) LONG_PTR; @@ -555,12 +556,12 @@ pub fn setWindowLongPtrA(hWnd: HWND, nIndex: i32, dwNewLong: isize) !isize { const value = SetWindowLongPtrA(hWnd, nIndex, dwNewLong); if (value != 0) return value; - return switch (GetLastError()) { - .SUCCESS => 0, + switch (GetLastError()) { + .SUCCESS => return 0, .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn SetWindowLongPtrW(hWnd: HWND, nIndex: i32, dwNewLong: LONG_PTR) callconv(WINAPI) LONG_PTR; @@ -573,12 +574,12 @@ pub fn setWindowLongPtrW(hWnd: HWND, nIndex: i32, dwNewLong: isize) !isize { const value = function(hWnd, nIndex, dwNewLong); if (value != 0) return value; - return switch (GetLastError()) { - .SUCCESS => 0, + switch (GetLastError()) { + .SUCCESS => return 0, .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn GetDC(hWnd: ?HWND) callconv(WINAPI) ?HDC; @@ -586,11 +587,11 @@ pub fn getDC(hWnd: ?HWND) !HDC { const hdc = GetDC(hWnd); if (hdc) |h| return h; - return switch (GetLastError()) { + switch (GetLastError()) { .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn ReleaseDC(hWnd: ?HWND, hDC: HDC) callconv(WINAPI) i32; @@ -652,11 +653,11 @@ pub extern "user32" fn MessageBoxA(hWnd: ?HWND, lpText: [*:0]const u8, lpCaption pub fn messageBoxA(hWnd: ?HWND, lpText: [*:0]const u8, lpCaption: [*:0]const u8, uType: u32) !i32 { const value = MessageBoxA(hWnd, lpText, lpCaption, uType); if (value != 0) return value; - return switch (GetLastError()) { + switch (GetLastError()) { .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } pub extern "user32" fn MessageBoxW(hWnd: ?HWND, lpText: [*:0]const u16, lpCaption: ?[*:0]const u16, uType: UINT) callconv(WINAPI) i32; @@ -665,9 +666,9 @@ pub fn messageBoxW(hWnd: ?HWND, lpText: [*:0]const u16, lpCaption: [*:0]const u1 const function = selectSymbol(pfnMessageBoxW, MessageBoxW, .win2k); const value = function(hWnd, lpText, lpCaption, uType); if (value != 0) return value; - return switch (GetLastError()) { + switch (GetLastError()) { .INVALID_WINDOW_HANDLE => unreachable, .INVALID_PARAMETER => unreachable, else => |err| return windows.unexpectedError(err), - }; + } } From c8723beda8c7a0fa7d2137d63afc13ae5334fca3 Mon Sep 17 00:00:00 2001 From: Aransentin Date: Sun, 22 Nov 2020 14:58:10 +0000 Subject: [PATCH 4/4] UnregisterClassW needs WINAPI as well --- lib/std/os/windows/user32.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/os/windows/user32.zig b/lib/std/os/windows/user32.zig index 97de924eeb88..6a870da0cd4a 100644 --- a/lib/std/os/windows/user32.zig +++ b/lib/std/os/windows/user32.zig @@ -295,7 +295,7 @@ pub fn unregisterClassA(lpClassName: [*:0]const u8, hInstance: HINSTANCE) !void } } -pub extern "user32" fn UnregisterClassW(lpClassName: [*:0]const u16, hInstance: HINSTANCE) callconv(.Stdcall) BOOL; +pub extern "user32" fn UnregisterClassW(lpClassName: [*:0]const u16, hInstance: HINSTANCE) callconv(WINAPI) BOOL; pub var pfnUnregisterClassW: @TypeOf(UnregisterClassW) = undefined; pub fn unregisterClassW(lpClassName: [*:0]const u16, hInstance: HINSTANCE) !void { const function = selectSymbol(UnregisterClassW, pfnUnregisterClassW, .win2k);