Window Feature 学习
从msdn上看到一篇文章,ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.WIN32COM.v10.en/winui/winui/windowsuserinterface/windowing/windows/windowfeatures.htm。文中主要讲一些windows窗口的基本知识,以及一些窗口的消息流程,对我这样对window系统不熟的人来说,感觉收获还是不小。做个学习笔记,强化一下记忆。
Window的窗口类型(Window Type)
Overlapped Windows
在window的头文件中,这种类型定义如下
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | \
WS_CAPTION | \
WS_SYSMENU | \
WS_THICKFRAME | \
WS_MINIMIZEBOX | \
WS_MAXIMIZEBOX)
从定义可以看出,一个Overlapped window是有最大和最小按钮,有系统目录,有标题栏,有ThickFrame的。我们一般创建一个window应用程序,主窗体一般都是使用的这种,用vs2005向导生成的win32程序中,窗体也是使用的这种类型。除了WS_OVERLAPPEDWINDOW这种以外,还有一种称为WS_OVERLAPPED的,文中说这种类型的窗口是有titlebar和边框的。
我用CreateWindowEx创建一个WS_OVERLAPPED的窗口。运行显示,该窗口没有最大,最小和关闭按钮;在标题栏左上角业没有系统菜单;窗体的大小是不可以调整的。我加上WS_THICKFRAME后,大小就可以调增了。
Pop-up Windows
之前对这种窗口是一点概念也灭有,就是现在也不是很确定的。一个Popupwindow是一种特殊的overlapped窗口。 对于要出现在程序主窗口之外的对话框、message box等都使用这中类型。这种窗口的titlebar是可选的。否则就和一个WS_OVERLAPPED一样了。指定这种类型使用WS_POPUP,要加标题栏使用WS_CAPTION;WS_POPUPWINDOW可以创建一个带有边框和菜单的 Popup窗口。
我将vs生成的代码中的WS_OVERLAPPEDWINDOW改成了WS_POPUPWINDOW,程序能够编译运行,但是看不见窗口。?为什么? 下来在研究一下。经过测试发现,当我创建window时指定窗口的大小,而不使用CW_USEDEFAULT时会显示出窗口,难道对于popupwindow的CW_DEFAULT为0? 此时显示出来的窗口是没有标题栏的。
Child windows
有WS_CHILD类型的窗口是一个子窗口。一个子窗口必须要有父窗口的,子窗口不能有菜单。子窗体活动区域限制在父窗口中,而且他在主窗口之前被Destroy。在父窗体show之后才show,父窗体hide之前hide.
关于WS_CLIPCHILDREN,系统不会自动的从父窗口的区域中去除掉子窗口,也就是说父窗口有可能会在子窗口的位置上绘制东西。如果指定了该类型,那么父窗口就不能在子窗口的位置上绘制了。自己试验了一下,在父窗口未设置该样式,那么父窗口会在子窗口的位置上绘制,此时拖动窗体时,会产生闪烁,可以隐现子窗口的位置背后有父窗体绘制的东西,如果指定了,那么父窗口就不绘制子窗体区域,也不会闪烁,nice。
与WS_CLIPCHILDREN类似,WS_CLIPSIBLING的功能是针对兄弟窗口的。使用这两个样式会有性能上的损失。
子窗口可以通过SetParent来更换起父窗口。通过IsChild可以判断一个窗口是不是子窗口。EnumChildWindows会枚举出所有的子窗口。
对于窗口的消息循环,子窗口的消息直接发送给子窗口的窗口处理函数,而不经过父窗口,唯一的例外情况是子窗口被EnableWindow函数给Disabled掉了,此时子窗口的消息将会发送给父窗体。
子窗口一般都应该有一个指定的ID,当其和父窗口通信时,父窗口使用此ID来判断是哪一个此窗口在通信。这个ID可以在CreateWindow是通过hMenu参数传递进去。
Layered window
大概瞅了一下,发现这个窗口类型的内容很多,对我这样初级的还有点用不着,先知道有这么个东西就行了。
Message-Only windows
一个message-only窗口能够接受和发送消息,但是它不可见,没有z-order,也不能被枚举出来,不会接受广播消息。这个窗体只是简单的分发消息。指定HWND_MESSAGE或者一个message-only窗口作为父窗口,那么CreateWindowEx出来的窗口就是一个message-only窗口。通过FindWindowEx窗口可以检出message-only窗口。
窗口间的关系(Window Relationships)
foreground 和background 窗口
一个进程中会有多个执行的线程,而每个线程都可以创建若干窗口。用户当前工作窗口所属的线程称为foreground thread,对应的窗口称为foreground window, 其他的线程为background thread,他们创建的窗口为background window。
用户可以通过点击窗口、按ALT+Tab,ALT+Esc等方式来设置foreground window。通过GetForeGroundWindow可以获取到foreGround window的句柄。 SetForeGroundWindow可以设置,限于一个进程使用?还有一个AllowSetForegroundWindow函数好像也可以用,这个好像可以用来在不能进程间使用。
Owned Windows
这个不知道怎么翻译,应该是被拥有的窗口。一个overlapped或者popup窗体可以被另一个overlapped或者popup窗体。只有一个overlapped或者popup窗体能够称为一个owner窗体。一个子窗体不能成为一个owner窗口。一个owner窗口是一个top-level窗口。所有子窗口的子孙窗口的owner都是这个top-level窗口。
可以通过GetOwner函数(使用GW_OWNER)来得到窗口的owner窗口。
Z-order
这个主要是用来试着窗口之间的层叠关系。
待续。。。。。。。。。。。。。。。。。。。。。。。。