随笔 - 16, 文章 - 1, 评论 - 4, 引用 - 0
数据加载中……

C++ Builder 初学问与答(一~五)

一直以来都想写一点为BCB初学者快速入门的东西,前不久写了几篇《闲谈BCB》想把自己学习BCB中如何来解决难点的方法说给大家,没想到被骂得不成样子。本想不写了,但觉得这些东西留下来能做什么呢?还是用另一种方法来重新演译我的思维吧,最近有些忙,那几篇没有写完的文章,我也会尽快写完的,至于《深入QR》,我想我一定会用另一种手法来写,让你一看就会把QR这个娇女的所有衣服都脱光,不整理到这个地步,我是不敢轻易再拿出来,还请朋友见谅!

本文分为《基础入门》、《快速提高》与《成功编程者》三部分。

  第一部分:基础入门

  1.窗体

  1)问:Windows的编程就是在窗体的基础上实现的, C++Builder是怎样处理窗体的呢?

  答:窗体的一部分功能通过窗体的属性来实现,窗体的属性非常多,这里只对其中比较重要的属性进行介绍。

  1.ActiveControl指定窗体上的某个组件为输入焦点。如下面的语句将窗体上的Label1组件成为输入焦点:ActiveControl=Label1。在同一时时刻,应用程序只能有一个输入焦点。

  2.BorderIcons用来设定标题栏上出现哪些系统图标。它是一个集合,可以设成以下几个类型:最大化按钮(biMaximize)、最小化按钮(biMinimize)、帮助按钮(biHelp)和系统菜单(biSystemMenu)。

  3.Icon属性用来指定当窗体最小化时显示的图标。

  4.KeyPreview属性为true时,表示击键事件发生时先传给窗体,然后再传给有输入焦点的组件上,相当于窗体截获了原本属于组件的事件。缺省值为false,表示击键事件只送到当前有输入焦点的组件上。

  5. Menu属性用来指定窗体的主菜单。

  6.Visible属性用来确定窗体是否可见。

  此外还有一些运行时态属性,这些属性只有在程序运行的时候才能通过编程访问。这种属性主要有:

  Active
  属性用来确定窗体是否获得输入焦点。
  
  ActiveMDIChild
  这个函数将返回当前活动的子窗体。
  
  DropTarget
  属性用来指定窗体是否是拖放操作的对象。
  
  Parent
  属性用来设定包含窗体的窗口控件,通常是另一个窗体。如果窗体没有包含它的控件,那么它的Parent属性为nil。

