一般来讲,要绘制或者渲染目标物体首先需要创建窗口,通常需要配合渲染API(opengl directx 等)来实现。这边主要介绍的是windows上最基本的窗口创建方式,抛弃MFC等内部创建调用的方式,通过最底层的调用来实现窗口的创建
CreateWindowW创建窗口句柄
窗口创建主要是获取窗口句柄
HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"D", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
窗口可以调节尺寸以及移动
MSG msg;
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
if (bDone)
{
break;
}
完整代码
#include <windows.h>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY: // 窗口销毁消息
{
PostQuitMessage(0); // 发送退出消息
}
break;
}
// 其他的消息调用缺省的消息处理程序
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
int main()
{
WNDCLASSEXW wc = { sizeof(wc), CS_CLASSDC, WindowProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, L"Example", NULL };
::RegisterClassExW(&wc);
HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"D", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
::ShowWindow(hwnd, SW_SHOWDEFAULT);
::UpdateWindow(hwnd);
bool bDone = false;
while (true)
{
MSG msg;
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
if (bDone)
{
break;
}
}
return 0;
}
窗口的效果
由于什么操作都没有做,得到的窗口是一个全白带有窗口最小化最大化关闭的界面
创建指定画面大小,不包含窗口栏尺寸且无法调整尺寸的窗口
//窗口尺寸无法修改
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
WNDCLASSEXW stAvmWndClass = { sizeof(stAvmWndClass), CS_CLASSDC, WindowProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, L"AVM", NULL };
::RegisterClassExW(&stAvmWndClass);
RECT stWindowRect = { 0,0,g_nWidth,g_nHeight };
AdjustWindowRect(&stWindowRect, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, FALSE);//调节窗口尺寸,设置WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX窗口尺寸无法修改
int nWindowActuralWidth = stWindowRect.right- stWindowRect.left;
int nWindowActuralHeight = stWindowRect.bottom - stWindowRect.top;
HWND pHwndAVM = ::CreateWindowW(stAvmWndClass.lpszClassName, L"AVM", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 100, 100, nWindowActuralWidth, nWindowActuralHeight, NULL, NULL, stAvmWndClass.hInstance, NULL);
::ShowWindow(pHwndAVM, SW_SHOWDEFAULT);
::UpdateWindow(pHwndAVM);
在这里插入代码片
思考
在linux是否有hwnd句柄这一概念,linux上的窗口界面怎么创建显式渲染画面呢?
linux上使用X11
实现窗口的创建,一般结合glx
或者egl
来实现中间层的构建
XMapWindow 函数可以让一个已经创建但是还没有显示出来的窗口在屏幕上可见,作用于Windows上的ShowWindow类似