• 技术文章 >运维 >windows运维

    Win32 SDK基础(五)之关于窗口类的简单介绍

    黄舟黄舟2017-06-06 09:42:55原创1443

    一、引言

    在上一文中,我们从零开始创建了一个窗口。其中很重要的一个步骤,就是注册窗口类,如下面的代码:

    //注册窗口类
    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和作用域上有分别,这里就不再详述,如要了解,请参照上一文。

    以上就是Win32 SDK基础(五)之关于窗口类的简单介绍的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:Win32 SDK基础(四)之如何从零开始创建windows窗口的第二步 下一篇:Win32 SDK基础(六)之详解窗口类的查找过程和相关API

    相关文章推荐

    • 升级PowerShell的方法(图文步骤)• Windows7安装OpenSSH服务的步骤详解(亲测有效)• 重装win7系统的过程 • IIS7.0在win2008下的安装配置教程(图文)• Win2008 r2下修改mysql data目录的方法详细介绍

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网