2)问: Windows窗体有很多样式,比如对话框,弹出窗口。如果我要控制窗体的边界样式,应该怎么办?





  答:属性BorderStyle可以指定窗体边界的外观和行为。它一共有六种可能的取值。

  bsDialog
  表示大小不可变的标准的对话框边界。
  
  bsSingle
  表示大小不可变的单线边界。
  
  bsNone
  表示大小不可变、没有边界。
  
  bsSizeable
  表示标准的可改变大小的窗体。
  
  bsToolWindow
  与bsSingle时类似,但是标题较小,用做工具框窗口。
  
  bsSizeToolWin
  与bsSizeable时相似,但是标题较小,做工具框窗口。

  要注意的是,对于MDI子窗体,bsDialog或bsNone将不起作用。

  3)问:同样是获得焦点,ActiveControl与SetFocus()有什么不同?

  答: ActiveControl是把焦点交给组件,它是一个属性。而SetFocus()是组件主动要焦点,是一个方法。书写格式也不一样。例如,我们想使同样的一个Button1获得焦点,可以下的两种写法:

  ActiveControl=Button1或Button1=SetFocus()

  二者作用是一样的,不过一般都习惯用第一种方式。

  4)问:属性FormStyle有什么作用?

  答:属性FormStyle可以确定窗体的类型,它一共有四种属性值。

  fsNormal
  表示窗体既不是MDI父窗口也不是MDI子窗口,只可能是单文档SDI窗口或者对话框。这个属性值是缺省值。
  
  fsMDIChild
  表示这个窗体是一个MDI子窗口。
  
  fsMDIForm
  表示这个窗体是一个MDI父窗口。

  fsStayOnTop
  表示窗体始终保持在窗体所属工程中其它窗体的上面,除非还有别的窗体的FormStyle属性也被设置成了fsStayOnTop。

  要特别注意的是,在程序运行期间不要修改窗体的FormStyle属性。

  5)问:属性Position有什么作用?

  答:属性Position可以确定程序运行时出现在屏幕上的窗体的大小和位置,它有五种可能的取值。

  1.poDesigned表示使用设计时指定的尺寸和位置属性时显示窗体。尺寸属性是指Height和Width,位置属性是指Left和Top。这个属性值是缺省值。

  2.poDefault表示窗体在屏幕上显示的位置和大小由Windows决定。每次运行应用程序时,窗体都会稍微向下向右移动。

  3.poDefaultPosOnly表示窗体以设计时的窗体尺寸显示窗体,但是在屏幕上显示的位置由Windows确定。每次运行应用程序时,窗体都会稍微向下向右移动。当无法再向下移动时,就又会从屏幕的左上角开始显示。

  4.poDefaultSizeOnly表示窗体的位置由设计时指定的值确定,而尺寸由Windows确定。

  5.poScreenCenter表示使用设计时指定的尺寸和位置属性,在屏幕的中央显示窗体。

  6)问:如何最大化或最小化窗体?

  答:属性WindowState与窗体的显示有关,它有三种可能的取值。

  wsNormal
  窗体既不是最大化显示也不是最小化显示。这个值是缺省值。
  
  wsMinimized
  窗体最小化显示。
  
  wsMaximized
  窗体最大化显示。

  7)问:属性ClientHeight和ClientWidth有什么作用?

  答:这两个属性用来定义窗体用户区域的高和宽。所谓用户区域窗体的实际工作区域,就是除了窗体的标题栏、菜单条、工具条和状态条以及边框之外的窗体区域。所以对于新创建的窗体,它的用户区域比窗体的大小要稍微小一些,相对而言,窗体的大小是由属性Height和Width确定的。

  8)问:如何动态创建一个窗体呢?

  答:我们先创建一个主窗体MainForm,把她的Caption改为“主窗体”,把FormStyle属性改为fsMDIForm。再创建一个子窗体windows1,把Caption改为“子窗体”,把FormStyle属性改为fsMDIChild。

  fsStayOnTop
  表示窗体始终保持在窗体所属工程中其它窗体的上面,除非还有别的窗体的FormStyle属性也被设置成了fsStayOnTop。

  要特别注意的是,在程序运行期间不要修改窗体的FormStyle属性。

  5)问:属性Position有什么作用?

  答:属性Position可以确定程序运行时出现在屏幕上的窗体的大小和位置,它有五种可能的取值。

  1.poDesigned表示使用设计时指定的尺寸和位置属性时显示窗体。尺寸属性是指Height和Width,位置属性是指Left和Top。这个属性值是缺省值。

  2.poDefault表示窗体在屏幕上显示的位置和大小由Windows决定。每次运行应用程序时,窗体都会稍微向下向右移动。

  3.poDefaultPosOnly表示窗体以设计时的窗体尺寸显示窗体,但是在屏幕上显示的位置由Windows确定。每次运行应用程序时,窗体都会稍微向下向右移动。当无法再向下移动时,就又会从屏幕的左上角开始显示。

  4.poDefaultSizeOnly表示窗体的位置由设计时指定的值确定,而尺寸由Windows确定。

  5.poScreenCenter表示使用设计时指定的尺寸和位置属性,在屏幕的中央显示窗体。

  6)问:如何最大化或最小化窗体?

  答:属性WindowState与窗体的显示有关,它有三种可能的取值。

  wsNormal
  窗体既不是最大化显示也不是最小化显示。这个值是缺省值。
  
  wsMinimized
  窗体最小化显示。
  
  wsMaximized
  窗体最大化显示。

  7)问:属性ClientHeight和ClientWidth有什么作用?

  答:这两个属性用来定义窗体用户区域的高和宽。所谓用户区域窗体的实际工作区域,就是除了窗体的标题栏、菜单条、工具条和状态条以及边框之外的窗体区域。所以对于新创建的窗体,它的用户区域比窗体的大小要稍微小一些,相对而言,窗体的大小是由属性Height和Width确定的。

  8)问:如何动态创建一个窗体呢?

  答:我们先创建一个主窗体MainForm,把她的Caption改为“主窗体”,把FormStyle属性改为fsMDIForm。再创建一个子窗体windows1,把Caption改为“子窗体”,把FormStyle属性改为fsMDIChild。

选择“Project|Options…”菜单项,将会弹出一个如图所示的对话框。

  在这里我们可以通过下拉框选择主窗体(Main form),在左侧的Auto-create forms里列出了所有的窗口,这里面的窗口通常是动态创建,你可以把需要动态创建的窗口(Available forms)通过中间的那四个按钮调到右侧,然后OK就可以了。

  动态的创建的方法如下:

void _fastcall TForm1::Button1Click(TObject *Sender)

{

   Tform2 *Forms;

   try

   {

Form2=new TForm2(Application);//动态创建Form2

Form2->ShowModal();

delete Form2;//把Form2释放

   }

   catch(Exception &exception)

   {

delete Form2;

Application->ShowException(&exception);

}

}

要注意一般你可能不喜欢用上面的那种形式,而写成如下格式:

void _fastcall TForm1::Button1Click(TObject *Sender)

{

   Tform2 *Forms;

Form2=new TForm2(Application);//动态创建Form2

……

}

  你要记住,无论你的子窗体创建是否完成,你都必须运行delete来释放你刚才创建的子窗体,当然你也可以把释放的过程写在OnClose事件函数内,这个函数有一个参数为Action,它有四个取值:caNone为不关闭窗体,什么也不操作;caHide为不关闭窗体,但把它隐藏起来;caFree为关闭窗体,同时释放内存;caMinimize为最小化窗体,不关闭。所以我们也可以象下面这样来释放子窗体。

