using D3D = Vortice.Direct3D;using D3D11 = Vortice.Direct3D11;using DXGI = Vortice.DXGI;using D2D = Vortice.Direct2D1;
其他的引用代码如下
using System.Runtime.CompilerServices;using System.Runtime.InteropServices;using System.Runtime.Versioning;using Windows.Win32.Foundation;using Windows.Win32.UI.WindowsAndMessaging;using static Windows.Win32.PInvoke;using static Windows.Win32.UI.WindowsAndMessaging.PEEK_MESSAGE_REMOVE_TYPE;using static Windows.Win32.UI.WindowsAndMessaging.WNDCLASS_STYLES;using static Windows.Win32.UI.WindowsAndMessaging.WINDOW_STYLE;using static Windows.Win32.UI.WindowsAndMessaging.WINDOW_EX_STYLE;using static Windows.Win32.UI.WindowsAndMessaging.SYSTEM_METRICS_INDEX;using static Windows.Win32.UI.WindowsAndMessaging.SHOW_WINDOW_CMD;using Vortice.DCommon;using Vortice.Mathematics;using AlphaMode = Vortice.DXGI.AlphaMode;
由于本文使用的项目 , 在 csproj 项目文件设置了使用 ImplicitUsings 属性 , 加上对 System 等命名空间的默认引用,这里就不需要再写对默认命名空间的引用
加上 Win32 定义为了创建 Win32 窗口以及初始化创建 DX 对象,就需要使用一些 Win32 函数 。使用 Win32 函数之前 , 需要对 Win32 函数进行定义 。本文使用 Microsoft.Windows.CsWin32 库来辅助编写 Win32 函数的定义
在安装了 Microsoft.Windows.CsWin32 库 , 即可新建一个 NativeMethods.txt
的文件,在这个文件里面,一行一个函数或 Win32 类型名,即可自动使用源代码生成的方式创建定义
新建一个 NativeMethods.txt
文件 , 在这个文件里面写上需要使用的 Win32 函数,内容如下
GetModuleHandlePeekMessageTranslateMessageDispatchMessageGetMessageRegisterClassExWDefWindowProcLoadCursorPostQuitMessageCreateWindowExWDestroyWindowShowWindowGetSystemMetricsAdjustWindowRectExGetClientRectGetWindowRectIDC_ARROWWM_KEYDOWNWM_KEYUPWM_SYSKEYDOWNWM_SYSKEYUPWM_DESTROYWM_QUITWM_PAINTWM_CLOSEWM_ACTIVATEAPPVIRTUAL_KEY
完成了初始化准备之后,接下来就可以开始编写代码
创建窗口本文使用控制台项目,在创建 Win32 窗口,需要使用到很多 Win32 窗口创建的细节代码,但本文更侧重如何使用 DX 的知识,因此关于 Win32 创建窗口的逻辑,大部分都会略过
在开始创建 Win32 窗口之前,先准备一些参数
设置窗口的尺寸
SizeI clientSize = new SizeI(1000, 1000);
再给窗口定义一个标题
// 窗口标题var title = "Demo";var windowClassName = "lindexi doubi";
配置窗口的 Win32 样式,这个样式的内容没啥固定的,可以根据自己的需求来,也可以乱来,不离谱就好
// 窗口样式,窗口样式含义请执行参阅官方文档,样式只要不离谱,自己随便写,影响不大WINDOW_STYLE style = WS_CAPTION |WS_SYSMENU |WS_MINIMIZEBOX |WS_CLIPSIBLINGS |WS_BORDER |WS_DLGFRAME |WS_THICKFRAME |WS_GROUP |WS_TABSTOP |WS_SIZEBOX;
根据上面设置的窗口尺寸,尝试根据样式算出实际可用的尺寸
var rect = new RECT{right = clientSize.Width,bottom = clientSize.Height};// Adjust according to window stylesAdjustWindowRectEx(&rect, style, false, WS_EX_APPWINDOW);
接着算出窗口显示的坐标和尺寸,这个逻辑非核心逻辑,也可以自己随意写一个坐标 。本文将尝试让窗口显示在屏幕中间
int x = 0;int y = 0;int windowWidth = rect.right - rect.left;int windowHeight = rect.bottom - rect.top;// 随便,放在屏幕中间好了 。多个显示器?忽略int screenWidth = GetSystemMetrics(SM_CXSCREEN);int screenHeight = GetSystemMetrics(SM_CYSCREEN);x = (screenWidth - windowWidth) / 2;y = (screenHeight - windowHeight) / 2;
准备完成,开始创建窗口
var hInstance = GetModuleHandle((string)null);fixed (char* lpszClassName = windowClassName){PCWSTR szCursorName = new((char*)IDC_ARROW);var wndClassEx = new WNDCLASSEXW{cbSize = (uint)Unsafe.SizeOf<WNDCLASSEXW>(),style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,// 核心逻辑,设置消息循环lpfnWndProc = new WNDPROC(WndProc),hInstance = (HINSTANCE)hInstance.DangerousGetHandle(),hCursor = LoadCursor((HINSTANCE)IntPtr.Zero, szCursorName),hbrBackground = (Windows.Win32.Graphics.Gdi.HBRUSH)IntPtr.Zero,hIcon = (HICON)IntPtr.Zero,lpszClassName = lpszClassName};ushort atom = RegisterClassEx(wndClassEx);if (atom == 0){throw new InvalidOperationException($"Failed to register window class. Error: {Marshal.GetLastWin32Error()}");}}// 创建窗口var hWnd = CreateWindowEx(WS_EX_APPWINDOW,windowClassName,title,style,x,y,windowWidth,windowHeight,hWndParent: default,hMenu: default,hInstance: default,lpParam: null);
获取到的 hWnd
将会在接下来被 DX 挂上
但愿大家知道 hWnd
是啥意思
既然创建出了窗口了 , 那就显示出来吧
推荐阅读
- 为什么阿里Java开发手册不推荐使用Timestamp
- VMware安装Win11+WSA子系统和使用教程
- 支付宝取消自动续费怎么取消? 支付宝取消自动续费怎么取消
- 宝马3系320Li的使用日记 宝马3系320li价格
- 晚上避光使用了果酸面霜,为什么脸色还是变黑了
- 手镯变黑怎么恢复 银手镯变黑怎么清洗变亮
- 姜力洗发水跟润发乳要怎么使用
- 甜橙信用卡免费还款额度怎么使用不了 甜橙信用卡免费还款额度怎么使用
- 婷美高保湿面膏如何使用
- 百果园回应使用变质水果做果切