一、引言
在上一文中,我们从零开始创建了一个窗口。其中很重要的一个步骤,就是注册窗口类,如下面的代码:
//注册窗口类 BOOL Register(LPSTR lpClassName, WNDPROC wndProc) { WNDCLASSEX wce = { 0 }; wce.cbSize = sizeof(wce); wce.cbClsExtra = 0; wce.cbWndExtra = 0; wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wce.hCursor = NULL; wce.hIcon = NULL; wce.hIconSm = NULL; wce.hInstance = g_hInstance; wce.lpfnWndProc = wndProc; wce.lpszClassName = lpClassName; wce.lpszMenuName = NULL; wce.style = CS_HREDRAW | CS_VREDRAW; ATOM nAtom = RegisterClassEx(&wce); if (nAtom == 0) return FALSE; return true; }
Windows下的任何一个窗口,在创建之前都要在系统中已经明确的注册,我们在使用CreateWindowEx进行窗口的创建时,第二个参数的名称就是窗口类名称,这个名称在我们代码可见的作用域内应该是唯一的。本文主要讨论下Windows下,窗口类的问题。
二、窗口类分类
Windows中所有可见的一切元素基本上都属于一个窗口,不管它的形状如何,是圆的、方的、甚至是无规则的。所有的这些窗口都属于某一个窗口类,大体上来说Windows的窗口类共分为三种:
(1)系统窗口类
(2)全局窗口类
(3)局部窗口类
下面,我将就Windows中窗口类的分类分别进行讨论。
2.1 系统窗口类
一个按钮、一个编辑框所有这些我们在windows操作系统中可见的控件其实都是一个窗口。当我们安装完操作系统之后,Windows会在操作系统内部注册大量的系统级别的窗口类,我们在进行开发时,可以直接根据窗口类名称创建这些窗口。为了解释这个问题,在上一文中的代码之上,我们引入下面的代码。
HWND CreateMain(LPSTR lpClassName, LPSTR lpWndName) { HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, g_hInstance, NULL); return hWnd; } int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { // TODO: Place code here. g_hInstance = hInstance; HWND hWnd = CreateMain("Button", "window"); Display(hWnd); Message(); return 0; }
CreateMain是我们定义的一个创建窗口的函数。它接收两个参数,第一个时已经注册的窗口类名称,第二个是窗口的标题。与上一文中的代码不同,我们省去了注册自定义窗口的步骤。而是在WinMain函数中,调用CreateMain创建了一个窗口类名称为“Button”的窗口。我想你已经知道我们要做什么了吧?对,就是要生成一个Button按钮。我们常用的所有控件都已经被操作系统注册成了系统窗口类,我们都可以直接使用。请看下面的程序运行结果:
你还可以尝试去创建诸如编辑框、下拉框等其他系统级别的窗口。
2.2 全局窗口类
全局窗口类指注册之后可以在应用程序全局范围内使用的窗口类。比如,我们可以在dll中对全局窗口类进行注册,那么引入该dll的所有程序都可以使用该类。注册全局使用的窗口类时,我们只需要在注册时对wec的结构体的style成员添加CS_GLOBALCLASS属性,如下:
wce.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
为了验证这个问题,我们新添加一个dll项目,然后定义一个如下的窗口注册函数RegisterWindow():
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 break; default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } BOOL RegisterWindow() { WNDCLASSEX wce = { 0 }; wce.cbSize = sizeof(wce); wce.cbClsExtra = 0; wce.cbWndExtra = 0; wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wce.hCursor = NULL; wce.hIcon = NULL; wce.hIconSm = NULL; wce.hInstance = NULL; wce.lpfnWndProc = WndProc; wce.lpszClassName = "DllMain"; wce.lpszMenuName = NULL; wce.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS; ATOM nAtom = RegisterClassEx(&wce); if (nAtom == 0) return FALSE; return true; }
RegisterWindow()中注册的窗口类名称为"DllMain",我们在dll的主函数中调用该注册函数完成注册:
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { .... RegisterWindow(); return TRUE; } }
在我们的主程序中使用该窗口类创建窗口:
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { ... HWND hWnd = CreateMain("DllMain", "我是一个Dll注册的窗口"); Display(hWnd); Message(); return 0; }
运行程序你会发现我们也成功生产了这个窗口:
2.3 局部窗口类
局部窗口类从定义上来说,凡是未在wce的style中添加CS_GLOBALCLASS,而注册的窗口类都是局部窗口类。
wce.style = CS_HREDRAW | CS_VREDRAW;//未添加CS_GLOBALCLASS
我们在上一文中注册的窗口就是一个局部的窗口类,它的特点就是只能在注册的作用域内使用,由于它和全局窗口类只在注册的style和作用域上有分别,这里就不再详述,如要了解,请参照上一文。
Atas ialah kandungan terperinci Win32 SDK基础(五)之关于窗口类的简单介绍. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver Mac版
Alat pembangunan web visual

VSCode Windows 64-bit Muat Turun
Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft

Muat turun versi mac editor Atom
Editor sumber terbuka yang paling popular

SecLists
SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.