void _fastcall TForm2::FormClose(Tobject *Sender,TcloseAction &Action)

{

  Action=caFree;

}

  9)问:为什么我们用Close()不能关闭我当前活动的子窗体?

  答:关闭当前活动窗体,很多人会用如下的方法:

void _fastcall TForm1::Button2Click(Tobjcet *Sender)

{

  ActiveMDIChild->Close();//注意这是在主窗体(或者说在其它窗体)中来关闭当前活动的子窗体,这样做不好,一般的关闭应该象10)问中那样来做

}

此时窗体并没有关闭,而是最小化了,因此要在子窗体的OnClose事件中用如下代码来关闭。

void _fastcall TForm2::FormClose(Tobject *Sender,TCloseAction &Action)

{

  Action=caFree;

}

  这段程序不用多说了,上面都说过了。

  这里有一点要说明一下,就是在调用Close()时,会自动触发OnClose事件,而由上我们知道窗体没有关闭,而是最小化,说明在OnClose中Action的此时的值为caMinimize。所以我们要写上面的方法来关闭。

  10)问:Show()与ShowModal()有什么不同?

  答:我们的程序中不可能就只有一个Form,比如,有Form1和Form2两个窗口,我们在Form1中调用Form2应该先在Unit1.cpp的开头部分加入:

#include “Unit2.h”

  在要调用的地方加入:

Form2->Show();//或是Form2->ShowModal();

  两者的区别在于若使用了ShowModal()则必须关闭Form2,才能处理其它窗口的内容,而Show()则不用。当然你可以直接在Form2直接创建一个Button1来关闭她,程序内容如下:

void _fastcall TForm2::Button1Click(Tobject *Sender)

{

Close();

}

  在Close前,不需要加上Form2,因为这行程序就是在Form2上运行的,所以默认的父组件就是Form2。
2.文本输入组件
11)问:如果要实现文本输入,在C++Builder中应该怎么办?

  答:C++Builder常用文本输入组件来实现,常用的文本输入组件有Edit、MaskEdit 、Memo和RichEdit。他们的主要不同在于Edit和MaskEdit用于输入单行文本,而Memo和RichEdit可以输入多行文本。此外Label组件也可用来进行文本显示。

  Edit和MaskEdit是一个窗口控件,它可以获得输入焦点。当用户需要输入单行文本时,就应该使用编辑框。它通常与标签组件一起使用。

  12)问:编辑框(Edit)常用的属性有哪几个?

  答:编辑框常用的几个属性如下:

  Text属性是一个String类型的数据,它决定了在编辑框中出现的文本字符串。在编程中,我们经常要通过text属性获取编辑框中的文本字符串

  MaxLength是一个Integer类型的数据,它指定编辑框所能容纳的最大字符数。缺省情况下为0,表示长度不限。

   编辑框还可以用做口令输入。具体方法是,把PasswordChar属性设置为除#0之外的任何字符。这时,无论你在编辑框中输入什么字符,都只显示PasswordChar包含的字符。我们经常把PasswordChar设置为星号*,当用户输入口令时只显示星号。如输入#0表示编辑框正常显示。PasswordChar是一个字符类型的数据。

  如果要限制用户对编辑框写的权利。可以使用属性ReadOnly,当ReadOnly的值为True时只读。

13)问:标签控件(Label)起什么作用?

  答:标签的常用属性有Caption和FocusControl。

  Caption属性是字符串类型,用来指定标签的标题,也就是标签的显示内容。

  FocusControl属性是窗口控件类,用来指定一个与标签相连的窗口控件。从而允许这个控件使用快捷键来获得输入焦点。

  标签是一个典型的非窗口控件,它不能获得输入焦点,所以经常被用来给一些没有Caption属性的组件做标签。标签还能同时给这些组件提供快捷键的功能,允许用户通过快捷键获得输入焦点。

  14)问:那在Label中如何使用Caption与FocusControl呢?

  答:下面举个例子说吧(这个例子在第19问中会用到):

  首先在输入标题时需要指定一个快捷键,这可以用在一个字母前面加上一个连字符&来实现。单击caption属性输入栏,输入&N姓名,这里字母N就被指定为快捷键,要注意的是中文是不能被指定为快捷键的,只有26个英文字母才可以。

  然后,把标签的FocusControl属性与编辑框Edit1相连,选择FocusControl属性,从属性值字段列举的窗体上所有的窗口控件中选取Edit1。这样当用户按下Alt+N时,输入焦点就会转移到编辑框Edit1。

  15)问:我遇到一些程序,当在编辑中输入完文本后,按一下回车键,程序就开始执行了,C++Builder应该怎样实现?

  答:当然可以。当我们按下回车键时,产生了OnKeyPress事件。所以如果要在程序中处理这种事件,这就要编写OnKeyPress事件处理程序。

  还有三种事件是编辑框常用的事件:OnChange事件、OnEnter事件和OnExit事。每当编辑框中的文本发生改变时都会触发OnChange事件。当编辑框获得输入焦点时会触发OnEnter事件,而失去焦点时会产生OnExit事件。

