Last active
March 24, 2026 02:02
-
-
Save jxqu3/a38d06598cc8716b7882a5b3e46af61d to your computer and use it in GitHub Desktop.
This is a class to make a window using the Win32 API. It needs to have Microsoft's CsWin32 set up, and works like this.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| User32.* | |
| Kernel32.* | |
| WM_DESTROY | |
| IDC_ARROW | |
| BS_DEFPUSHBUTTON |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Windows.Win32; | |
| using Windows.Win32.UI.WindowsAndMessaging; | |
| using Windows.Win32.Foundation; | |
| using System.Text; | |
| using System.Runtime.InteropServices; | |
| using System.Runtime.CompilerServices; | |
| namespace NativeWindowApp; | |
| internal class Window : Control, IDisposable | |
| { | |
| public string Title { get; set; } = "Native Window"; | |
| public Window(int width, int height, string title = "Native Window", string className = "MyNativeWindowClass") | |
| { | |
| Width = width; | |
| Height = height; | |
| Title = title; | |
| ClassName = className; | |
| Initialize(); | |
| } | |
| public override void Initialize() | |
| { | |
| unsafe | |
| { | |
| hInstance = PInvoke.GetModuleHandle(null); | |
| fixed (char* pClassName = ClassName) | |
| { | |
| WINDOW_EX_STYLE style = WINDOW_EX_STYLE.WS_EX_APPWINDOW | WINDOW_EX_STYLE.WS_EX_WINDOWEDGE; | |
| var wndClass = new WNDCLASSW | |
| { | |
| lpfnWndProc = &WindowProc, | |
| lpszClassName = new PCWSTR(pClassName), | |
| hInstance = new HINSTANCE(hInstance.DangerousGetHandle()), | |
| hCursor = PInvoke.LoadCursor(HINSTANCE.Null, PInvoke.IDC_ARROW), | |
| }; | |
| _ = PInvoke.RegisterClass(wndClass); | |
| _hwnd = PInvoke.CreateWindowEx(style, ClassName, Title, WINDOW_STYLE.WS_OVERLAPPEDWINDOW, 100, 100, Width, Height, HWND.Null, new FreeLibrarySafeHandle(), hInstance, null); | |
| PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_SHOW); | |
| } | |
| } | |
| } | |
| public void Dispose() | |
| { | |
| if (_hwnd != HWND.Null) | |
| { | |
| PInvoke.DestroyWindow(_hwnd); | |
| _hwnd = HWND.Null; | |
| } | |
| } | |
| public void InitLoop() | |
| { | |
| while (PInvoke.GetMessage(out MSG msg, HWND.Null, 0, 0) > 0) | |
| { | |
| PInvoke.TranslateMessage(msg); | |
| PInvoke.DispatchMessage(msg); | |
| Thread.Sleep(10); | |
| } | |
| } | |
| [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] | |
| static LRESULT WindowProc(HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam) | |
| { | |
| switch (msg) | |
| { | |
| case PInvoke.WM_DESTROY: | |
| PInvoke.PostQuitMessage(0); | |
| return (LRESULT)0; | |
| } | |
| return PInvoke.DefWindowProc(hWnd, msg, wParam, lParam); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using NativeWindowApp; | |
| internal class Program | |
| { | |
| private static void Main(string[] args) | |
| { | |
| Console.WriteLine("Starting Native Window Application..."); | |
| using (var window = new Window(1024, 768, "My Native Window")) | |
| { | |
| var button = new Button(window); | |
| window.InitLoop(); | |
| } | |
| Console.WriteLine("Adding Native Button..."); | |
| //var button = new Button(window); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <Project Sdk="Microsoft.NET.Sdk"> | |
| <PropertyGroup> | |
| <OutputType>WinExe</OutputType> | |
| <TargetFramework>net10.0-windows</TargetFramework> | |
| <ImplicitUsings>enable</ImplicitUsings> | |
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |
| <Nullable>enable</Nullable> | |
| <PublishAot>true</PublishAot> | |
| <CsWin32RunAsBuildTask>true</CsWin32RunAsBuildTask> | |
| <DisableRuntimeMarshalling>true</DisableRuntimeMarshalling> | |
| </PropertyGroup> | |
| <ItemGroup> | |
| </ItemGroup> | |
| <ItemGroup> | |
| <PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.264"> | |
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |
| <PrivateAssets>all</PrivateAssets> | |
| </PackageReference> | |
| <PackageReference Include="Microsoft.Windows.SDK.Win32Metadata" Version="69.0.7-preview" /> | |
| </ItemGroup> | |
| </Project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment