📄 07.5 对话框伸缩功能的实现.txt
字号:
7.5 对话框伸缩功能的实现
先让我们看看 Windows提供的画图程序中的一个功能,单击画图程序的【颜色】菜单下的【编辑颜色】菜单项,将出现编辑颜色对话框,如图 7.31所示。当单击该对话框上的【规定自定义颜色】按钮时,该对话框将扩展为如图 7 .3 2所示的样子。
图 7.3 1原始的画图程序编蟹颜色对话框 图 7.32扩展后的画图程序编辑颜色对话框
下面为读者介绍如何实现对话框的扩展与收缩功能。首先,在 Mybole程序中的测试
对话框上再添加一个按钮,并在其属性对话框中将其 Caption设置为:"收缩<<"。当 Mybole
程序运行时,用户单击此按钮后,将把这个测试对话框切除一部分,并且把此按钮的文本
改成:"扩展》飞当用户再次单击这个"扩展"按钮时,程序还原整个对话框。关于在程
序中动态修改按钮的文本,可以参考上面的程序中 .lJ且i
修改静态文本控件文本的实现代码。首先需要给这
个按钮添加一个命令响应函数,这可以通过 ClassWizard来完成,也可以直接在这个按钮上双击 IOn8utlOnl ......…:…I_C ICICED 0.,... 10: IOC_BUIION1 旦旦」
鼠标左键,即可弹出如图 7.33所示的添加成员函数 图 7.33 Add Member Function对话框
的对话框。
从图 7.33可以看出,这个对话框的功能就是为"收缩<<"按钮添加鼠标单击消息 ( BN_CLICKED )响应函数。直接单击【 OK】按钮,程序将会跳转到这个函数的定义处。通过这种方法,就能够很方便地为对话框添加了一个鼠标单击按钮的响应函数。在此函数中,首先实现鼠标单击按钮后按钮文本发生变化这一功能,具体实现代码如例 7-28所示。
例 7-28
void CTestDlg : : OnButto丑 1 ( )
// TODO: Add your control notification handler code here CString str;
if(GetDlgltemText(i DC-BUTTON1, str ), str == "收缩 << " )
SetDlgItemText(IDC_BUTTON1,"扩展 >> "};
else
SetDlgltemText(工 DC_BUTTON1,"收缩 << ");
上述例 7-28所示代码中,首先获得了 IDC_BUTTONl按钮的文本,然后对该文本进行判断,如果是"收缩<<",那么将该按钮的文本改变为"扩展》":否则将其还原为"收缩<<"。
Build并运行 Mybole程序,打开测试对话框,单击【收缩《】按钮,该按钮的文本立即变为"扩展》飞再次单击此按钮,其文本又还原为"收缩<<"。也就是说,随着鼠标的单击,该按钮的文本在"收缩<<"和"扩展>>"之间来回切换。
下面在测试对话框资源中放置一个分隔条,用来划分对话框中要动态切除的部分。这个分隔条可以通过 VC I I提供的图像控件来实现。首先用鼠标单击资源控件面板上的图像控件,然后在测试对话框资源窗口中靠近底部的位置处拖动鼠标拉出一条线。这时的测试对话框资源如图 7 .3 4所示。
打开这个图片控件的属性对话框(如图 7.35所示),可以看到它的 ID也是 IDC_ STATIC,我们首先将其 m改为 IDC_SEPERATOR,然后打开 Styles选项卡,选中 Sunken选项,这样,这条分隔条就会呈现出一种下陷的状态。
下面就要实现这样的功能:当单击【收缩《】按钮时,对话框显示新添的这条"分隔条"以上的内容:当单击【扩展》】按钮时,对话框还原为原来的样子。为了还原对话框,需要保存其原始位置,对话框的原始位置通过调用 GetWindowRect函数就能得到。那么如何确定收缩后的对话框大小呢?我们注意到,当切除掉"分隔条"以下部分后,对话框的左上角坐标,以及对话框的宽度井没有改变,发生变化的只是右下角的纵坐标。也就是说,我们只要得到切除后的对话框右下角的纵坐标,也就得到了切除后的对话框的大小和位置。要得到切除后的对话框右下角的纵坐标,就要利用我们所添加的图像控件窗口 (作为分隔条使用〉。我们可以在图像控件对象上调用 GetWindowRect函数来得到图像控件窗口的大小和位置,它的右下角纵坐标也就是收缩后的对话框的右下角纵坐标。
具体的实现代码如例 7-29所示(其中灰色部分为新添的代码)。例 7-29 '
void CTestDlg : :OnButtonl()
11 TODO : Add your control notification handler code here CString stri if (GetDlgltemText (IDC_BUTTON1 , str) , str "收缩 << " )
SetDl g工 temText(IDC_BUTTON1,"扩展 >> 11 ) ;
e lse
SetDlgltemText(IDC_ BUTTON1 , '收缩<< " ) i
}
static CRect rec飞 Largei
static CRect rectSmalli
if(rectLarge.工 sRectNull ( ) )
CRect rectSeparatori
GetWindowRect(&rectLarge) i
GetDlg工 tem( 工 DC_SEPARATOR)->GetWindowRect(&rectSeparator)i
rectSmall.left=rectLarge.left;
rectSmall.top=rectLarge.toPi
rectSmall.right=rectLarge.righti
" I 251
第 7童对话框〈一〉
rectSmall.bottom=rectSeparator.bottom;
if(str=="收缩<<" ) SetWindowPos(NULL, O, O, rectSmall.Width() , rectSmall.Height() , SWP_NOMOVE I SWP_NOZORDER); else SetWindowPos(NULL, O, O, rectLarge.Width() , rectLarge.Height() , SWP_NOMOVE I SWP_NOZORDER);
在新添加的代码中,首先定义了两个矩形变量: rectLarge和 rectSmall,分别用来保存对话框原始尺寸和切除部分区域之后的尺寸。并且当第一次单击【收缩《】按钮获得这两个尺寸后,以后再次单击此按钮时,并不需要再去设置这两个变量的值,因此,将这两个变量定义为静态变量。
接下来,判断对话框的原始尺寸是否己经被赋值。 CRect类有两个成员函数可以用来判断一个矩形是否为空:
. IsRectEmpty
检测矩形区域是否为空。如果矩形的宽度和高度为 O或是一个负值,则说明此矩形为空,返回非零值:否则,返回 0。
. IsRectNull
如果矩形的左上角和右下角的四个坐标值都是 0,贝Ij此函数返回一个非零值:否则,返回 0。可以通过下面的例子来看看这两个函数的区别,首先定义了两个矩形变量 :
CRect rectl(10 , 10 , 10, 10);
CRect rect2(O , O, O, O);
于是, IsRectEmpty (rect1)和 IsRectEmpty ( rect2)调用都将返回一个非零值, IsRectNull
( rect2)调用也将返回一个非零值,但 IsRectNull ( rectl)调用将返回 0。本例中,因为矩形变量是静态变量,系统将它们的坐标均初始化为 0。因此,可以使用这两个函数中的任一个来判断矩形是否为空。
在上述例 7-28所示程序中,如果判断出 rec tLarge为空,那么首先调用 GetWindowRect函数获取这个对话框的原始尺寸,井保存于 rectLarge中。然后获得 IDC_SEPARATOR图片控件的位置,并设置对话框切除部分区域之后的位置坐标,即设置 rectSmal1变量的值。上面已经分析过了,对话框切除图片控件以下的部分区域后,剩余部分的大小,即 rectSma1 1变量的左上角是没有变化的,右下角横坐标也没有变化,只有纵坐标发生了变化,变化后的纵坐标也就是图像控件的右下角纵坐标。
有了原始和切除后的矩形尺寸,就可以利用 SetWindowPos函数来设置对话框的收缩和扩展之后的大小了。这个函数的原型声明如下所示 :
252 I
详解
BOOL SetWindowPos( const CWnd* pWndlnsertAfter , int x , int y , int cx , int cy , UINT nFlags );
该函数的作用是设置窗口的位置和大小,各参数的意义如下所示:
. pWndInsertAfter
标识一个 CWnd对象,该对象是在以Z次序排序的窗口中位于当前窗口前面的那个窗口对象。这个参数可以是指向某个CWnd对象的指针,也可以是指向表7.2中所列值的指针之一。
表7.2 SetWindowPos函数的pWndlnsertAfter参数取值
参数取值 意义
wndBottom 把当前窗口放置于Z次序的底部
wndTop 将当前窗口放置于Z次序的顶部
wndTopMost 将当前窗口设置为一个顶层窗口,放置于所有非顶层窗口之上,即使窗口未被激活也将保持顶层位置
wndNoTopMost 将当前窗口放置于所有非顶层窗口之上,但在所有顶层窗口之后
. x和y窗口左上角的x和y坐标。
. cx和cy窗口的宽度和高度。
. nFlags
设定窗口的只寸和定位。该参数可以是表7.3中所列各种取值的组合。
表7.3 nFlags参数取值
参数取值 意义
SWP DRAWFRAME 在窗口周围绘制一个边框,这是在窗口创建时定义的
SWP FRAMECHANGED 给窗口发送 WM_NCCALCSIZE消息,即使窗口尺寸没有改变也会发送此消息.如果 未指定这个标志,那么只有在改变了窗口尺寸时才发送WM_NCCALCSIZE消息
SWP HIDEWINDOW 隐藏窗口
SWP NOACTIVATE 不激活窗口。如果未设置此标志,那么窗口被激活,并根据pWndlnsertAfter参数的取值,将当前窗口设置到其他顶层窗口或非顶层窗口之上
SWP NOCOPYBITS 消除客户区的所有内容。如果未设置此标志,客户区的有效内容将被保存并且在窗口 尺寸更新和重定位后复制回客户区
SWP NOMOVE 维持窗口当前位置,这将忽略x和y参数
SWPjNOO~RZORDER 不改变Z次序中的所有者窗口的位置
SWP NOREDRAW 不重画改变的内容。如果设置此标志,则不发生任何重画动作。适用于客户区和非客户 区(包括标题栏和滚动条)和任何由子窗口移动而露出的父窗口的部分.如果设置了此标志,应用程序必须明确地使窗口无效,并且重画窗口和父窗口中任何需要重画的部分
SWP _NOREPOSITION 与SWP一NOOWNERZORDER标志的作用相同
SWP NOSENDCHANGING 禁止窗口接收WM_WINDOWPOSCHANGING消息
SWP NOSlZE 维持窗口的当前尺寸,这将忽略cx和cy参数
SWP NOZORDER 维持当前的Z次序,这将忽略pWndInsertAfter参数
SWP SHOWWINDOW 显示窗口
喝道..-... I 253
可见,本例中 SetWindowPos函数的nFlags参数不能取 SWP_NOSIZE这个值,因为它将忽略 cx和 cy参数,从而就无法改变对话框矩形区域的大小了。
.
飞令·姐1日眉窗口的 Z次序表明了重叠窗口堆中窗口的位置,这个窗口堆是按一个假
想的轴定位的,这个轴就是从屏幕向外伸展的 Z轴。 Z次序最上面的窗口覆盖所有其他
的窗口, Z次序最底层的窗口被所有其他的窗口覆盖。应用程序设置窗口在 Z次序中的
位置是通过把它放在一个给定窗口的后面,或是放在窗口堆的顶部或底部。
Windοws系统管理三个独立的 Z次序一一一个用于顶层窗口、一个用于兄弟窗口,
还有一个是用于最顶层窗口。最顶层窗口覆盖所有其他非最顶层窗口,而不管它是不是
活动窗口或是前台窗口。应用程序通过设置 WS_EX_TOPMOST风格创建最顶层窗口。
一般情况下, Windows系统把刚刚创建的窗口放在 Z次序的顶部,用户可通过激活
另外一个窗口来改变 Z次序; Windows系统总是把活动的窗口放在 Z次序的顶部,应用
程序可用函数 BringWindowToTop把一个窗口放置到 Z次序的顶部。函数 SetWindowPos
和 DeferWindowPos用来重排 Z次序。
·
兄弟窗口
共享同一个父窗口的多个子窗口叫兄弟窗口。
·
活动窗口
活动窗口是应用程序的顶层窗口,也就是当前使用的窗口。只有一个顶层窗口可以是活动窗口,如果用户使用的是一个子窗口, Windows系统就激活与这个子窗口相应的顶层窗口。
任何时候系统中只能有一个顶层窗口是活动的。用户通过单击窗口(或其中的一个子窗口)、使用 ALT+TAB或 ALT+ESC组合键来激活一个顶层窗口,应用程序则调用函数 SetActiveWindow来激活一个顶层窗口 O
·前台窗口和后台窗口
在 Windows系统中,每一个进程可运行多个线程,每个线程都能创建窗口。创建正在使用窗口的线程称之为前台线程,这个窗口就称之为前台窗口。所有其他的线程都是后台线程,由后台线程所创建的窗口叫后台窗口。
用户通过单击一个窗口、使用 ALT+TAB或 ALT+ESC组合键来设置前台窗口,应用程序则用函数 SetForegroundWindow设置前台窗口 O如果新的前台窗口是一个顶层窗口,那么 Windows系统就激活它,换句话说, Windows系统激活相应的顶层窗口。
Bui1d并运行 Mybole程序,打开测试对话框,如图 7 .36所示。单击【收缩《】按钮,会发现对话框立即切除了分隔条以下的部分,并且此按钮的名称变为"扩展》飞如图 7 .3 7所示:再次单击此按钮,会发现对话框又还原为原来的样子,并且此按钮的名称也还原为"收缩<<"。可见,程序实现了所需的功能。如果不想让用户看到对话框中这条添加的分隔条,可以在对话框资源编辑窗口中,利用控件属性对话框,去掉这个图片控件的Visible属性(如图 7 .3 8所示)。然后再次运行 Mybole程序,打开测试对话框,这时就看不到添加的分隔条了,如图 7 .3 9所示。
254 I如~~
..
四
" ...1:rl 。"
「一 E
...
"
" .. .a此lo 』 ' ...
IT幽什
干
一
图 7.36原始大小的测试对话框图 7.37切除部分内容后的测试对话框
忡忡""""川川 .,IZ ."" f "1
绚
而,阳帽|咐. 1阳晒t1 81...... , r -
10: I'Dc_sEP.刷.TOR3τ酬 I Fr.me 333 -
.."|
「画画「曲"
「田....... r' T曲-即: JBIUk
r.啕由
图 7 .3 8去掉图片控件的 Visible选项图 7.39"分隔条"为不可见状态
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -