http://blog.csdn.net/feimashenhua/article/details/5913878
窗口Z次序:表明了重叠窗口堆中窗口的位置,这个窗口堆是按照一个假象的轴定位的,
这个轴是从屏幕向外伸展的Z轴,上面的窗口覆盖下面的窗口。
Windows系统管理三个独立的Z次序----一个用于顶层窗口、一个用于兄弟窗口、还有一个
用于最顶层窗口,最顶层窗口覆盖其他非最顶层窗口,而不管它是不是活动窗口或是前台
窗口。应用程序通过设置WS_EX_TOPMOST风格创建最顶层窗口。
一般情况下,Windows系统把刚刚创建的窗口放在Z次序的顶部,用户可以通过另外一个窗
口来改变Z次序;Windows总是把活动的窗口放在Z次序的顶部,应用程序可以用函数
BringWindowToTop把一个窗口放置到Z次序的顶部。函数SetWindowPos和DeferWindowPos
用来重排Z次序。
兄弟窗口:共享同一个父窗口的子窗口叫做兄弟窗口。
活动窗口:活动窗口是应用程序的顶层窗口,也是当前使用的窗口。只有一个顶层窗口可
以是活动窗口,如果用户使用的是一个子窗口,Windows系统就激活与这个子窗口相应的
顶层窗口。
任何时候系统中只能有一个顶层窗口是活动的。用户通过单击窗口(或其中的一个子窗口
)、使用ALT+TAB或ALT+ESC组合键来激活一个顶层窗口,应用程序则调用函数
SetActiveWindow来激活一个顶层窗口。
前台窗口和后台窗口:
在Windows系统中,每个进程可运行多个线程,每个线程都能创建窗口。创建正在使用的
窗口的线程称之为前台线程,这个窗口也称之为前台窗口。所有其他的线程都是后台线程
,由后台线程所创建的窗口叫做后台窗口。
用户通过单击一个窗口,使用ALT+TAB或ALT+ESC组合键来设置前台窗口,应用程序则用函
数SetForegroundWindow设置前台窗口。如果新的前台窗口是一个顶层窗口,那么Windows
系统就激活它,换句话说,Windows系统激活相应的顶层窗口。
从属窗口在z次序中总是在它的属主窗口的上面。
windows系统在销毁属主窗口时自动地销毁从属窗口。
从属窗门在其属主窗口最小化时是被隐藏
只有覆盖或弹出窗口可以是一个属主窗口,子窗口则不能。
应用程序创建一个从属 窗口是通过在创建具有WS_OVERLAPPED或WS_POPUP风格的窗口时,
把函数CreateWindowEx的参数hwndParent设置成属主窗门的句柄;参数hwndParent必须标
识一个覆盖或弹出窗口。如果hwndParent标识的是一个子窗口,windows系统就会把所属
关系赋给这个子窗口的顶层父窗口。创建了从属窗口之后,应用程序就不能再把窗口的
所属关系传给别的窗口。
对话框和消息框一般是从属窗口,因此应用程序在调用一个函数创建对话框或消息时要指
定的属主窗口
程序可以通过设置GW_OWNER标志来调用GetWindow函数来检索属主窗口的句柄。
被禁止的窗口
窗口是可以被禁止的,被禁止的窗口不再接收键盘或鼠标输入,们它能接收来自其它窗口
,或是来自其它应用程序以及windows系统的消息。应用程序禁止一个窗口是防止用户使
用这个窗口,例如,应用程序可能会禁止对话框中的一个按钮防止用户对它的选择。应用
程序可在任何时候再允许一个被禁止的窗口,允许一个窗口也就恢复了正常的输入。缺省
情况下,一个窗口在刚被创建时是被允许的,但程序能够通过设置WS_DISABLED风格来禁
止一个新窗口。应用程序通过函数EnableWindow允许或禁止一个存在的窗口,windows系
统在窗口的允许状态将要改变时向它发送一条WM_ENABLE消息.应用程序使用函数
IsWindowEnabled以确定—个窗口是否被允许。如果一个于窗口被禁止,windows系统就会
把这个子窗口的鼠标输入传给其父窗口,父窗口通过这条消息确定是否需要允许这个子窗
口。
在同一时间只有一个窗口能够接收键盘输入,也就是说这个窗口拥有键盘焦点。如果应用
程序用函数EnableWindow来禁止一个拥有焦点的窗口.这个窗口在被禁止的同时也失去了
键盘焦点,EnableWindow把键盘焦点设置成NULL,意思是说没有窗口具有焦点。如果一个
子窗口或其它的子孙窗口有了键盘焦点、子孙窗口也会在父窗口被禁止时失去键盘焦点。
前台窗口和后台窗口
每一个进程可运行多个线程,每个线程部能创建窗口。创建正在使用窗口的线程称之为前
台线程,这个窗口就称之为前台窗口。所有其它的线程都是后台线程.由后台线程所创建
的窗门叫后台窗口.
每一个线程都有一个优先等级,它决定了该线程占有cpu的时间。尽管应用程序能够设留
它的线程的优先等级,但通常前台线程具有比后台线程稍高的优先等级.正因为如此,前
台线程所占cpu时间比后台线程要长。通常,前台线程具有的优先级是9,而后台线程是7
。
用户是通过单击一个窗口、使用alt+tab或alt+esc组合键来设置前台窗口,应用程序则用
函数SetForegroundWindow设置前台窗口如果新的前台窗口是一个顶层窗口,那么windows
系统就激活它,换句话说,windows系统激活相应的顶层窗口。应
用程序通过函数GetForegroundWindow来检取前台窗口的句柄。
显示状态
在任何时候,窗口可以是活动的或是被禁止的;隐藏的或是可见的;最小化、最大化或是
被恢复,这些统称为窗口的显示状态。
活动窗口
活动窗口是应用程序的顶层窗口,也就是当前使用的窗口,为了使用户能很容易地识别活
动窗口,windows系统把它放在z次序的顶部,并把标题栏和边框的颜色设置成系统定义的
活动窗口的颜色。只有个顶层窗口可以是活动窗口.如果用户使用的是一个子窗口,
windows系统就激活与这个子窗口相应的顶层窗口。
任何时候系统中只能有一个项层窗口是活动的。用户是通过单击窗口(或其中的一个子窗
口)、使用alt+esc或alt+tab组合键来激活一个顶层窗口,应用程序则调用函数
SetActiveWindow来激活一个顶层窗口,还有另外一些函数windows系统用来激活不同的顶
层窗口包括:SetWindowPos, DeferWindowPos, SetWindowPlacement, 和
DestroyWindow.。尽管一个应用程序也能在任何时候激活一个不同的顶层窗口,但为避
免困惑用户,应该只根据用户的要求做出响应。应用程序通过函数GetActiveWindow来检
取活动窗口的句柄。
如果活动状态从—个应用程序的某个顶层窗口改变到另一个应用程序的顶层窗口,
windows系统就要向两个应用程序发送wM AcrIvATEAl)P消息来通知它们。如果是在同一个
应用程序的不同顶层窗门之间改变活动特性,windows系统就向两个窗口发送WM_ACTIVATE
消息。
可见性
窗口既可以是可见的,也可以被隐藏。windows系统只在屏幕上显示一个可见的窗口,对
隐藏的窗口只是不画它罢了。如果一个窗口是可见的,用户可通过窗口进行输入以及查看
窗口的输出。如果窗口是被隐藏着的,则相当于被有效地禁止了。隐藏的窗口可处理来自
windows系统或其它窗口的消息,但它不能处理用户的输入或是显示输出。应用程序在创
建某项口时就设置了它的可见状态,后面应用程序还可以改变其可见状态。
如果为窗口设置了WS_VISIBLE风格,则窗口是可见的。通常,除非应用程序设置了
WS_VISIBLE风格.否则函数CreateWindowEx只是创建了一个隐藏的窗口。应用程序一般是
在创建了一个窗口之后设置WS_VISIBLE风格,主要是不让用户看到创建过程的细节。例如
,应用程序在定制窗口的外观时,新窗口是被隐藏的。如果在函数CreateWindowEx中指定
了WS_VISIBLE风格,windows系统就会在创建了窗口之后,在显示该窗口之前向它发送
WM_SHOWWINDOW消息.
应用程序可通过函数IsWindowVisible确认一个窗口是否可见,应用程序通过函数
ShowWindow, SetWindowPos, DeferWindowPos, or SetWindowPlacement显示(使可见)或
隐藏一个窗口,这些函数是通过设置或删除窗口的WS_VISIBLE风格来显示或隐藏窗口的,
它们也在显示或隐藏窗口之前向其发送WM_SHOWWINDOW消息。
如果一个属主窗口被最小化了,windows系统会自动隐藏相应的从属窗口。同样,在一个
属主窗口被恢复时,windows系统也会自动地显示相应的从属窗口。这两种情况下.
windows系统都要在隐藏或显示拥有窗口之前,向其发送WM_SHOWWINDOW消息。偶尔,应用
程序也有可能在不最小化或隐藏属主窗口情况下需要隐藏从属窗口.那么应用程序就使用
函数ShowOwnedPopups,这个函数设置或删除所有从属窗口的WS_VISIBLE风格,并在隐藏
或显示拥有窗口之前向它们发送WM_SHOWWINDOW消息.隐藏一个属主窗口并不影响其拥有窗
口的显示状态。
如果一个父窗口是可见的,则与之相应的子窗口也是可见的。同样,在父窗口被隐藏时,
子窗口也被隐藏。最小化父窗口也不影响子窗口的可见状态.这就是说,子窗口也随着父
窗口被最小化,但其WS_VISIBLE风格依然没有改变.
尽管某一个窗口具有WS_VISIBLE风格,用户也有可能在屏幕上看不到这个窗口,因为其它
的窗口可能会完全盖住了它,或是由于移动而超出了屏幕的边沿。一个可见的子窗口也是
遵循由父子关系所建立的裁剪规则的.如果窗口的父窗口是不可见的,那么它也是不可见
的。因为子窗口是相对于其父窗口的左上角,如果父窗口的移动超出了屏幕的边沿,子窗
口也有可能这样。例如,尽管子窗口及其父窗口都具有WS_VISIBLE风格,但如果用户把父
窗口移动到远远超出了屏幕的边沿,用户就不能看到子窗口。
最小最大化和恢复窗口
最大化窗口是具有WS_MAXIMIZE风格的窗口,通常,windows系统会把最大化窗口放大到填
满整个屏幕,如果是子窗口,则可填满父窗口的客户区。尽管窗口的尺寸可被设置成与最
大化窗口一样大,但最大化窗口还是稍有不同的,windows系统会自动地把窗口的标题栏
移到屏幕或父窗口客户区的顶部,wmdows系统还要禁止窗口的改变大小边框和标题栏的窗
口定位能力(这样,用户就不能通过拖动标题栏来移动窗口)。
最小化窗口是具有WS_MINIMIZE风格的窗口,通常,windows系统把窗口的尺寸减少到一个
图符的尺寸,并把它移到屏幕或父窗口客户区的底部,屏幕或父窗口客户区的底部有时叫
做图符区。如果应用程序不设定位置.windows系统则把最小化窗口移到图符区中第一个
可用的位置。恢复窗口是恢复到原来的最小或最大尺寸相位置的窗口。
如果应用程序在函数CreateWindowEx中指定WS_MAXIMIZE or WS_MINIMIZE风格,那么窗口
一开始就是最大化的或是最小化的。在创建了窗口之后,应用程序可通过函数
CloseWindow最小化这个窗口,函数ArrangeIconicWindows用来把最小化的顶层窗口排列
在屏幕的底部,或是把父窗口的最小化的子窗口排列在父窗口客户区的底部。
函数ShowWindow可以最小化、最大化或恢复一个窗口.同时还能设定窗口的可见性和激活
状态,函数SetWindowPlacement与ShowWindow有相同的功能,但它还能屏蔽窗口默认的最
小、最大和被恢复的位置。
函数IsZoomed用来确定一个窗口是否是最大,函数IsIconic确定—个窗口是否是最小化的
。函数GetWindowPlacement检取窗门的最小、最大和被恢复的位置,也能用来确定窗口的
显示状态。
如果windows系统接收到一条最大或恢复最小窗 口的命令,windows系统就向这个窗口发
送一条WM_QUERYOPEN消息,如果窗口过程返回FALSE,windows系统就会忽略这条最大化或
恢复命令。
windows系统自动把最大窗口的尺寸和位置设置成系统定义的最大窗口的默认值,应用程
序能够通过函数SetWindowPlacement ,或是处理windows系统在将要最大化窗口时窗口接
收到的WM_GETMINMAXINFO消息来屏蔽默认值.这条消息含有MINMAXINFO结构的指针.结构
中含有windows系统用来设置最大尺少和位置的值,重置这些值也就改变了默认设置。
尺寸和位置
窗口的尺寸和位置是由一个限定矩形来表示的,它给出了相对于屏幕或父窗口的坐标。这
个坐标是顶层窗口相对于屏幕左上角,或是子窗口相对于父窗口的左上角的坐标.应用程
序在创建窗口时指定窗口的初始尺寸和位置,也可随时改变窗口的尺寸和位置。
窗口的尺寸(宽和高)是以象素为单位的,一个窗口的高度和宽度都可以为o,如果程序把
某个窗口的高度和宽度都置成0,windows系统就把尺寸置成默认的最小窗口尺寸。应用程
序是通过带有SM_CXMIN 和 SM_CYMIN标志的函数GetSystemMetrics来获取最小窗口的默认
尺寸的。
应用程序可能要创建具有一定尺寸的客户区的窗口,函数AdjustWindowRect 和
AdjustWindowRectEx可根据所设计的客户区尺寸来计算所需窗口的尺寸,应用程序再把
计算结果传给函数CreateWindowEx。
应用程序可把窗口的尺寸改变得很大,但最好不要超过屏幕的大小。在设置窗口的尺寸之
前,应用程序应该用带有SM_CXSCREEN and SM_CYSCREEN 标志的函数GetSystemMetrics来
检查屏幕的宽度和高度。
窗口的位置是由它左上角的坐标决定的,这些坐标有时叫做窗口坐标,总是相对于屏幕的
左上角,对于子窗口来说,则是相对于其父窗口客户区的左上角。例如,某个顶层窗口的
坐标是(10,10),那么它就被定位在屏幕左上角向右10个象素,向下10个象素的位置。如
果—个子窗口的坐标是(10,10).那么它就被定位在其父窗口客户区定上角向右10个象素
.向下10个象素的位置。
函数WindowFromPoint用来检取占取屏幕上某一点的窗口的句柄,函数
ChildWindowFromPoint 和 ChildWindowFromPointEx则用来检取占取父窗口客户区中某一
点的子窗口的句柄。
默认的尺寸和位置
应用程序可让windows系统计算一个顶层窗口的初始尺寸相位置,这是通过在函数
CreateWindowEx.中指定CW_USEDEFAULT常量。如果应用程序把窗口的坐标置成
CW_USEDEFAULT,而且应用程序还没有创建别的顶层窗口,windows系统就把新窗口的位置
设置在相对于屏幕左上角的位置上,否则windows系统就把窗口的位置设置在相对于应用
程序最近创建的顶层窗口的位置。同样,如果宽度和高度都设置成CW_USEDEFAULT.
windows系统就会计算新窗口的尺寸,如果应用程序已创建了其它的顶层窗口,windows系
统就根据应用程序最近创建的顶层窗口的尺寸来计算新窗口的尺寸。如果在创建子窗口或
弹出窗口时设置CW_USEDEFAULT风格,那么windows系统就把窗口的尺寸设置成默认的最小
窗口的尺寸.
跟踪尺寸
windows系统管理具有WS_THICKFRAME风格的窗口的最小和最大跟踪尺寸,具有这种风格的
窗口有一个改变大小边框。最小跟踪尺寸是用户通过拖动窗口大小边框所能达到的最小窗
口尺寸。同样,最大跟踪尺寸是用户通过拖动窗口大小边框所能达到的最大窗口尺寸。
窗门的最小和最大跟踪尺寸是在windows系统创建窗口时设置的系统定义的默认值。应用
程序可通过处理WM_GETMINMAXINFO消息来获取或改变这些默认值。
系统命令
如果应用程序有一个带有系统菜单的窗口,就可以通过发送系统命令改变窗口的大小相位
置,系统命令是在用户从系统菜单中选择命令时产生的,应用程序可通过向窗口发送
WM_SYSCOMMAND消息来模拟用户的活动。下表列出的系统命令影响窗口的人小和位置:
命令 描述
SC_CLOSE 关闭窗口,这条命令向窗口发送一条WM_CLOSE消息,窗口完成消除和销毁所要
做的每步工作
SC_MAXIMIZE 最大化窗口
SC_MINIMIZE 最小化窗口
SC_RESTORE 恢复最小或最大窗口到原来的大小和位置
SC_SIZE 启动一个改变大小命令,用户可以使用鼠标或键盘改变一个窗口的大小。
改变和位置大小的函数
创建了窗口之后,应用程序可调用下列函数来设置窗口的大小和位置,这些函数是
SetWindowPlacement, MoveWindow, SetWindowPos, and DeferWindowPos,
SetWindowPlacement设置窗口的最小化位置,最大化位置,恢复大小和位置和显示状态。
MoveWindow和SetWindowPos函数很相似,都用来设置单个应用程序窗口的大小和位置,函
数SetWindowPos则含有一系列影响窗口显示状态的标志,函数MoveWindow则不包含这些标
志。使用函数BeginDeferWindowPos, DeferWindowPos,和EndDeferWindowPos 一起起用来
同时设置一些窗口的大小、位置、Z次序中的位置和显示状态。
应用程序使用函数GetWindowRect检取窗口限定矩形的坐标.GetWindowRect用窗口的左上
角和右下角填充RECT结构,这些坐标是相对于屏幕左上角的,对于窗口也一样。函数
ScreenToClient 或 MapWindowPoints把子窗口限定矩形的屏幕坐标映射成相对于父窗口
客户区的坐标。
函数GetClientRect用于检取窗口客户区的坐标,GetClientRect用客户区左上角和右下角
坐标填充RECT结构,但这里的坐标是相对于客户区本身的。这就是说.客户区左上角的坐
标总是(o,o),右下角的坐标是客户区的宽度和高度。
函数CascadeWindows该函数层叠排列指定父窗口的各指定子窗口。TileWindows该函数并
到显示指定父窗口的各指定子窗口。
尺寸和位置消息
windows系统要向将要改变大小和位置的窗口发送WM_GETMINMAXINFO消息,例如,用户从
系统菜单上选中Move或 Size命令或单击了大小边框或是标题栏,或者应用程序调用函数
SetWindowPos移动或改变窗口大小时.发送WM_GETMINMAXINFO消息。WM_GETMINMAXINFO消
息含有一个MINMAXINFO结构的指针,这个结构是窗口的默认的最大尺寸和位置,以及窗口
的最小和最大跟踪尺寸。应用程序可以通过处理WM_GETMINMAXINFO消息并给MINMAXINFO结
构的成员适当的设置来改变这些默认值。接收WM_GETMINMAXINFO消息的窗口必须具有
WS_THICKFRAME 或 WS_CAPTION风格,具有WS_THICKFRAME风格的窗口在窗口创建过程中,
或是在移动或改变大小时会接收到这条稍息。
windows系统还会向一个将要改变大小、位置、在z中的次序及显示状态时的窗口发送一条
WM_WINDOWPOSCHANGING消息,这条消息含有一个WINDOWPOS结构的指针,这个结构指定了
窗口新的尺寸、位置、z次序中的位置及显示状态。设置WM_WINDOWPOSCHANGED消息的
WINDOWPOS结构成员对窗口并没有影响,一个必须处理WM_SIZE 和 WM_MOVE消息的窗口必
须把WM_WINDOWPOSCHANGED消息传给函数DefWindowProc,否则windows系统不会向窗口发
送WM_SIZE 和 WM_MOVE消息。
windows系统在某窗口创建或被改变大小的时候向该窗口发送WM_NCCALCSIZE消息,
windows系统使用这条消息计算窗口客户区的大小以及相对于窗口的左上角的客户区的位
置,窗口通常把这条消息传给默认的窗口过程,但是这条消息对要定制窗口客户区或在改
变窗口大小时保留客户区的某一部分的应用程序来说是很有用的。
窗口销毁
通常,应用程序必须销毁所有由它创建的窗口,这是调用函数DestroyWindow来实现的。
如果一个窗口被销毁,系统就会隐藏这个窗口,如果它是可见的,那么与该窗口相应的所
有内部数据都被删除,这就使窗口句柄失效,应用程序也就不能再用它。
有许多窗口会在应用程序创建它们不久就删除,例如,应用程序通常在从用户得到足够的
输入后删除对话框,并继续执行下去。应用程序最终要删除应用程序的主窗口(在结束之
前)。
在销毁一个窗口之前,应用程序保留或删除所有与窗口相关的数据.还应该释放为窗口分
配的所有系统资源,如果应用程序不释放这些资源,则由windows系统来释放这些资源。
销毁一个窗口并不影响创建这个窗口的窗口类,新窗口还可用这个窗口类来创建,由这种
窗口类创建的所有窗口还会继续运转下去。
销毁一个窗口同时也销毁了窗口的子孙窗口,函数DestroyWindow首先把WM_DESTROY消息
发给窗口.然后再传给它的子窗口和子孙窗门,这样窗口的子孙窗口随着窗口的销毁而销
毁。
带有系统菜单的窗口在用户从系统中选中CLOSE时会接收到一条WM_CLOSE消息.通过处理
这条消息,应用程序可在销毁窗口之前提示用户确认.如果用户确认窗口可以被销毁,应
用程序就可调用函数DestroyWindow来销毁这个窗口。
如果将销毁的窗口是一个活动窗口,那么活动及焦点状态就会转到另一个窗口上,这个将
要成为活动的窗口就是由alt+esc组合键确定的下一个窗口,这个新的活动窗口也就决定
那一个窗口接收键盘焦点。
使用窗口
下一节讲解如何在应用程序中创建和使用窗口,如何管理父子窗口关系以及如何移动和改
变一个窗口的大小。
创建主窗口
应用程序创建的第一个窗口通常是主窗口.创建主窗口是调用函数CreateWindowEx指定窗
口类、窗口名、窗口风格、大小、位置、菜单句柄、实例句柄和创建数据。主窗口属于应
用程序定义的窗口类,所以必须在创建主窗口之前,注册窗口类并提供窗口过程。
绝大多数应用程序部使用WS_OVERLAPPEDWINDOW风格来创建主窗口.这种风格给窗口一个
标题栏、系统菜单、改变大小边框、最小和最大框,函数CreateWindowEx返回一个唯一标
识此窗口的句柄。下面的范例创建了一个屑于应用程序定义的窗口类的主窗口,窗口名
"Main Window"显示在窗口标题栏中。通过把WS_VSCROLL 和 WS_HSCROLL 与
WS_OVERLAPPEDWINDOW风格组合使用,应用程序创建的主窗口除了具有由
WS_OVERLAPPEDWINDOW风格所创建的窗口成员外,还有水平和垂直滚动条。出现了4次的
CW_USEDEFAULT常量把窗口的初始尺寸和位置设置成系统定义的默认值,指定NULL而不是
菜单句柄意思是说窗口有为该窗口类定义的菜单。
HINSTANCE hinst;
HWND hwndMain;
// Create the main window.
hwndMain = CreateWindowEx(
0, // no extended styles
"MainWClass", // class name
"Main Window", // window name
WS_OVERLAPPEDWINDOW | // overlapped window
WS_HSCROLL | // horizontal scroll bar
WS_VSCROLL, // vertical scroll bar
CW_USEDEFAULT, // default horizontal position
CW_USEDEFAULT, // default vertical position
CW_USEDEFAULT, // default width
CW_USEDEFAULT, // default height
(HWND) NULL, // no parent or owner window
(HMENU) NULL, // class menu used
hinstance, // instance handle
NULL); // no window creation data
if (!hwndMain)
return FALSE;
// Show the window using the flag specified by the program
// that started the application, and send the application
// a WM_PAINT message.
ShowWindow(hwndMain, SW_SHOWDEFAULT);
UpdateWindow(hwndMain); HINSTANCE hinst;
HWND hwndMain;
// Create the main window.
hwndMain = CreateWindowEx(
0, // no extended styles
"MainWClass", // class name
"Main Window", // window name
WS_OVERLAPPEDWINDOW | // overlapped window
WS_HSCROLL | // horizontal scroll bar
WS_VSCROLL, // vertical scroll bar
CW_USEDEFAULT, // default horizontal position
CW_USEDEFAULT, // default vertical position
CW_USEDEFAULT, // default width
CW_USEDEFAULT, // default height
(HWND) NULL, // no parent or owner window
(HMENU) NULL, // class menu used
hinstance, // instance handle
NULL); // no window creation data
if (!hwndMain)
return FALSE;
// Show the window using the flag specified by the program
// that started the application, and send the application
// a WM_PAINT message.
ShowWindow(hwndMain, SW_SHOWDEFAULT);
UpdateWindow(hwndMain);
注意前面的例子中,创建了主窗口之后调用函数ShowWindow,这是因为windows系统在创
建了窗口之后并不会自动地显示它,给ShowWindow传给SW_SHOWDEFAULT标志.应用程序就
可让启动应用程序的程序设置主窗口的初始显示状态,函数UpdateWindow向窗口发送了第
一条WM_PAINT消息。
创建,统计子窗口及改变子窗口的大小
使用于窗口把窗口的客户区划分成不同的功能区域.创建一个子窗口也象创建一个主窗口
一样调用函数CreateWindowEx。要创建一个应用程序定义的窗口类窗口,就必须在创建子
窗口之前注册窗口类并提供窗口过程。必须给子窗口设置WS_CHILD风格并在创建子窗口时
指定它的父窗口。
下面的例子通过创建3个大小相同的子窗口把应用程序主窗口的客户区分成3个功能区,每
个子窗口的高度与主窗口的客户区等高,而宽度是客户区宽度的三分之一。主窗口创建子
窗口是对WM_CREATE消息做出响应,这条消息是主窗口在它自己的窗口创建进程中收到的
。因为每个子窗口都有WS_BORDER风格,那么每个子窗口都有一个边框。又因为没有指定
WS_VISIBLE风格,每个子窗口在开始都是隐藏的。还要注意每个子窗口都赋予了一个子窗
口标识。
主窗口改变子窗口的大小和位置以响应WM_SIZE消息,这条消息是主窗口在它的尺寸将要
改变时接收到的。为响应WM_SIZE消息.主窗口调用函数GetWindowRect检取它的客户区的
尺寸,又把这个尺寸传给函数EnumChildWindows, EnumChildWindows再把每—个子窗口的
句柄传给应用程序定义的回调函数EnumChildProc,这个函数调用函数MoveWindow来改变
每个子窗口的大小和位置;大小部位置取决于主窗口的客户区的尺寸及子窗口的标识。然
后,EnumChildProc调用函数ShowWindow使得窗口可见。
#define ID_FIRSTCHILD 100
#define ID_SECONDCHILD 101
#define ID_THIRDCHILD 102
LONG APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)
HWND hwnd;
UINT uMsg;
UINT wParam;
LONG lParam;
{
RECT rcClient;
int i;
switch(uMsg) {
case WM_CREATE: // creating main window
// Create three invisible child windows.
for (i = 0; i < 3; i++)
CreateWindowEx( 0, "ChildWClass", (LPCTSTR) NULL, WS_CHILD | WS_BORDER,
0,0,0,0,
hwnd, (HMENU) (int) (ID_FIRSTCHILD + i), hinst, NULL);
return 0;
case WM_SIZE: // main window changed size
// Get the dimensions of the main window's client
// area, and enumerate the child windows. Pass the
// dimensions to the child windows during enumeration.
GetClientRect(hwnd, &rcClient);
EnumChildWindows(hwnd, EnumChildProc, (LPARAM) &rcClient);
return 0;
// Process other messages.
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
BOOL CALLBACK EnumChildProc(hwndChild, lParam)
HWND hwndChild;
LPARAM lParam;
{
LPRECT rcParent;
int i, idChild;
// Retrieve the child-window identifier. Use it to set the
// position of the child window.
idChild = GetWindowLong(hwndChild, GWL_ID);
if (idChild == ID_FIRSTCHILD)
i = 0;
else if (idChild == ID_SECONDCHILD)
i = 1;
else
i = 2;
// Size and position the child window.
rcParent = (LPRECT) lParam;
MoveWindow(hwndChild, (rcParent->right / 3) * i, 0, rcParent->right / 3,
rcParent->bottom, TRUE);
// Make sure the child window is visible.
ShowWindow(hwndChild, SW_SHOW);
return TRUE;
}
销毁窗口
函数DestroyWindow用来销毁一个窗口。通常,在销毁一个窗口之前要发送一条WM_CLOSE
消息,给窗口一个机会提示用户在窗口被销毁之前确认一下。含有系统菜单的窗口在用户
选中菜单中的Close命令时会自动地接收到一条WM_CLOSE消息,如果用户确认这个窗口可
以被销毁,应用程序就调用DestroyWindow,windows系统在窗口从屏幕上删除后发送一条
WM_DESTROY消息。为响应WM_DESTROY消息,窗口保存数据并释放所有分配给它的资源。主
窗口调用函数PostQuitMessage结束对WM_DESTROY消息的处理,退出这个应用程序。
下面的范例说明了在销毁窗口之前,如何提示用户确认.为响应WM_CLOSE,这个例子显示
了一个含有Yes, OK, 和 Cancel按钮的对话框,如果用户单击Yes按钮,DestroyWindow就
被调用,否则,窗口就不会被销毁。因为将要销毁的是一个主窗口,这个例子调用
PostQuitMessage来响应WM_DESTROY。
case WM_CLOSE:
// Create the message box. If the user clicks
// the Yes button, destroy the main window.
if (MessageBox(hwnd, szConfirm, szAppName, MB_YESNOCANCEL) == IDYES)
DestroyWindow(hwndMain);
else
return 0;
case WM_DESTROY:
// Post the WM_QUIT message to
// quit the application terminate.
PostQuitMessage(0);
return 0;
窗口函数 结构 消息
AdjustWindowRect
AdjustWindowRectEx
ArrangeIconicWindows
BeginDeferWindowPos
BringWindowToTop
CascadeWindows
ChildWindowFromPoint
ChildWindowFromPointEx
CloseWindow
CreateWindow
CreateWindowEx
DeferWindowPos
DestroyWindow
EnableWindow
EndDeferWindowPos
EnumChildProc
EnumChildWindows
EnumThreadWindows
EnumThreadWndProc
EnumWindows
EnumWindowsProc
FindWindow
FindWindowEx
GetClientRect
GetDesktopWindow
GetForegroundWindow
GetLastActivePopup
GetNextWindow
GetParent
GetTopWindow
GetWindow
GetWindowPlacement
GetWindowRect
GetWindowText
GetWindowTextLength
GetWindowThreadProcessId
IsChild
IsIconic
IsWindow
IsWindowUnicode
IsWindowVisible
IsZoomed
MoveWindow
OpenIcon
SetForegroundWindow
SetParent
SetWindowLong
SetWindowPlacement
SetWindowPos
SetWindowText
ShowOwnedPopups
ShowWindow
ShowWindowAsync
TileWindows
WindowFromPoint
WinMain
Obsolete Functions
AnyPopup
EnumTaskWindows
GetSysModalWindow
GetWindowTask
SetSysModalWindow
CLIENTCREATESTRUCT
COPYDATASTRUCT
CREATESTRUCT
MDICREATESTRUCT
MINMAXINFO
NCCALCSIZE_PARAMS
STYLESTRUCT
WINDOWPLACEMENT
WINDOWPOS
WM_ACTIVATE
WM_ACTIVATEAPP
WM_CANCELMODE
WM_CHILDACTIVATE
WM_CLOSE
WM_COMPACTING
WM_COPYDATA
WM_CREATE
WM_DESTROY
WM_ENABLE
WM_ENTERSIZEMOVE
WM_EXITSIZEMOVE
WM_GETICON
WM_GETMINMAXINFO
WM_GETTEXT
WM_GETTEXTLENGTH
WM_INPUTLANGCHANGE
WM_INPUTLANGCHANGEREQUEST
WM_MOVE
WM_MOVING
WM_NCACTIVATE
WM_NCCALCSIZE
WM_NCCREATE
WM_NCDESTROY
WM_PARENTNOTIFY
WM_POWER
WM_QUERYDRAGICON
WM_QUERYOPEN
WM_QUIT
WM_SETICON
WM_SETTEXT
WM_SETTINGCHANGE
WM_SHOWWINDOW
WM_SIZE
WM_SIZING
WM_STYLECHANGED
WM_STYLECHANGING
WM_USERCHANGED
WM_WINDOWPOSCHANGED
WM_WINDOWPOSCHANGING
WM_WININICHANGE
--
SetWindowPlacement 好像會被甚麼蓋掉
不像 SetWindowPos 比較強硬
--
▍▍▍│▍▍│▍▍▍│▍▍│▍▍▍│
▍▍▍│▍▍│▍▍▍│▍▍│▍▍▍│
││││││││││││││││││
我不是鋼琴 能不能黑白分明
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 111.251.168.141