16)问:简单说一下Memo组件的重要属性?

  答: Memo与Edit的属性有很多相似的,下面只来说一下Memo组件的重要属性。

  Lines属性是一个TStrings类的一个对象,它是由多个字符串组成的,每一个字符串就是Lines中的一个 元素。Memo组件的每一行文本都是Lines中的一个字符串。

  在设计阶段,如果要给Memo组件增加一些显示内容,可以在对象编辑器中选择属性Lines,单击Value列上的省略号按钮,这时会打开一个字符串编辑窗口。

  在这个编辑器中输入文本。编辑器中显示的所有内容都会出现在Memo组件中。

  Memo组件属性中:

  Alignment
   用来确定Memo组件中显示文本的对齐方式。

  WordWrap
   确定文本到达右边界时是否自动换行

  WantReturn
   确定用户是否可以在文本中插入回车符。

  WantTabs
   确定用户是否可以在文本中插入Tab字符。

  属性ScrollBar是一个常见的属性,它确定着滚动组件滚动条的行为。ScrollBar有四种可能的取值:

  SsNone
   表示没有滚动条;

  ssHorizonal
   表示只有水平滚动条;

  ssVertical
   表示只有垂直条;

  SsBoth
   表示既有水平滚动条也有垂直滚动条。

当显示的内容比较多时,应该选择ssBoth,这样才能够使用户看到所有的内容。

17)问:要在程序运行期间修改Memo组件的显示内容,应该怎么办?

  答:这就需要使用TStrings类的某些属性和方法。例如要给Memo组件增加一句话“我来了”,那么可以使用方法Add来完成。

Lines->Add(“我来了”);

  要寻找Memo中的某一行,可以使用Lines->Strings[n]的形式,不过要注意Lines的字符串是从0开始的,所以在与Memo中的实际行号对应时,行号需要减一。

  18)问:如果我要实现文本的剪切、复制和粘贴,应该怎么办?

  答:Memo组件提供了三个用来完成剪切、复制和粘贴的方法。CutToClipboard用来把Memo组件中被选中的文本剪切到剪切板。

  CopyToClipboard用来把Memo组件中被选中的文本复制到剪切板。

  PasteFromClipboard用来把剪切板的内容粘贴到Memo组件中光标所在的位置。

  19)问:前面讲了几个控件,能把他们综合起来编制一个程序吗?

  答:好的,就利用刚才已经放好的组件来编写一个用户姓名录入和显示的程序。

  这个程序将实现当在编辑框中输入文本并按下Enter键后,文本就被增加到Memo组件中。因此需要给编辑框组件增加事件处理过程。

  当用户按下Enter键时产生了OnKeyPress事件,所以应该编写这个事件的处理过程。

  选中组件Edit1,

  在对象观察器上选择Events标签页,

  双击Edit1的事件OnKeyPress,C++Builder将自动生成这个事件处理程序的代码模板。在里面编写如下代码:

void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)

{

AnsiString Temp("用户姓名:");

if((Key==0xD) && !Edit1->Text.IsEmpty())

      Memo1->Lines->Add(Temp+Edit1->Text);

}

或者写成如下的格式更好理解,它们是一样的。

void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)

{

       AnsiString Temp="用户姓名:";

       if((Key==VK_RETURN) && Edit1->Text!="")

      Memo1->Lines->Add(Temp+Edit1->Text);

}

  当用户输入文本并且按下回车键后,第三条语句将Temp和用户输入的字符串合并后加到Memo控件文本的末尾。

  现在,点击速度条上Run的按钮,运行这个程序,在编辑框中输入一个用户姓名,然后按回车键。用户的姓名就被自动加到了文本框的末尾。

  用鼠标在Memo控件中点击一下,将焦点移动到它里面,然后按下Alt+N加速键,可以看出,标签控件将焦点移动到了编辑框中。

20)问:BCB中有一个和写字板差不多的组件RichEdit,学习她主要注意那几个属性的呢?
   答:只要能够把设置缺省字符格式DefAttributes、设置选中字符格式SelAttributes与设置段落Paragraph三个属性掌握好就差不多了,因为她的其它属性与Memo差不多。

    缺省字符格式DefAttributes、设置选中字符格式SelAttributes是TtextAttributes对象,它是用来控制字符格式的,它的Color、Height、Name、Size、Style、Pitch等性性和字体Tfont对象差不多,当然还有一些象CharSet、ConsistentAttributes、Protected等一些不太常用的属性。

    设置段落Paragraph是TparaAttributes对象,用来设置段落的对齐Alignment、首行缩进FirstIndent、左缩进LeftIndent、右缩进RightIndent、编号方式Numbering、制表位Tab等属性。

    段落的对齐Alignment的取值是taLeftJustify左对齐、taCenter居中和taRightJustify右对齐。

    编号方式Numbering,用来设置编号方式,取nsNone表示没有编号,取nsBulet表示采用悬挂缩进方式编号。

    制表位Tab用来设置某个制表位所在的位置。其声明为:_property int Tab[Byte Index]。第一个制表位为Tab[0],依次类推。

  注:本文的所有例程都在BCB6、WINXP下编译通过。

