Windows编程基础,第一个Windows程序,注册窗口,创建窗口(下)

简介: Windows编程基础,第一个Windows程序,注册窗口,创建窗口

五.注册窗口类

1.窗口类的概念:

<1>.窗口类包含了窗口各种参数信息的结构

<2>.每个窗口都有一个窗口类,基于窗口类创建窗口

<3>.每个窗口类都有一个名称,使用前必须注册到操作系统内核中

2.窗口的分类

<1>.系统窗口类

系统已经定义好的窗口类,所有应用程序都可以使用,例如Button(按钮),edit(编辑框)

<2>.应用程序全局窗口类

由用户自己定义,当前应用程序所有模块中都可以使用

<3>.应用程序局部窗口类

由用户自己定义,当前应用程序中只有本模块可以使用

3.注册窗口类函数

ATOM RegisterClassExW(
  [in] const WNDCLASSEXW *unnamedParam1
);

在这里带大家看一下WNDCLASS结构体:

typedef struct tagWNDCLASSA {
  UINT      style;               //窗口风格
  WNDPROC   lpfnWndProc;         //窗口处理函数
  int       cbClsExtra;          //窗口类的附加数据buff的大小
  int       cbWndExtra;          //窗口类的附加数据buff的大小
  HINSTANCE hInstance;           //当前模块的实例句柄
  HICON     hIcon;               //窗口图标句柄
  HCURSOR   hCursor;             //鼠标句柄
  HBRUSH    hbrBackground;       //绘制窗口背景的画刷句柄
  LPCSTR    lpszMenuName;        //窗口菜单的资源id字符串
  LPCSTR    lpszClassName;       //窗口类的名称
} WNDCLASSA, *PWNDCLASSA, *NPWNDCLASSA, *LPWNDCLASSA;

大家也可以在微软的MSDN官方文档中查看:WNDCLASS结构体

4.style窗口类风格

应用程序全局窗口类的注册,需要在窗口类的风格中增加CS_GLOBALECLASS

应用程序局部窗口类,在注册窗口类时,不添加CS_GLOBALECLASS

具体的窗口类风格,大家可以到MSDN官方文档中查看:窗口类风格style

六.创建窗口

我们来看看创建窗口函数:

HWND CreateWindowExW(
  [in]           DWORD     dwExStyle,          //窗口的拓展风格
  [in, optional] LPCWSTR   lpClassName,        //已经注册的窗口类名称
  [in, optional] LPCWSTR   lpWindowName,       //窗口标题栏名称
  [in]           DWORD     dwStyle,            //窗口的基本风格
  [in]           int       X,
  [in]           int       Y,
  [in]           int       nWidth,
  [in]           int       nHeight,            //以上四个参数是决定窗口的位置
  [in, optional] HWND      hWndParent,         //父窗口句柄
  [in, optional] HMENU     hMenu,              //窗口的菜单句柄
  [in, optional] HINSTANCE hInstance,          //当前应用程序实例句柄
  [in, optional] LPVOID    lpParam             //窗口创建时的附加参数
);

这里给出MSDN官方文档地址:CreateWindowExW函数

那么在CreateWindow函数中,具体是如何实现的?

这里先给出一张图,我们围绕这张图来讲解:

CreateWindow函数创建窗口过程:

  • 1:CreateWindow函数内部根据传入的窗口类名称,在应用程序局部窗口类中查找,如果找到与之匹配的,执行2,如果没有找到,执行3
  • 2:比较局部窗口类与创建窗口时传入的HINSTANCE变量,如果相等,说明创建和注册的窗口在同一个模块,创建窗口并返回
  • 3:在应用程序全局窗口类中查找窗口类名称,如果找到,执行4,否则执行5(这时候已经不需要比对hins参数了,因为之前提到了,应用程序全局窗口类当前应用程序任何一个模块都可以使用
  • 4:使用找到的窗口类信息,创建窗口并且返回
  • 5:在系统窗口类中查找,如果找到,创建窗口并且返回(这时候已不需要比对hins参数,理由同上),如果未找到,创建创库失败,返回0。
    这里给大家一段伪代码,表示创建窗口的过程:
CreateWindow(各种参数){
  匹配查找窗口类,即上述过程
  if(找到了){
    申请一块内存,将窗口的数据存该内存(该数据包括两部分,CreateWindow函数的参数和找到的窗口类信息)
    return 本内存句柄;
  }else{
  return 0;

七.无法正常关闭窗口问题

当我们写出第一个windows程序的时候,我们点击程序的关闭按钮,发现程序是不显示了,但是在任务管理器中仍然存在,说明我们的应用程序没有正常关闭。

我们来看看,为什么没有正常关闭?没有正常关闭的话,我们的程序停在了哪?

我们发现在代码的消息处理函数中有这样一段代码:

MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd,NULL, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return (int) msg.wParam;
}

我们可以发现我们的程序肯定停在了while循环中,我们分析发现,如果GetMessage函数返回值为0,那么程序就可以正常关闭,那么我们如何让GetMessage函数的返回值变为零呢?

我们可以将窗口处理函数这样写:

switch(msgID){
  case WM_DESTORY:{
    PostQuitMessage(0);
    break;
  }
}

这样我们写的应用程序就可以正常退出了,至于这其中的原理,我们会在后续章节中讲解到。

八.子窗口创建过程

子窗口的创建很简单,我们只需要满足两个条件;

  • 1.创建窗口时设置父窗口句柄
  • 2.创建窗口时,在style参数中加入WS_WHILD|WS_VISIBLE即可。
相关文章
|
3天前
|
Windows
[原创]用MASM32编程获取windows类型
[原创]用MASM32编程获取windows类型
|
4天前
|
JavaScript 前端开发 API
MASM32编程通过WMI获取Windows计划任务
MASM32编程通过WMI获取Windows计划任务
|
5天前
|
Windows Python
python获取windows机子上运行的程序名称
python获取windows机子上运行的程序名称
|
3天前
|
安全 网络安全 API
基于WMI更新Windows系统信息采集程序sysInfo的一些收获
基于WMI更新Windows系统信息采集程序sysInfo的一些收获
|
3天前
|
网络协议 API Windows
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
|
5天前
|
API Windows
MASM32编程获取Windows当前桌面主题名
MASM32编程获取Windows当前桌面主题名
|
5天前
|
小程序 Windows
MASM32编写的程序在Windows 7,10下运行正常,但在Win XP下运行时只闻其声不见其形的故障
MASM32编写的程序在Windows 7,10下运行正常,但在Win XP下运行时只闻其声不见其形的故障
|
Shell Windows
Windows 注册和取消注册一个dll或者ocx
原文: Windows 注册和取消注册一个dll或者ocx   一、DLL是什么        DLL,是Dynamic Link Library 的缩写形式,中文名称为动态链接库。        DLL是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。
1405 0
|
28天前
|
网络安全 虚拟化 Windows
windows 11安装openSSH server 遇到的"kex_exchange_identification: read: Connection reset"问题
windows 11安装openSSH server 遇到的"kex_exchange_identification: read: Connection reset"问题
|
2月前
|
PHP Windows
【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误
【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误