《windows核心编程》(五)-----------2013.7.31
一、概念
窗口的注册
•窗口类
窗口类包含了窗口的各种参数信息的数据结构。每个窗口都具有窗口类,基于窗口类创建窗口。每个窗口类都具有一个名称,使用前必须注册到系统。
•窗口类的分类
-系统窗口类
系统已经定义好的窗口类,所有应用程序都可以直接使用。
-应用程序全局窗口类
由用户自己定义,当前应用程序所有模块都可以使用。
-应用程序局部窗口类
由用户自己定义,当前应用程序中本模块可以使用
系统窗口类的注册
•不需要注册,直接使用窗口类即可。系统
已经定义好相应名称,例如:
按钮 - BUTTON
编辑框 - EDIT
创建BUTTON:
创建EDIT:
创建BUTTON:
// WinReg.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "WinReg.h"
#include "windows.h"
HINSTANCE g_hInstance = 0;
void SysReg()
{
HWND hWnd = CreateWindow("BUTTON","OK",WS_OVERLAPPEDWINDOW,
100,100,500,500,NULL,NULL,g_hInstance,NULL);
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
MSG nMsg = {0};
while(GetMessage(&nMsg,NULL,0,0))
{
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
g_hInstance = hInstance;
SysReg();
return 0;
}
创建EDIT:
// WinReg.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "WinReg.h"
#include "windows.h"
HINSTANCE g_hInstance = 0;
void SysReg()
{
HWND hWnd = CreateWindow("EDIT","OK",WS_OVERLAPPEDWINDOW,
100,100,500,500,NULL,NULL,g_hInstance,NULL);
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
MSG nMsg = {0};
while(GetMessage(&nMsg,NULL,0,0))
{
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
g_hInstance = hInstance;
SysReg();
return 0;
}
应用程序全局窗口类的注册
•RegisterClass/RegisterClassEx
ATOM RegisterClass(
CONST WNDCLASS *lpWndClass //窗口类的数据
); 注册成功后,返回一个数字标识;注册失败后,返回0。
•ATOM RegisterClassEx(
CONST WNDCLASSEX *lpwcx //窗口类的数据
);
•typedef struct _WNDCLASSEX {
• UINT cbSize; //结构体的大小
(新增)
• UINT style; //窗口类的风格
• WNDPROC lpfnWndProc; //窗口处理函数
• int cbClsExtra; //窗口类的附加数据
• int cbWndExtra; //窗口的附加数据
• HINSTANCE hInstance; //当前模块的实例句柄
• HICON hIcon; //窗口图标句柄
• HCURSOR hCursor; //鼠标的句柄
• HBRUSH hbrBackground; //绘制窗口背景的画刷句柄
• LPCTSTR lpszMenuName; //窗口菜单的资源ID字符串
• LPCTSTR lpszClassName; //窗口类的名称
• HICON hIconSm; //窗口的小图标句柄
(新增)
•} WNDCLASSEX, *PWNDCLASSEX;
•应用程序全局窗口类的注册,需要在窗口类的风格中增加 CS_GLOBALCLASS,例如:
WNDCLASSEX wce = {0};
wce.style = CS_GLOBALCLASS;
•应用程序局部窗口类
在注册窗口类时,不添加CS_GLOBALCLASS风格。
窗口类的风格
CS_GLOBALCLASS - 应用程序全局窗口类
CS_BYTEALIGNCLIENT - 窗口客户区的水平位置8倍数对齐
CS_BYTEALIGNWINDOW - 窗口的水平位置8倍数对齐
CS_HREDRAW - 当窗口水平变化时,窗口重新绘制
CS_VREDRAW - 当窗口垂直变化时,窗口重新绘制
CS_CLASSDC - 该类型的窗口,都是有同一个绘图(DC)设备
CS_PARENTDC - 该类型的窗口,使用它的父窗口的绘图(DC)设备
CS_OWNDC - 该类型的窗口,每个窗口都使用自己的绘图(DC)设备
CS_SAVEBITS - 允许窗口保存成图(位图),提高窗口的绘图效率,但是耗费内存资源
CS_DBLCLKS - 允许窗口接收鼠标双击
CS_NOCLOSE - 窗口没有关闭按钮
窗口类的查找过程
(重要)
1 系统根据传入的窗口类名称,在应用程序局部窗口类中查找,如果找到执行2,如果未找到执行3。
2 比较局部窗口类与创建窗口时传入的HINSTANCE变量。如果发现相等,创建和注册的窗口类在同一模块,创建窗口返回。如果不相等,继续执行3。
3 在应用程序全局窗口类,如果找到,执行4,如果未找到执行5。
4 使用找到的窗口类的信息,创建窗口返回。
5 在系统窗口类中查找,如果找到创建窗口返回,否则创建窗口失败。
相关API
注册一个窗口:
•RegisterClass/RegisterClassEx 注册
•GetClassInfo 获取信息
•UnregisterClass 卸载
注册一个窗口:
// WinReg.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "WinReg.h"
#include "windows.h"
HINSTANCE g_hInstance = 0;
void AppReg()
{
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 = DefWindowProc;
wce.lpszClassName = "Main";
wce.lpszMenuName = NULL;
wce.style = CS_HREDRAW | CS_VREDRAW;
ATOM nAtom = RegisterClassEx(&wce);
if(nAtom == 0)
{
MessageBox(NULL,"注册失败","Infor",MB_OK);
return;
}
HWND hWnd = CreateWindow("Main","Window",WS_OVERLAPPEDWINDOW,
100,100,500,500,NULL,NULL,g_hInstance,NULL);
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
MSG nMsg = {0};
while (GetMessage(&nMsg,NULL,0,0))
{
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
g_hInstance = hInstance;
AppReg();
return 0;
}