3. 按钮类组件
  
  21)问:在进行Windows程序界面设计中,经常会用到按钮,在C++Builder中,按钮一定是通过按钮组件来实现的吗?

答:是的,并且C++Builder的按钮类组件十分丰富。BCB提供了两类按钮类组件:一类是执行类按钮,另一类是信息类按钮。所谓执行类按钮是指它们通常用来启动程序运行的,比如按钮、位图按钮、加速按钮。而信息类按钮一般用来获取信息,包括单选按钮和复选框。灵活地使用各种按钮,不仅可以使程序更加丰富多彩,而且可以提高程序的性能。

  22)问:那么按钮组件有哪些常用的属性和方法呢?

  答:对于按钮组件,Caption属性用来描述按钮的标题,也就是按钮上显示的文本,它与标签组件很相识,我们同样可以在这个属性中为按钮指定快捷键。

  当Cancel属性值为True时,用户无论何时按下Esc键,都会产生OnClick事件,当窗体上有多个按钮时,Esc键触发TabOrder值最小的那个按钮的OnClick事件。它的缺省值为False

  当Default属性值为true时,用户无论何时按下Enter键时,都会产生OnClick事件,与Cancel属性不同的是,如果输入焦点正好在一个按钮上,那么会产生这个按钮的OnClick事件。否则,产生TabOrder的值最小的那个按钮的OnClick事件。它的缺省值为True

  Hint属性保存着按钮的提示内容,当用户把鼠标光标停留在按钮上时,就会显示提示信息。

  ShowHint属性用来确定是否显示提示文本,缺省值为False。

  按钮常用的事件就是OnClick事件,OnClick事件在鼠标单击按钮时产生,另外,通过快捷键、enter键和Esc键也可以产生OnClick事件,一般情况下,按钮都需要增加OnClick事件处理程序。

  23)问:那么位图按钮又有什么特点呢?

  答:位图按钮BitBtn除了可以像普通按钮那样显示文本外,还可以显示图形,除了具有一般按钮所具有的全部属性外,位图按钮还有一个特有的Kind属性。这个属性用来设定按钮为几种预定义图形按钮风格中的哪一种。这是几种预定义按钮风格。这些做好的按钮如下表:
 

Kind属性值

按钮外观

等价属性设置

bkCustom

缺省值

用来给用户制定

bkOK

Caption=”OK”

ModalResult=mrOK

Default=true

bkCancel

Caption=”Cancel”

ModalResult=mrCancel

Cancel=true

bkYes

Caption=”&Yes”

ModalResult=mrYes

Default=true

bkNo

Caption=”&No”

ModalResult=mrNo

Cancel=true

bkHelp

Caption=”&Help”

bkClose

Caption=”&Close”

bkAbort

Caption=”Abort”

ModalResult=mrAbort

bkRetry

Caption=”&Retry”

ModalResult=mrRetry

bkIgnore

Caption=”&Ignore”

ModalResult=mrIgnore

bkAll

Caption=”&All”

