【OpenGL】七、桌面窗口搭建 ( 导入头文件 | 桌面程序入口函数 | 注册窗口 | 创建窗口 | 显示窗口 )
文章目錄
- 一、導入頭文件
- 二、桌面程序入口函數
- 三、注冊窗口
- 四、創建窗口
- 五、顯示窗口
- 六、完整代碼示例
- 七、相關資源
基于 【OpenGL】一、Visual Studio 2019 創建 Windows 桌面程序 ( Visual Studio Installer 安裝 C++ 桌面開發庫 | 創建桌面程序 ) 博客中創建的 Windows 桌面程序繼續向下講解 , Visual Studio 自動生成了空白的桌面程序 , OpenGL 系列開發基于該桌面程序進行 ;
本篇博客簡單介紹下該桌面初始化的操作 , 注冊桌面窗口 , 創建桌面窗口 , 顯示桌面窗口 ;
一、導入頭文件
Windows 窗口程序需要導入 windows.h 頭文件 ;
// Windows 頭文件 #include <windows.h>下面的代碼時 Visual Studio 創建桌面程序時 , 自動生成的頭文件 , 其中包含了 windows.h 頭文件 ;
// header.h: 標準系統包含文件的包含文件, // 或特定于項目的包含文件 //#pragma once#include "targetver.h" #define WIN32_LEAN_AND_MEAN // 從 Windows 頭文件中排除極少使用的內容 // Windows 頭文件 #include <windows.h> // C 運行時頭文件 #include <stdlib.h> #include <malloc.h> #include <memory.h> #include <tchar.h>二、桌面程序入口函數
Windows 桌面程序的入口 是 wWinMain 函數 ,
該函數相當于命令行程序中的 void main() 函數 ;
完整的 wWinMain 函數格式 :
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR lpCmdLine,_In_ int nCmdShow)三、注冊窗口
使用 WNDCLASSEXW 結構體注冊窗口 ;
WNDCLASSEXW 結構體代碼如下 :
typedef struct tagWNDCLASSEXW {UINT cbSize;/* Win 3.x */UINT style;WNDPROC lpfnWndProc;int cbClsExtra;int cbWndExtra;HINSTANCE hInstance;HICON hIcon;HCURSOR hCursor;HBRUSH hbrBackground;LPCWSTR lpszMenuName;LPCWSTR lpszClassName;/* Win 4.0 */HICON hIconSm; } WNDCLASSEXW, *PWNDCLASSEXW, NEAR *NPWNDCLASSEXW, FAR *LPWNDCLASSEXW;下面是該結構體各個字段的含義 :
- style : 窗口風格 ;
- lpfnWndProc : 設置消息響應函數 , 如響應鼠標 , 鍵盤事件 ;
- cbWndExtra : 窗口是否需要額外空間 ;
- hInstance : 窗口實體 , 通過桌面程序入口函數傳入 ;
- hIcon : 生成的程序在文件夾中的樣式 , 可執行程序的圖標
- hCursor : 設置鼠標光標樣式 ;
- hbrBackground : 設置背景 ;
- lpszMenuName : 設置菜單 ;
- lpszClassName : 設置窗口標識 ;
窗口注冊代碼示例 : 下面的代碼時 Visual Studio 自動身
// // 函數: MyRegisterClass() // // 目標: 注冊窗口類。 // ATOM MyRegisterClass(HINSTANCE hInstance) {// 注冊窗口的結構體WNDCLASSEXW wcex;// 設置結構體的大小wcex.cbSize = sizeof(WNDCLASSEX);// 窗口風格 , CS 是 Class Style 縮寫 , VREDRAW 垂直重繪 , HREDRAW 水平重繪wcex.style = CS_HREDRAW | CS_VREDRAW;// 消息響應函數 , 鼠標點擊窗口 , 或打字字后的回調函數wcex.lpfnWndProc = WndProc;// 不需要額外的空間wcex.cbClsExtra = 0;// 不需要額外的空間wcex.cbWndExtra = 0;// 設置程序的實例, 通過桌面程序入口函數傳入wcex.hInstance = hInstance;// 生成的程序在文件夾中的樣式 , 可執行程序的圖標wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_OPENGL));// 設置鼠標光標樣式wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);// 設置背景wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);// 菜單wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_OPENGL);// 窗口的唯一標識符wcex.lpszClassName = szWindowClass;// 設置窗口運行后顯示在右上角的圖標wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));// 設置完上述參數后 , 最后調用該方法注冊窗口return RegisterClassExW(&wcex); }四、創建窗口
調用 CreateWindowW 方法 , 創建 Windows 窗口 ,
創建完成之后 , 驗證下創建方法返回值 hWnd , 如果創建失敗 , 直接退出 ;
// 創建窗口的核心邏輯HWND hWnd = CreateWindowW(szWindowClass, // 窗口主類szTitle, // 窗口標題名稱WS_OVERLAPPEDWINDOW, // 窗口風格100 , // x 坐標100 , // y 坐標800, // 寬度600, // 高度nullptr, // 父窗口 nullptr, // 菜單hInstance, // 程序實體nullptr);// 如果創建失敗 , 直接退出if (!hWnd){return FALSE;}五、顯示窗口
創建完成后 , 顯示窗口 ;
// 顯示窗口ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);六、完整代碼示例
Windows 窗口完整代碼 , 這是 Visual Studio 自動生成的代碼 ;
// OpenGL.cpp : 定義應用程序的入口點。 // 窗口程序入口 // 代碼提交測試#include "framework.h" #include "OpenGL.h"#define MAX_LOADSTRING 100// 全局變量: HINSTANCE hInst; // 當前實例 WCHAR szTitle[MAX_LOADSTRING]; // 標題欄文本 WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口類名 // 此代碼模塊中包含的函數的前向聲明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);int APIENTRY wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR lpCmdLine,_In_ int nCmdShow) {UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);// TODO: 在此處放置代碼。// 初始化全局字符串LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadStringW(hInstance, IDC_OPENGL, szWindowClass, MAX_LOADSTRING);// 注冊窗口MyRegisterClass(hInstance);// 執行應用程序初始化:// 創建窗口if (!InitInstance (hInstance, nCmdShow)){return FALSE;}// 下面的邏輯是一個死循環 , 避免讓窗口退出 HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_OPENGL));MSG msg;// 主消息循環:while (GetMessage(&msg, nullptr, 0, 0)){if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){TranslateMessage(&msg);DispatchMessage(&msg);}}return (int) msg.wParam; }// // 函數: MyRegisterClass() // // 目標: 注冊窗口類。 // ATOM MyRegisterClass(HINSTANCE hInstance) {// 注冊窗口的結構體WNDCLASSEXW wcex;// 設置結構體的大小wcex.cbSize = sizeof(WNDCLASSEX);// 窗口風格 , CS 是 Class Style 縮寫 , VREDRAW 垂直重繪 , HREDRAW 水平重繪wcex.style = CS_HREDRAW | CS_VREDRAW;// 消息響應函數 , 鼠標點擊窗口 , 或打字字后的回調函數wcex.lpfnWndProc = WndProc;// 不需要額外的空間wcex.cbClsExtra = 0;// 不需要額外的空間wcex.cbWndExtra = 0;// 設置程序的實例, 通過桌面程序入口函數傳入wcex.hInstance = hInstance;// 生成的程序在文件夾中的樣式 , 可執行程序的圖標wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_OPENGL));// 設置鼠標光標樣式wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);// 設置背景wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);// 菜單wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_OPENGL);// 窗口的唯一標識符wcex.lpszClassName = szWindowClass;// 設置窗口運行后顯示在右上角的圖標wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));// 設置完上述參數后 , 最后調用該方法注冊窗口return RegisterClassExW(&wcex); }// // 函數: InitInstance(HINSTANCE, int) // // 目標: 保存實例句柄并創建主窗口 // // 注釋: // // 在此函數中,我們在全局變量中保存實例句柄并 // 創建和顯示主程序窗口。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) {hInst = hInstance; // 將實例句柄存儲在全局變量中// 創建窗口的核心邏輯HWND hWnd = CreateWindowW(szWindowClass, // 窗口主類szTitle, // 窗口標題名稱WS_OVERLAPPEDWINDOW, // 窗口風格100 , // x 坐標100 , // y 坐標800, // 寬度600, // 高度nullptr, // 父窗口 nullptr, // 菜單hInstance, // 程序實體nullptr);// 如果創建失敗 , 直接退出if (!hWnd){return FALSE;}// 顯示窗口ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);return TRUE; }// // 函數: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目標: 處理主窗口的消息。 // // WM_COMMAND - 處理應用程序菜單 // WM_PAINT - 繪制主窗口 // WM_DESTROY - 發送退出消息并返回 // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {switch (message){case WM_COMMAND:{int wmId = LOWORD(wParam);// 分析菜單選擇:switch (wmId){case IDM_ABOUT:DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);break;case IDM_EXIT:DestroyWindow(hWnd);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}}break;case WM_PAINT:{PAINTSTRUCT ps;HDC hdc = BeginPaint(hWnd, &ps);// TODO: 在此處添加使用 hdc 的任何繪圖代碼...EndPaint(hWnd, &ps);}break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0; }// “關于”框的消息處理程序。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {UNREFERENCED_PARAMETER(lParam);switch (message){case WM_INITDIALOG:return (INT_PTR)TRUE;case WM_COMMAND:if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL){EndDialog(hDlg, LOWORD(wParam));return (INT_PTR)TRUE;}break;}return (INT_PTR)FALSE; }七、相關資源
GitHub 地址 : https://github.com/han1202012/OpenGL
博客源碼快照 : https://download.csdn.net/download/han1202012/14503846
總結
以上是生活随笔為你收集整理的【OpenGL】七、桌面窗口搭建 ( 导入头文件 | 桌面程序入口函数 | 注册窗口 | 创建窗口 | 显示窗口 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android Binder 系统】一
- 下一篇: 【OpenGL】八、初始化 OpenGL