// 窗口样式 , 窗口样式含义请执行参阅官方文档 , 样式只要不离谱 , 自己随便写 , 影响不大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
是啥意思
既然创建出了窗口了 , 那就显示出来吧
// 创建完成 , 那就显示ShowWindow(hWnd, SW_NORMAL);
获取实际的窗口大小 , 这将用来决定后续交换链的创建 。什么是交换链?自己去了解
RECT windowRect;GetClientRect(hWnd, &windowRect);clientSize = new SizeI(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
以上代码就完成了创建 Win32 窗口
获取显示适配器接口这一步是可选的 , 通过枚举 DX 提供的抽象的显示适配器接口 , 可以用来后续创建 D3D 设备 。本文这里是给大家演示如何获取抽象的显示适配器接口的方法 , 没有指定显示适配器接口也是可以创建 D3D 设备
显示适配器接口 IDXGIAdapter 是对硬件或软件的一个抽象 , 可以是一个显卡 , 也可以是一个软件渲染器 。这里获取到的抽象的显示适配器接口 , 在大部分情况下都是和具体的显卡相关的 , 但是不代表着一定就是真实的显卡
下图是从官方文档拷贝的 , 一个电脑加两个显卡的对象关系
文章插图
先尝试使用 IDXGIFactory6 提供的 EnumAdapterByGpuPreference 方法枚举显卡 , 这个方法的功能是可以按照给定的参数进行排序 , 特别方便开发时 , 获取首个可用显卡
想要使用 EnumAdapterByGpuPreference 方法 , 需要先获取 IDXGIFactory6 对象 。而 IDXGIFactory6 对象可以通过工厂创建 IDXGIFactory2 对象间接获取
经验总结扩展阅读
- 为什么阿里Java开发手册不推荐使用Timestamp
- VMware安装Win11+WSA子系统和使用教程
- 拱辰享适合什么肤质的人使用?
- 护衣留香珠的使用方法?
- 悦薇水乳适合多大年纪的人使用?
- 怡丽丝尔护肤品适合多大年龄的人使用?
- 御泥坊眼膜贴适合什么年龄段的人使用?
- 御泥坊五件套使用步骤是什么?
- 御泥坊小金瓶适合什么人群使用?
- 御泥坊小金瓶适合什么年龄使用?