ModalResult=mrAll

  当把Kind的属性值设置为bkCustom时,还可以给位图按钮指定其他的图形,具体的方法是,在对象编辑器中选择Glyph属性,然后单击Value列中的省略号按钮,这时会出现一个图形编辑对话框,要求指定位图的位置。

  单击Load按钮,在文件打开对话框中选择一个位图文件就可以了。要注意的是,如果选择的位图太大,位图按钮不会自动调整其尺寸,这时你只能看到一部分的图形。

  24)问:位图按钮组件的NumGlyph属性有什么作用?

  答:属性NumGlyph指出位图按钮使用的位图的数目,当你需要位图按钮使用多个位图分别表示按下,弹起等不同状态时,必须保证这些位图具有相同的尺寸,并且一个接着一个地水平排列着。

  在C++Builder中,一个位图按钮最多可有四个位图,因此,NumGraph地取值范围只能是1到4,C++Builder将根据位图按钮地状态确定显示哪个位图。

  一般来说,当按钮未选中时显示第一个位图。

  当按钮不能选择时,显示第二个位图,

  当按钮被单击时显示第三个位图,

  当用户释放鼠标键时,又会重新显示第一个位图,

  当没有希望的位图时,那么所有地状态都使用第一个位图。

  25)问:快捷按钮有哪几个重要属性?

  答:快捷按钮与位图按钮很相似,也可以显示图像,但也有一些不同之处:快捷按钮一般都比较小,缺省大小25*25,基本上都是只显示图像而不显示文字,最大差别是,快捷可以保持在按下的状态,而其它两类按钮不能。快捷按钮一般都是用来制作工具栏按钮,这时要和Panel配合使用。下面来看一下它的重要属性:

  AllowAllUp:设置一个组的快捷按钮是否可以全部处于弹起的状态。缺省为false,这时可以用来模拟单选按钮,让同一个组的总有一个按钮处在按下状态。如果一个组中只有一个快捷按钮,把这个属性改为true,这时这个按钮就可以在按下和弹起两个状态之间切换,可以用来模拟一个复选按钮。

  Down:表示按钮是否按下,若设为true,则处于按下的状态。

  GroupIndex:用来把几个这个属性相同的快捷按钮编为一组,即相同取值的按钮为一组。缺省为0,表示这个按钮不编成组。

  26)问:那么单选按钮又有什么特点呢?

  答:单选按钮RadioButton是相互排斥的一种选择组件,在一组单选按钮中用户一次只能选取一个单选按钮。

  虽然你可以只使用一个单选按钮,但是那样单选按钮也就失去了意义。单选按钮一般都是成组出现的。

  单选按钮只有一个比较特殊的属性Checked,它表示按钮是否被选中。缺省情况下,Checked的属性是False,表示按钮未选中。

  另外单选按钮也具备Caption属性,这就意味着它也可以通过快捷键来选中。

  单选按钮在成组使用时有一些特点需要掌握。当你在同一容器(如:Form、Panel、GroupBox等)上直接放置单选按钮时,这些单选按钮自成一组,也就是说,无论在容器上放置2个或者几十个单选按钮,它们都是一组的,每次只能选中它们中的某一个。

  27)问:如果我想在窗体上放置不止一组按钮,应该怎么办?

  答:可以用两种方法。一种是使用组合框(GroupBox),另一种是使用单选按钮分组框(RadioGroup)。

  组合框顾名思义就是用来把许多组件组合起来,使窗口变得整齐而有条理,每一组不同的按钮使用一个组合框。在设计时,首先把组合框放在窗体上,然后再把单选按钮放在分组框上。要记住的是,放置次序不能颠倒。一旦把单选按钮放在分组框中,那么这个单选按钮就属于这个组合框了,你无法把它从组合框中移走,如果删除组合框的话,分组框中所有的单选按钮也会被同时删除。

  在实际应用中,我们经常使用单选按钮分组框而不是单选按钮。因为单选按钮分组框可以包含多个单选按钮,而它实际上只是一个组件。这比使用分组框和多个单选按钮更直观和简单。

  28)问:单选按钮分组框又有哪些特殊的属性呢?

  答: 单选按钮分组框有三个属性是比较特殊的:

  属性Items是类TStrings的一个对象,这一点与Memo组件中的Lines属性很相似,但是它们的含义不同,Lines属性包含Memo组件中显示的每一行字符串,而Items属性虽然也包含许多字符串,但是每一个字符串代表单选按钮组中的一个单选按钮。

  单击Items属性Value列中的省略号按钮,可以打开一个字符串编辑器,然后在这个编辑器中可以输入单选按钮的标题。每个单选按钮占用一行。

  Columns属性决定着单选按钮分组框内分栏的数目,默认是1,最多可以有16栏,即16列。

  ItemIndex属性为单选分组框中被选中项的序号。-1表示不指向任何一个项。

  29)问:复选按钮(CheckBox)有什么作用?

  答:复选按钮与单选按钮不同,你可以一次选择多个复选按钮。复选按钮有几个比较重要的属性。

  Alignment属性控制复选框标题的位置。

  taRightJustify
  标题出现在复选框的右边
  
  taLeftJustify
  标题出现在复选框的左边

  缺省值为taRightJustify。

  AllowGrayed属性决定复选框是否可以处于灰色的状态,当属性值为True时,复选框有三种状态,选中、未选中、和灰色;当属性值为False时,复选框只有两种状态。缺省值为false。

  Checked属性确定复选框是否被选中。缺省值为false。

要知道复选框是选中状态、未选中状态还是灰色状态。,可以在运行的时候,用程序读取运行时态变量State的值,缺省值为cbUnChecked。

  虽然复选框之间并不互相排斥,也就是说,直接放置在窗体上的每一个复选按钮相互之间都不干扰,但是最好还是把复选框分组使用。这样做的好处是便于用户理解。

  30)问: CheckBox、RadioButton如何完成动态改变其按钮的标题? RadioGroup能动态添加吧?读取上面三个组件标题又如何做呢?
  答:CheckBox、RadioButton的属性里有一个Caption,它的属性值就是按钮的标题,所以应该说对这两个组件来说很容易做到的:

  CheckBox1->Caption=”信息”;

  Label1->Caption= CheckBox1->Caption;

  RadioButton与CheckBox一样,这里就不多说了。

  而RadioGroup里面有一个Items属性,这在《闲谈BCB》中说过这个问题,所以你要添加按钮,可以用下面的方法:

  RadioGroup1->Items->Add(“我是新来的”);

  读取可以利用ItemsIndex来完成:

  Label1->Caption=RadioGroup1->Items->Strings[RadioGroup1->ItemIndex];

  String是把选中的序号转换成你需要的文本,因为Items是Tstring对象,这类情况在你以后的学习中会经常看到的。

  要注意在RadioGroup中也有一个Caption,这是用来给单选分组框设置标题的,这个标题与单选的文字无关。

