38)问:事件OnChange和OnScorll都可以描述滚动条的滚动事件,他们有什么区别吗?
答:事件OnChange和OnScorll是有区别的。只要属性Position的值发生改变,那么无论这个值是用户操作滚动条引起的还是通过程序修改的,都会产生OnChange事件。而OnScorll事件只有在用户操作滚动条时才发生。当用户操作滚动条时,首先发生OnScorll事件,然后OnChange事件才会发生。
下面我们共同看一个程序来加深对滚动条的理解。
在窗体上放置一个水平滚动条ScrollBar1和一个垂直滚动条ScrollBar2,以及一个记录滚动条事件的Memo组件。当用户操作滚动条时,在Memo组件中就会显示发生的事件。
选择Memo组件,把它的ScrollBars属性设置为ssVertical。
选择水平滚动条组件,双击OnScroll的Value域,系统将生成事件处理模板,输入这样一段代码。
void __fastcall TForm1::ScrollBar1Scroll(TObject *Sender,
TScrollCode ScrollCode, int &ScrollPos)
{
AnsiString temp;
if(Sender==ScrollBar2)
temp="垂直滚动条的";
else
temp="水平滚动条的";
switch(ScrollCode)
{
case scLineUp:temp+="scLineUp";break;
case scLineDown:temp+="scLineDown";break;
case scPageUp:temp+="scPageUp";break;
case scPageDown:temp+="scPageDown";break;
case scPosition:temp+="scPosition";break;
case scTrack:temp+="scTrack";break;
case scTop:temp+="scTop";break;
case scBottom:temp+="scBottom";break;
case scEndScroll:temp+="scEndScroll";break;
default:
temp+="未知";break;
}
Memo1->Lines->Append(temp+"事件");
}
第一条语句声明一个AnsiString类型的变量,用来存放将要显示的字符串。
第二条语句判断发送事件的对象,如果是垂直滚动条,将temp初始化为 “垂直滚动条的”,否则初始化为 “水平滚动条的”。
第三条语句根据ScrollCode的值,显示相应的事件。
最后一条语句将要显示的字符串加到文本框的末尾。
在窗体中选择垂直滚动条组件,选择Events标签,单击OnScroll的Value域,从下拉列表框中选择ScrollBar1Scroll事件处理程序。这样,垂直滚动条和水平滚动条将共用一个事件处理程序。
选择水平滚动条组件,选择Events标签,双击OnChange域,然后输入:
Memo1->Lines->Append("水平滚动条的OnChange事件");
它将在文本框后面显示水平滚动条改变的信息。
类似的,给垂直滚动条的OnChange事件加上如下代码:
Memo1->Lines->Append("垂直滚动条的OnChange事件");
详细代码如下:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ScrollBar1Scroll(TObject *Sender,
TScrollCode ScrollCode, int &ScrollPos)
{
AnsiString temp;
if(Sender==ScrollBar2)
temp="垂直滚动条的";
else
temp="水平滚动条的";
switch(ScrollCode)
{
case scLineUp:temp+="scLineUp";break;
case scLineDown:temp+="scLineDown";break;
case scPageUp:temp+="scPageUp";break;
case scPageDown:temp+="scPageDown";break;
case scPosition:temp+="scPosition";break;
case scTrack:temp+="scTrack";break;
case scTop:temp+="scTop";break;
case scBottom:temp+="scBottom";break;
case scEndScroll:temp+="scEndScroll";break;
default:
temp+="未知";break;
}
Memo1->Lines->Append(temp+"事件");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ScrollBar1Change(TObject *Sender)
{
Memo1->Lines->Append("水平滚动条的OnChange事件");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ScrollBar2Change(TObject *Sender)
{
Memo1->Lines->Append("垂直滚动条的OnChange事件");
}
//---------------------------------------------------------------------------
现在,编译并运行这个程序,点击滚动条,可以看出滚动条的事件产生情况。
哪个事件优先你能看出来吗?你一定会对OnScroll同一事件产生的两个属性值先后被OnChange分开而不解是吗?你好好看一下什么时候产生scEndScroll值J
其实我们如果要了解其他某个组件所产生的事件之间的顺序,也可以用同样的方法来实现。
39)问:轨迹条(TrackBar)有那些主要属性呢?
答:轨迹条与滚动条有相似之处,它也有一个类似于滚动块的滑动块,可以用鼠标或者使用方向键移动。轨迹条的某些属性与滚动条完全相同,例如Max,Min和Position。但是它还有一些特殊的属性。
1.LineSize属性,用于指定当用户按下方向键时,轨迹条的滑动块移动的距离。
2.PageSize属性,用于指定当用户按下PgUp和PgDn时,轨迹条上的滑动块移动的距离。
3.Frequency属性,用于设置轨迹条刻度的单位。如果Max-Min等于100,而这个属性等于10,那么轨迹条就被分成了10等份。
4.Orientation属性,用来确定轨迹条的放置方向,它有两个值,tbHorizontal表示水平放置,tbVertical表示是垂直放置的。缺省情况下是水平放置的。
5.SelStart这个属性用来设置选择的起点。
6.SelEnd这个属性用来设置的选择终点。
7.TickMarks这个属性用来设置轨迹条标尺的位置。它有三个值,分别表示三种不同的滑动块位置:
tmBottomRight表示垂直放置时标尺显示在轨迹条的下面或者水平放置时显示在右边。
tmTopLeft表示垂直放置时标尺显示在轨迹条的上面或者水平放置时显示在左边。
tmBoth则表示轨迹条的两边都有标尺。
8.TickStyle这个属性用来确定轨迹条标尺的样式。它有三个值,分别表示三种不同的标尺样式:
tsAuto表示自动显示标尺的刻度。
tsManual表示需要使用SetTick过程才能设置在某个位置显示刻度。
tsNone表示标尺不显示刻度。
40)问:轨迹条有哪些常用的事件呢?
答:当用户用鼠标或者键盘操作轨迹条时,就会产生OnChange事件。不过要注意,在程序中改变属性Position的值不会产生OnChange事件,这一点与滚动条不同。
41)问:进程条(ProgressBar)如何用呢?
答:它的属性与上面的那些组件差不多,象Max、Min、Orientation、Position与上面的含义大同小异。其中Position是这个组件的关键,它用来设置或者返回进程条的填充小方块的当前位置,当进条结束的时候,这个位置应该是位置上限。
Smooth:布尔类型,缺省为false。这时的填充是按格进行的,如果设置为true,则填充是平滑进行的。
StepBy:其声明为:void _fastcall StepBy(int Detla);这个函数用来向前填充进程条,同时改变Position的属性值。它的增加量由参数Detla来指定。
StepIt:其声明为:void _fastcall StepIt(void);这个函数用来向前填充进程条,同时改变Position的属性值。其填充步长由Step属性来指定。
Step:这个属性用来设置当调用StepIt函数时,Position位置的增加量。缺省为10。
42)问:UpDown控件有什么用?
答:这个控件是一对上下箭头按钮,按下按钮时会自动增加或减少某个数值。它通常有一个附属组件,由UpDown控件的Associate属性指定。如果这个组件是一个编辑框,那么编辑框就会自动显示UpDown控件的属性Position的值。
UpDown控件也有一些滚动条和轨迹条所具备的属性,例如Max,Min,Position,Orientation,它们的意义也基本上相同,不过UpDown控件同样有一些特殊的属性。
AlignButton为udLeft时,表示将UpDown控件放置在附属组件的左边,为udRight时,则表示将UpDown控件放置在附属组件的右边。
Associate用来指定关联的附属组件。
ArrowKey属性,当属性为True时,按下上下方向键就像按下UpDown控件的上下箭头一样。缺省值为True。
Thousands属性, 当属性为True时,如果Position超过1000,那么就会自动给所显示的数值加上一个千分位。缺省值为True。
Wrap属性,当属性为True时,如果Position的值大于Max,那么就会自动回到Min属性指定的值。缺省值为False。
43)问:UpDown控件有哪些常用的事件呢?
答:UpDown控件有两个常用的事件:OnChanging和OnClick。当用户正在按下上下箭头时,将发生OnChanging事件;当用户按下上下箭头时,会发生OnClick事件。
我们共同来看一个例子:
在窗体上放置两个Edit控件,和两个UpDown控件,将两个UpDown控件的Orientation属性分别取值udHorizontal和udVertical。
将第二个UpDown控件的Max的取值为5000,Position值为100,将他们的Associate属性分别与两个编辑框关联。在对应事件中输入如下代码:
void _fastcall TForm1::UpDown1Changeing(TObject *Sender,bool &AllowChange)
{
Edit1->Text=UpDown1->Position;
}
// 注意参数AllowChange可以用来指定是否允许改变Position属性的值。
void _fastcall TForm1::UpDown2Click(TObject *Sender,TUBtnType Button)
{
Edit2->Text=UpDown2->Position;
}
//注意参数Button表示哪个按钮被按下:btNext为上箭头或者右箭头;btPrew为下箭头或者左箭头。
44)问:在UpDown右边有一个HotKey组件是做什么的?
答:热键HotKey用来在程序运行期间动态地指定某个组件或者菜单的快捷键。在它的属性中你只要记住HotKey属性就可以了,这个属性用来返回用户指定的快捷键。
代码如下:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::X1Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::HotKey1Change(TObject *Sender)
{
X1->ShortCut=HotKey1->HotKey;//X1为菜单名,注意有些书介绍用OnEnter事件,但我觉得不妥,不防你也试一下,用OnEnter你将得不到什么关联J
}
//---------------------------------------------------------------------------
为什么这里用了一个Button1?如果你的程序中没有另外一个组件可以获得焦点,你将感受不到快捷键的功能的,因为焦点会停在HotKey组件上,在这里就是想将焦点转移一下,然后用快捷键试一下效果J
(待续)
本文地址:http://com.8s8s.com/it/it29175.htm