C语言实例教程(PDF格式)-第37部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
{
CAboutDlg dlgAbout;
dlgAbout。DoModal();
}
else
{
…………………………………………………………Page 284……………………………………………………………
CDialog::OnSysmand(nID; lParam);
}
}
// If you add a minimize button to your dialog; you will need the code below
// to draw the icon。 For MFC applications using the document/view model;
// this is automatically done for you by the framework。
void CProgressDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND; (WPARAM) dc。GetSafeHdc(); 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect。Width() cxIcon + 1) / 2;
int y = (rect。Height() cyIcon + 1) / 2;
// Draw the icon
dc。DrawIcon(x; y; m_hIcon);
}
else
{
CDialog::OnPaint();
}
…………………………………………………………Page 285……………………………………………………………
//程序据此函数进行窗口的重绘
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window。
HCURSOR CProgressDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CProgressDlg::OnStepit()
{
// TODO: Add your control notification handler code here
m_ProgressBar。SetStep(1);
//设定函数StepIt 的步长,一般来说,使用步长宜适中。
//在设定的步长大于刻度所代表的长度时,需执行几次函数StepIt 进度条的滑块
//才会前进一个刻度距离。而当其大于一个刻度所代表的长度时,每执行一次函数
//StepIt 滑块就会前进不止一个刻度距离。但每个刻度只有在被完全跨越时滑块
//在外观上才前进一个刻度。
m_ProgressBar。StepIt();
//若函数执行时滑块已经到达其可能达到的最大位置,则执行后滑块重新达到其
//最小位置,在例程中读者不妨实际执行之以得到一直观印象。
//按钮Step It的消息处理函数。
}
void CProgressDlg::OnHScroll(UINT nSBCode; UINT nPos; CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
CSliderCtrl *pSlider=(CSliderCtrl *)pScrollBar;
…………………………………………………………Page 286……………………………………………………………
if(pSlider==&m_TrackBar)
m_ProgressBar。SetPos(pSlider…》GetPos());
CDialog::OnHScroll(nSBCode; nPos; pScrollBar);
}
//滑块控件需要处理的唯一消息,从这里我们可以看出,在例程中,我们根据滑块控件的位
置
//来设定进度条的当前位置。换句话说,我们让滑块控件与进度条在程序中具有了相同的意
义。
第六节 上下控件消息响应
与其它的标准控件相比,上下控件 (Spin)是一种更常用于对输入进
行在一定范围内进行精确定位的控件。与滑块控件不同的是,滑块控
件的定位是连续的,而上下控件的定位则在很大程度上可以被视为是
离散的。滑块控件一般多用于在很大范围内进行快速的选择,而上下
控件则多用在选择范围较小而对精度要求较苛刻的场合。同时,使用
上下控件也可以将程序要求的用户输入精度明显地表示出来。图5。30
为Visual C++的资源编辑器中的上下控件图标。
图5。 30 资源编辑器中的上下控件图标
由于上下控件在程序控制中与滑块控件的诸多相识性,在本章中,我
们将结合两者进行比较,同时考虑到上下控件在控制方式上的特殊
性,我们会对其特性也进行比较简单的介绍。
首先,创建一个上下控件与创建其它控件在可视阶段并没有什么特殊
之处。在基于对话框的程序中,将上下控件直接放到对话框中即可。
在并非基于对话框的程序中,我们使用其生成函数Create即可:
BOOL Create( DWORD dwStyle; const RECT& rect; CWnd* pParentWnd; UINT nID );
函数的几个参数很容易理解。参数dwSytle指定上下控件的风格,
rect则指定其大小和位置,参数pParentWnd为指向该控件的父窗口的
指针,在对话框程序中,简单地设为NULL在很多场合就足够了,函数
最后一个参数nID则指定控件的ID号。
…………………………………………………………Page 287……………………………………………………………
但是,对于上下控件的风格 (Style)的设置则对程序控制具有很大
的影响。随参数dwStyle取值的变化,上下控件的行为具有相当大的
区别。下面我们结合资源编辑器中的可视实现对其作讲解。
如图5。31中,上下控件的风格选项卡具有七个不同的域。
l 注意:
l 下面的讲解中各选项后的括号中的值为对应该选项的风格值设
定。
域Orientation决定上下控件的显示方式――同时决定其处理的消息
的不同。选择Verical时,控件按上下方式显示,而当选择
Horizontal (UDS_HORZ)时,它按水平方式显示。域Alignment则决
定上下控件的关联窗口的布置方式。它可以为下列值之一:
图5。 31 上下控件的风格设定
Unattached (default):此为域缺省值,表明上下控件与其关联控
件之间没有什么特定的要求。
Left (UDS_ALIGNLEFT):此时上下控件的关联控件的位置被指定为
在上下控件的右边,同时,其关联控件的大小被调整到与其关联的上
下控件等高。
Right (UDS_ALIGNRIGHT ): 此时上下控件的关联控件的位置被指定
为在上下控件的左边,同时,其关联控件的大小被调整到与其关联的
上下控件等高。
选项Auto buddy (UDS_AUTOBUDDY)对程序控制影响较大。当该选项
被选择时,系统自动设定该上下控件的关联窗口,同时,自动在该关
联窗口中显示其所联系的上下控件位置值。(因此,该关联窗口一般
为一编辑框或静态文本控件。)也就是说,设定该值后,上下控件的
关联窗口的行为管理是自动的,在指定了上下控件的关联窗口后,就
不再需要对其行为控制添加另外的代码。而当没有设定该风格时,我
们必须为该控件的行为编写独立的代码:要考虑编辑框中值的显示,
…………………………………………………………Page 288……………………………………………………………
要考虑刷新静态文本控件的内容。我们认为,如果仅仅是简单的利用
上下控件的位置信息,一般设为自动处理方式就相当合适了。当然,
如果程序员希望在其中处理一些额外的动作,就不得不动动脑筋考虑
一下其实现方法了。
选项Set buddy integer (UDS_SETBUDDYINT)则决定了上下控件位置
改变时的消息发送。设置该选项时,上下控件的位置改变是,向其关
联窗口发送消息WM_SETTEXT,同时,上下控件的位置以十进制或十六
进制格式发出。
选项No thousands(UDS_NOTHOUSANDS)被设置时,在数的每三位中,
不插入一个起分隔作用的千位分隔符。
选项Wrap (UDS_WRAP )决定当上下控件的选择位置超过极限位置时的
处理方式:当该选项被设置时,当上下控件的位置达到其最大或最小
位置后,用户试图再增大或减小该值时,上下控件的值变为最小或最
大。否则,上下控件的值只是简单的保持不变。
选项Arrow keys (UDS_ARROWKEYS)被设置时,当按下向上或向下方
向箭头时,控制增加或减小其位置。
上下控件的扩展风格的设定与其它控件的设定没有什么大的改变,这
里不再详述。
下面,我们看一下上下控件的关联窗口的指定及其行为管理的实现。
首先,我们看看当上下控件的Auto buddy风格被设定的情况下的管
理。
我们先指定上下控件的关联窗口。这需要用到函数SetBuddy:
CWnd* SetBuddy( CWnd* pWndBuddy );
该函数的唯一一个参数为一指向上下控件的关联窗口的指针,其返回
值为一指向
该上下控件原来的关联窗口的指针。
l 注意:
l 在程序中,一般应先指定上下控件的变动范围SetRange:
l void SetRange( int nLower; int nUpper );
…………………………………………………………Page 289……………………………………………………………
该函数的两个参数分别指定了上下控件的最小及最大变动
值。
以后我们不再需要为上下控件的关联窗口的行为编写任何代码。系统
会为我们作好所有的规范化的工作:上下控件的位置改变时,其变化
直接反应在与其关联的窗口中――该窗口中会以十进制或十六进制数
的形式来反应上下控件此时的位置信息。
当我们不设定该风格的时候,情况发生了变化。范围及关联窗口的设
定同上文没有什么差别。但现在,当上下控件的位置发生变化时,虽
然上下控件会发送消息反应这一变化,但其关联窗口的行为需要我们
编写代码来实现。当上下控件发生的位置与其前一位置不一样时,它
发送消息ON_WM_HSCROLL (ON_WM_VSCROLL)来反应这一变化。在程序
接收到该消息后,经过适当的处理,就可以自己对该消息作出反应了
(当然,如果你愿意,你也可以什么事也不做)。
下面为一段关于上下控件的关联窗口控制的代码。
// 。。。
m_Spin2。SetRange(0;(sizeof(szColors)/sizeof(szColors'0'))…1);
m_Spin2。SetPos(0);
m_Spin2。SetBuddy(&m_Buddy2);
m_Spin2。SetWindowText(szColors'0');
// 。。。
void CSpinBoxDlg::OnHScroll(UINT nSBCode; UINT nPos; CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
CSpinButtonCtrl *pSpin=(CSpinButtonCtrl *)pScrollBar;
if(pSpin==&m_Spin2)
m_Buddy2。SetWindowText(szColors'pSpin…》GetPos()');
CDialog::OnHScroll(nSBCode; nPos; pScrollBar);
}
第一段代码设定了上下控件的范围,关联窗口,位置,并初始化了编
…………………………………………………………Page 290……………………………………………………………
辑框中的显示。
第二段中的函数处理了消息ON_WM_HSCROLL,并利用上下控件的位置
对其关联窗口的显示进行了改变。语句
CSpinButtonCtrl *pSpin=(CSpinButtonCtrl *)pScrollBar;
将该消息的最后一个参数进行转换,以便确定是否该消息是我们所关
心的上下控件发出的。接下来用语句
if(pSpin==&m_Spin2)
进行判断。在确知该消息是由特定的上下控件发出的后,语句
m_Buddy2。SetWindowText(szColors'pSpin…》GetPos()');
对编辑框中的文本进行了更新。先用上下控件的成员函数GetPos取得
其位置,然后用函数SetWindowText重新设定编辑框中的文本
(szColors' '为预先设定的一枚举数组)。
l 注意:
l 以上设定范围、关联窗口、位置 (还有没有在上文提到的加速设
置)动作,都有相应的获取函数 :例如GetBuddy函数对应于
SetBuddy等。读者有兴趣可以参考系统的技术支持部分。
…………………………………………………………Page 291……………………………………………………………
第六章 使用Windows标准控件
我们在前面曾提到过,控件是一些行为标准化了的窗口,一般用于对
话框或其它窗口中充当与用户交互的元素。在Visual C++中,可以使
用的控件分成三类:
(1) Windows标准控件
Windows标准控件由Windows操作系统提供,在Windows 95中还提供了
一些新增的控件。所有这些控件对象都是可编程的,我们可以使用
Visual C++提供的对话框编辑器把它们添加到对话框中。Microsoft
基础类库 (MFC)提供了封装这些控件的类,它们列于表6。1。
表6。1 Windows标准控件