-Window Classes分类
预定义窗口类:
1.窗口类类别
1.1.系统类—由系统注册
Button–按钮
ComboBox–组合框
Edit–编辑框
ListBox–列表框
MDIClient–MDI客户框
ScrollBar–滚动条
Static–静态框
1.2.应用全局类
由exe或DLL注册,可被所有进程其它模块使用。
写一个DLL,注册此类。
在注册表路径
HKEY_LOCAL_MACHINE\ Software\ Microsoft\ Windows NT\ CurrentVersion\ Windows
键值AppInit_DLLs 里加上dll名字。
DLL须在初始化处理注册此类,指定CS_GLOBALCLASS 类型。
1.2.应用本地类
EXE或DLL中注册,仅供应用自身使用。
不同模块可用相同名,注册同一进程的本地类。
类的注册:
RegisterClass[Ex]
撤销注册:
UnregisterClass
WNDCLASSEX:
类名
窗口处理函数
实例句柄(注册类的exe或dll,窗口处理函数也在此模块)
鼠标光标
大小图标
背景画刷(填充客户区的颜色,模式)
默认的窗口菜单
风格
系统应该预留给类的额外内存大小
系统应该预留给类的每个窗口的额外内存大小
-CreateWindowEx:
1.扩展风格
2.类名–字符串/类原
自定义类名/预定义类名
3.窗口名
有标题栏时,标题栏显示窗口名。
按钮,复选,静态控件,指定控件内容。
静态控件+SS_ICON,指定图标名/ID(# num)
4.窗口风格
5/6/7/8.x
overlapped or pop-up ,左上角(屏幕坐标)
child (相对于父窗口客户端左上角)
CW_USEDEFAULT (窗口为overlapped才有意义)
9.父窗口/拥有窗口。
对pop-up,是可选参数。
10.菜单句柄/子窗口ID。
overlapped or pop-up ,菜单句柄
child,子窗口ID
11.实例句柄
关联与窗口的模块的实例句柄。
12.可传递给窗口的参数(WM_CREATE)
-可用类名直接使用的预定义类
1.BUTTON
2.COMBOBOX
3.EDIT
4.LISTBOX
5.MDICLIENT
6.RichEdit
7.RICHEDIT_CLASS
8.SCROLLBAR
9.STATIC
每个预定义类的使用手册,可见:帮助–收藏。
-窗口特性
窗口类型,状态,尺寸,位置。
1.窗口类型
1.1.Overlapped–WS_OVERLAPPED
顶级窗口,有标题栏,边框,客户区,菜单,最小,最大按钮,滚动条。
一般用作应用主窗口。
1.2.Pop-up–WS_POPUP
适用于对话框,消息框,显示在应用主窗口外的其它临时窗口。
是特殊类型的overlapped窗口。
1.2.Child–WS_CHILD
子窗口的父窗口类型可是Overlapped/Pop-up/Child
子窗口不能有 菜单。
2.Positioning
2.1.子窗口超出父窗口客户区部分会被截断(不会被显示)。
2.2.影响父窗口的行为也影响子窗口。
a.销毁。
先销毁子窗口,再销毁父窗口。
b.隐藏
先隐藏子窗口,再隐藏父窗口。
c.移动
随父窗口客户区移动。
子窗口负责绘制移动后自身客户区的绘制。
d.显示
先显示父窗口,再显示子窗口。
3.Clipping
父窗口在子窗口之上绘制时,如果父窗口有WS_CLIPCHILDREN 风格,父窗口不能在子窗口上区域绘制。
同一父窗口的各个子窗口,互称兄弟窗口。
兄弟窗口可在另一兄弟窗口区域上绘制。
但子窗口有WS_CLIPSIBLINGS风格时,它的兄弟窗口,不能在该子窗口区域上绘制。
4.Relationship to Parent Window
可通过SetParent改变现存子窗口的父窗口。
这时,系统从老父窗口的客户区移除子窗口。
将其移动到新父窗口的客户区。
父窗口指定为NULL时,已桌面窗口作为父窗口。
0:父窗口–1:子窗口–2:子窗口的子窗口-….
1,2,…都是0的后继窗口。
IsChild判断,一个给定的窗口是不是一个窗口的子窗口或后继窗口。
EnumChildWindows,枚举窗口的所有子窗口,后继窗口也被枚举。(
会传递窗口句柄给应用定义的回调函数。)
5.Messages
系统把子窗口的输入消息直接传递到子窗口。
唯一例外是,如果子窗口,被禁用。这时,系统把本来要传递给子窗口的输入消息,传递给父窗口。
6.Layered Windows–WS_EX_LAYERED
实现窗口模糊–透明效果。
CreateWindowEx 调用后,分层窗口将不会变得可见,
直到SetLayeredWindowAttributes or UpdateLayeredWindow被调用。
BOOL WINAPI SetLayeredWindowAttributes(
In HWND hwnd,
In COLORREF crKey,
In BYTE bAlpha,// 0-255
In DWORD dwFlags// LWA_ALPHA,LWA_COLORKEY
);
BOOL WINAPI UpdateLayeredWindow(
In HWND hwnd,
In_opt HDC hdcDst,
In_opt POINT *pptDst,
In_opt SIZE *psize,
In_opt HDC hdcSrc,
In_opt POINT *pptSrc,
In COLORREF crKey,
In_opt BLENDFUNCTION *pblend,
In DWORD dwFlags
);
7.Message-Only Windows
使你可以发送,接收消息。
不可见,无Z序,不能被枚举,不接收广播消息,仅仅分发消息。
在CreateWindowEx中,通过给hWndParent参数指定HWND_MESSAGE常量或指定一个已存在的此类窗口的句柄来创建。
也可把已存在窗口的父窗口修改为HWND_MESSAGE来实现。
可通过FindWindowEx,hWndParent参数指定为HWND_MESSAGE来搜索。
8.窗口关系
8.1.前台和后台窗口
进程有多个可执行线程。
每个线程可创建窗口。
线程,创建了窗口,用户当前正在用此窗口,
这个线程称为前台线程,这个窗口称为前台窗口。
其它线程,称为后台线程,由后台线程创建的窗口称为后台窗口。
前台线程优先级略高于后台线程。
GetForegroundWindow,取得前台窗口的句柄。可以将应用窗口句柄和此函数返回句柄比较来检查应用窗口是否为前台窗口。
SetForegroundWindow。
系统在进程满足以下任一条件时,才允许进程用SetForegroundWindow,编程方式设置前台窗口。
a.进程是前台进程。
b.进程由前台进程启动。
c.进程接收了最后输入事件。
d.没有前台进程。
e.前台进程正在被调试。
f.前台未被锁定。
g.前台锁定超时。
可设置前台窗口的进程可使另一进程也能设置前台窗口,通过以下方式:
a.AllowSetForegroundWindow。
b.BroadcastSystemMessage + BSF_ALLOWSFW。
可禁用SetForegroundWindow,通过:
LockSetForegroundWindow。
9.Owned Windows
一个overlapped or pop-up 窗口,可被另一overlapped or pop-up 窗口拥有。
被拥有,给窗口增加了几个限制:
a.被拥有的窗口通常在Z序上高于它的拥有者。
b.系统自动销毁被拥有窗口,当它的拥有者被销毁时。
c.被拥有窗口将被隐藏,当它的拥有窗口被最小化时。
拥有关系的建立:
CreateWindowEx + WS_OVERLAPPED/WS_POPUP + hWndParent指定为拥有窗口句柄。
hWndParent应该是overlapped or pop-up风格的窗口,为child时,指定此child的顶级父窗口作为拥有窗口。
拥有关系一旦建立,不可变更。
对话框/消息框–最常见的被拥有窗口。
GetWindow + GW_OWNER:取得窗口拥有者句柄。
10.Z-Order
系统维护Z序,在一个单独的列表里。
系统确定窗口Z序位置,基于:
窗口类别: topmost windows, top-level windows, or child windows
topmost window ,置于其它non-topmost windows之上,无论它们是否活动或前台窗口。
topmost window—WS_EX_TOPMOST 。
BringWindowToTop,让窗口到Z序顶部。如果窗口是top-level ,则它被激活。如果是child,它的顶级父窗口被激活。
BOOL WINAPI SetWindowPos(
In HWND hWnd,
// 窗口句柄或以下值
// HWND_BOTTOM 其它窗口—本窗口
// HWND_NOTOPMOST topmost 窗口–本窗口–其它窗口
// HWND_TOP 本窗口—其它窗口
// HWND_TOPMOST
In_opt HWND hWndInsertAfter,
// 定义位置,尺寸
In int X,
In int Y,
In int cx,
In int cy,
// SWP_DRAWFRAME 绘制边框
// SWP_HIDEWINDOW 隐藏窗口
// SWP_SHOWWINDOW 显示窗口
// SWP_NOACTIVATE 改变Z序,不额外激活
// SWP_NOMOVE 忽略X/Y
// SWP_NOSIZE 忽略cx/cy
// SWP_NOZORDER 忽略hWndInsertAfter
// SWP_NOOWNERZORDER 不改变拥有窗口在Z序位置
In UINT uFlags
);
用SetWindowLong改变窗口数据后,SetWindowPos使改变生效。
11.Window Show State
11.1.Active Window
应用的top-level window ,用户当前正操作的。
位于Z序顶部,边框/标题栏为系统定义激活色。
只有top-level window 可成为Active Window。
用户操作子窗口时,子窗口的父窗口被激活。
系统中同时,只有一个顶级窗口被激活。
GetActiveWindow:得到激活窗口句柄。
由应用A的 top-level window 被激活转为应用B的 top-level window 被激活,系统发送 WM_ACTIVATEAPP 消息给两个应用。
激活由一个应用内的 top-level window A转向top-level window B时,系统给两个窗口发送WM_ACTIVATE 。
11.2.Disabled Windows
一个禁用的窗口不能接收来自用户的键盘/鼠标消息,
但能接收来自其它窗口,其它应用,其它系统的。
系统发送WM_ENABLE给窗口,当它的enabled state 将变化时。
EnableWindow/IsWindowEnabled。
子窗口被禁用时,系统传递子窗口的鼠标输入消息给父窗口。
同一时刻,只有一个窗口可接收键盘输入。那个窗口–有键盘焦点的窗口。
如果应用用EnableWindow禁用一个键盘焦点窗口,窗口被禁用,同时失去键盘焦点。
键盘焦点此时为NULL,即没有窗口有焦点。
如果子窗口或后继窗口有键盘焦点,父窗口被禁用时,子窗口或后继窗口被禁用且丢失键盘焦点。
11.3.Window Visibility
一个隐藏的窗口可处理来及系统或其它窗口的消息,但不能处理用户输入或显示输出。
当拥有窗口最小化时,系统自动隐藏关联的被拥有窗口。恢复时,类似。
两种情况下,系统均给被拥有窗口发送:WM_SHOWWINDOW。
11.4.Minimized, Maximized, and Restored Windows
11.5.Window Size and Position
系统发送WM_GETMINMAXINFO给窗口,当它的大小或位置要变化时。
可设置MINMAXINFO来实现尺寸定制。
WS_THICKFRAME or WS_CAPTION 风格窗口才能接收WM_GETMINMAXINFO。
系统发送WM_WINDOWPOSCHANGING 给窗口,当它的尺寸,位置,Z序位置,显示状态将
变化时。消息包含一个指向WINDOWPOS结构指针,来指定新的尺寸,位置,Z序位置,显示状态。
系统发送WM_WINDOWPOSCHANGED 给窗口,当它的尺寸,位置,Z序位置,显示状态已经
变化时。
11.6.Window Animation
使用AnimateWindow 可让显示/隐藏窗口时,产生特殊效果。
BOOL WINAPI AnimateWindow(
In HWND hwnd,
In DWORD dwTime,// 动画时间
// AW_ACTIVATE
// AW_HIDE
// AW_BLEND 褪色,top-level 窗口可用
// AW_CENTER
// AW_SLIDE
// AW_HOR_POSITIVE
// AW_HOR_NEGATIVE
// AW_VER_POSITIVE
// AW_VER_NEGATIVE
In DWORD dwFlags
);
11.7.Window Layout and Mirroring
某些语言下,排列顺序从右到左时,使用。
11.8.Window Destruction
销毁一个窗口也销毁窗口的后继窗口。
DestroyWindow先发送WM_DESTROY给窗口,再发给它的子窗口和后继窗口。
如果被销毁的窗口是活动窗口,活动和焦点状态被传递到另一个窗口。
ALT+ESC组合键,决定下一个窗口。活动窗口继而决定那个窗口接收键盘焦点。