4.列表类组件
  31)问:当我需要使用多个选项的时候,使用单选按钮或复选框来进行选择不是很恰当,因为在窗体上放置大量的按钮既不利于布局的美观,又会消耗大量的系统资源,C++Builder有什么解决办法吗?

答:可以使用列表框(ListBox、CheckListBox)或组合框(ComboBox)这两类最常用的列表组件。

  32)问:列表框有那些主要属性?

  答:列表组件ListBox在缺省情况下,只能进行单项选择,当属性MultiSelected为True时,可以进行多项选择。这时你只要单击想要的选项,那么这些选项都会被选中。



  Items属性:列表框中的所有选项都是通过这个属性来进行访问的。设置时只要点击Items右边的“…”就可以编辑了。

  当属性ExtendedSelect也等于True时,有两种方法可以进行多项选择。一种是单击选项同时按下Ctrl键,这样可以选中两个选项之间的所有选项。它的缺省值为False。

  Sorted属性确定列表框中显示的内容书否按照字母顺序排列。缺省值为False。

  当不允许多项选择时,我们通过属性ItemIndex就可以返回被选中的选项。但是,如果打开了多项选择,那么属性ItemIndex只返回最后个被选中的选项序号(有些书上也说返回选中选项中具有输入焦点的选项序号,但我觉得这种说法有点不易让初学者理解)。

  SelCount属性在MultiSelected属性为True时,指出了列表框中被选中项目的个数。当MultiSelected属性为False时,它的值为-1。

  Selected属性指出了列表框中的某个项目是否被选中。

  TcheckListBox是从TcustomListBox继承下来的的,TListBox也是直接从TcustomListBox继承下来的,因此这两个组件是兄弟关系,它们的属性和使用都非常相似。下面来看看它的不同之处:

  AllowGrayed属性和多选按钮一样,当属性值为True时,则列表框中的选项有三种状态:选中、未选中和选中但变灰;当属性值为False时,列表框只有两种状态。缺省值为false。

  Checked其声明为:_property  bool  Checked[int Index];这个属性用来返回或者设置列表框中的指定选项是否被选中。其中参数Index表示指定的选项的序号。

  32)问:那么,组合框和列表框相比有什么相似之处和不一样的地方呢?

  答:首先,从外观上来说,列表框占据了比较大的空间,而组合框只需要一行的空间就可以了。从另一方面来说,组合框还带有一个编辑框,用户可以直接在编辑框中输入文本,组合框在一般情况下只显示这个编辑框,当用户单击组合框右边的下拉箭头时,就会显示一个包含所有选项的下拉列表。
  
  组合框和列表框最大的不同是组合框不能进行多项选择。

  组合框与列表框有一定的相似之处,就是它们都能够包含许多的选项。但是组合框还是有不少独特的属性。

  33)问:组合框有哪些常用属性及事件呢?

  答:属性Style决定着组合框的样式,C++Builder为组合框定义了五种不同的样式。

  CsDropDown:这时为一个标准的组合框,由一个编辑框和下拉列表组成。

  CsDropDownList:与标准组合框相似,但不能在编辑框中输入文本。

  CsSimple:没有下拉列表的组合框,只是一个编辑框,也就是说只能输入不能选择。

  csOwnerDrawFixed和csOwnerDrawVariable这两种样式的组合框常用于需要图像作为项目时,当然你输入字符串也可以。前面一种样式组合框中各个项目的高度是固定的,而后面一种样式的高度可以变化,也就是说,各个项目的高度可以不一样,此外,在这两种样式中,编辑框是不可输入的。

  Text属性用来设置或者返回组合框中显示出来的文本内容。

  当编辑框中的内容发生变化时将触发OnChange事件。所以在组合框里我们用的就是它。

  注意下面四段两组语句的区别与联系:

  //………………第一组

  void _fastcall TForm1::ComboBox1Change(TObject *Sender)

  {

  if(ComboBox1->Text!=””)

  Edit1->Font->Size=StrToInt(ComboBox1->Text);

  }

  上面的代码还可以写成下面的样子,它们的作用是一样的:

  void _fastcall TForm1::ComboBox1Change(TObject *Sender)

  {

  if(!ComboBox1->Text.IsEmpty())

  Edit1->Font->Size= ComboBox1->Text.ToInt();

  }

  //………………第二组

  void _fastcall TForm1::ComboBox2Change(TObject *Sender)

  {

  Edit1->Font->Name= ComboBox2->Text;

  }

  也可以用下面的代码,它们在这里是等价的:

  void _fastcall TForm1::ComboBox2Change(TObject *Sender)

  {

  Edit1->Font->Name= ComboBox2->Items->String[ComboBox2->ItemIndex];

  }

  我想通过对比,你会明白这些语句的区别与联系的,什么时候用什么样的语句,细细品味一下你就会明白了。

  34)问:前面您提到了面板组件,它是一种什么类型的组件?

  答:它是一种容器组件,容器组件是可以包含其他组件的组件,最典型的容器组件就是窗体。其他比较常用的容器组件有面板(Panel)、组合框(GroupBox)。

  面板组件可以容纳其他组件。任何放置在面板上的组件都会成为面板的子组件,当你删除面板组件时,放置在面板上的其他组件也同时被删除了,这是容器组件的共同特点。

  面板组件没有什么特别的属性,只有BevelInner(面板内部斜面),BevelOuter(面板外部斜面),BevelWidth(斜面宽度,单位像素),BorderStyle(边界风格)和BorderWidth(边界宽度)几个属性有一些特点。这些属性的任意组合可以生成各种效果的边框。你可以设置这几个属性的值,可以得到不同的面板效果。

  其中BevelInner(面板内部斜面),BevelOuter(面板外部斜面)的属性值是一样的:bvNone(缺省值)表示没有斜面;

  bvLowered表示为沉降的斜面;

  bvRaised表示为上升的斜面。

  组合框(GroupBox)属性中你只要设置好Caption就可以了,它是标题的名称,表示此组合框类别、功能、选项等。GroupBox1为默认名称。

  5.特殊的输入控制类组件
  35)问:C++Builder有哪些输入控制类组件?

  答:C++Builder输入控制类组件主要包括滚动条(ScrollBar)、轨迹条(TrackBar)、进程条(ProgressBar)以及加减组件UpDown,它们都可以实现边续范围内数值的选择。

  36)问:滚动条主要用在什么地方,它又有哪些常用属性呢?

  答:滚动条是常见的组件,它经常出现在列表框、Memo等组件中。这时,它是作为这些组件的一部分而存在的。其实滚动条还可以单独使用,单独使用时,滚动条一般用来控制连续的数值输入。象调节音量等,都可以使用滚动条输入。

  滚动条有这样一些常用属性

  1.Position:这个属性用来设置或者返回当前流动条中滑块的位置。属性Max,Min,用来设置滚动条可以滚动的最大或最小位置。当Position等于Max时,滚动块位于滚动条的最右端;当Position等于Min时,滚动块位于滚动条的最左端。当Position等于Max和Min之间的某一个值时,滚动块位于滚动条中间的某个位置。

  2.属性Kind。属性Kind有两个可能的取值:sbHorizontal(缺省值)和sbVertical,分别表示水平滚动条和垂直滚动条。

  3.属性SmallChange决定当用户单击滚动条两端的箭头按钮时滚动块移动的距离。

  4.属性LargeChange确定当用户单击滚动块两边的空白或按下PgUp和PgDn键时,滚动块移动的距离。属性LargeChange和SmallChange的取值范围是1到32767。


 37)问:滚动条能够响应哪些常用事件呢?

  答:滚动条的常用事件是OnChange,只要属性Position的值发生改变都会产生这个事件。一般情况下,了解滚动条的这个属性就可以了。

  但是有时候可能需要更详细地了解用户单击了滚动条的哪个位置,这时就需要响应OnScroll事件,其声明为:-_property TScrollEvent OnScroll;其中TscrollEvent的声明为:typedef void fastcall (closuer TScrollEvent)(System::Tobject Sender,TscrollCode ScrollCode,int &ScrollPos); OnScroll事件处理程序带有三个参数:

  其中参数Sender指出了是哪个对象发送了这个消息,参数ScrollPos指出了滚动块的位置,参数ScrollCode返回滚动条的状态,这些状态是用这样一些参数值表示的,

  scLineUp
  表示用户单击了滚动条左端的箭头按钮(水平滚动条)或上端的箭头按钮(垂直滚动条)。
  
  scLineDown
  表示用户单击了滚动条右端的(水平滚动条)或下端的箭头按钮(垂直滚动条)。
  
  scPageUp
  表示用户单击了滚动块左边(水平滚动条)或上边(垂直滚动条)的区域。
  
  scPageDown
  表示用户单击了滚动块右边(水平滚动条)或下边(垂直滚动条)的区域。
  
  scPosition
  表示用户移动了滚动条但是已经释放了。
  
  scTrack
  表示用户正在移动滚动块。
  
  scTop
  表示用户把滚动块移动到了滚动条的左端(水平滚动条)或顶端(垂直滚动条)。
  
  scBottom
  表示用户把滚动块移动到了滚动条的右端(水平滚动条)或下端(垂直滚动条)。
  
  scEndScroll
  表示用户结束了移动滚动块的操作,释放了鼠标或者键盘按键。

posted on 2007-06-29 11:13 东东会会 阅读(3856) 评论(0)  编辑 收藏 引用 所属分类: C++Builder 基础


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理