VFP6.0中ActiveX控件TreeView 使用实例
--------------------------------------------------------------------------------
tech.sina 2000/09/20  软件世界 陈学军
  ActiveX控件早已为大多数程序开发人员作为一重要工具来使用。由于它与开发语言无关,任何支持ActiveX控件的软件平台上,都可以使用ActiveX控件。就像使用WINDOWS控件一样自如。然而,ActiveX控件在具体到某种开发工具中去使用时会遇到很多问题,这一点在许多刊物的文章都经常被提出讨论,但大多数都是针对Vc,Delphi,VB,PB等开发平台下的ActiveX控件。其实,在上述平台中使用ActiveX控件基本上能在其帮助功能中,开发人员依照其示例最终能到ActiveX控件的属性,方法,事件的使用说明。甚至有些开发工具已将部分ActiveX控件作为其常用表单控件,使开发人员使用起来感到非常方便。
  可是在VFP开发平台下,去使用ActiveX控件就不如上述开发工具那样的幸运,因为VFP对其根本就未涉及到相关语法说明和示例,使VFP开发者感到尴尬与茫然。又因,很少有介绍这方面文章。因此,笔者就以正在开发“楼盘销售软件”为例介绍一下TreeView控件在VFP中的具体使用,以供与笔者同感的VFP同仁参考。
  一、 首先介绍TreeView 控件
  TreeView 控件显示 Node 对象的分层列表,每个 Node 对象均由一个标签和一个可选的位图组成。TreeView 一般用于显示文档标题、索引入口、磁盘上的文件和目录、或能被有效地分层显示的其它种类信息。
  Node 对象是 TreeView 控件中的一项,它包含图像和文本。Nodes 集合包含一个或多个 Node 对象。 语法:treeview.Nodes,treeview.Nodes.Item(index)。可以使用标准的集合方法(例如 Add 和 Remove 方法)操作 Node 对象。可以按其索引或存储在 Key 属性中的唯一键来访问集合中的每个元素。为选择指定的 Node 对象,必须通过它的 Index 属性或 Key 属性的值去引用它。
  在 Treeview 控件的 Nodes 集合中添加一个 Node 对象:object.Add(relative, relationship, key, text, image, selectedimage) Nodes 集合是一个基于 1 的集合。在添加 Node 对象时,它被指派一个索引号,该索引号被存储在 Node 对象的 Index 属性中。这个最新成员的 Index 属性值就是 Node 集合的 Count 属性的值。因为 Add 方法返回对新建立的 Node 对象的引用,所以使用这个引用来设置新 Node 的属性十分方便。下面介绍一下节点几个属性:
  relative 是可选的。它表示已存在的 Node 对象的索引号或键值。而新节点与已存在的节点间的关系,可在下一个参数 relationship 中到。
  relationship 是可选的。它表示指定的 Node 对象的相对位置,如设置值中所述
。relationship 的设置值是:
  tvwFirst为常数 ,0 为值。它表示首的节点。该 Node 和在 relative 中被命名的节点位于同一层,并位于所有同层节点之前。
  TvwLast为常数,1 为值。它表示最后的节点。该 Node 和在 relative 中被命名的节点位于同一层,并位于所有同层节点之后。任何连续地添加的节点可能位于最后添加的节点之后
  TvwNext为常数,2 为缺省值。它表示下一个节点。该 Node 位于在 relative 中被命名的节点之后。
  TvwPrevious为常数, 3为值。它表示前一个节点。该 Node 位于在 relative 中被命名的节点之前。
  TvwChild为常数, 4 为缺省值。它表示子节点。该 Node 成为在 relative 中被命名的节点的子节点。
  注意 如果在 relative 中没有被命名的 Node 对象,则新节点被放在节点顶层的最后位置。
  key 是可选的。它表示节点中唯一的字符串,可用于用 Item 方法检索 Node。
  text 是必需的。它表示在 Node 中出现的字符串,即节点的名称。
  index 是整数或字符串,它唯一地标识 Nodes 集合的一个成员。整数是 Index 属性的值,字符串是 K
ey 属性的值。
  FullPath 属性,这个属性返回在 TreeView 控件中引用的 Node 对象的完整限定路径。当赋予该属性为字符串变量时,该字符串被设为具有指定索引的 FullPath 节点。
  Indentation 属性返回或设置控件中对象的缩进宽度。
  LabelEdit 属性返回或设置一个值,它确定是否可以编辑在 TreeView 控件中的 Node 对象的标签。
  二、源程序示例
  在该程序中TreeView控件能够实现项目、楼宇、单元、楼层这样四层逐级包含的关系。用户只要简单地单击每层节点“+”/“-”就能很直观地观察到一个项目中包含几幢楼,一幢楼包含几个单元,一个单元又有多少楼层。通过与页框PAGEFRAME中每一页的表格GRID联合使用,只要双击每层节点就可在相应的表中增加记录并在GRID中显示相应的详细信息。值得说明的是该程序可以实现多个项目的显示,项目节点与项目节点之间是平行同级的关系,仅仅是第二个项目首节点排在第一个之后。而楼宇节点是项目节点的子节点,单元节点是楼宇节点的子节点,楼层节点是单元节点的子节点。
  源程序1实现TreeView 控件初始化工作,即表单中的Olecontrol1.init事件填写源程序1中所有代码。源程序2实现与页框配合,显示节点相应的详细内容,即表单中的Olecontrol1.NodeClick事件填写源程
序2中所有代码。
  源程序1代码如下:
  LOCAL M.L_XMCOUNT,I,J,K,L,M.L_NODES,M.L_LYCOUNT,M.L_DYCOUNT,M.L_LCCOUNT
  THIS.NODES.CLEAR &&清除所有节点
  THIS.LABELEDIT=1 &&节点
标签可以编辑
  THIS.Indentation=10 &&缩进宽度为10个象素
  SELECT SF_XMXX
  set dele on
  M.L_XMCOUNT=RECCOUNT()
  FOR I=1 TO M.L_XMCOUNT
  SELECT SF_XMXX
  GO I
  if !delete()
  M.L_NODES=THIS.NODES.ADD(,,'XM'+XM_BH,XM_MC) &&向节点集合加入第一个节点KEY=XM,TEXT=项目名称
  M.L_NODES.EXPANDED=.T. &&所有节点可以折叠
  M.L_NODES.FORECOLOR=RGB(0,0,255) &&设置所有节点的前景颜
  M.P_XMBH=XM_BH
  =REQUERY('VIEW_XMLY')
  M.L_LYCOUNT=RECCOUNT('VIEW_XMLY')
  IF M.L_LYCOUNT>0
  FOR J=1 TO M.L_LYCOUNT
  SELECT VIEW_XMLY
  GO J
  if !delete()
  &&向'项目'父节点加入子节点'楼宇'KEY=LY,TEXT=楼宇实际编号
  THIS.NODES.ADD('XM'+SF_XMXX.XM_BH,4,'LY'+VIEW_XMLY.LY_BH,VIEW_XMLY.LY_SJBH)
  M.P_LYBH=VIEW_XMLY.LY_BH
  =REQUERY('VIEW_XMDY')
  M.L_DYCOUNT=RECCOUNT('VIEW_XMDY')
  IF M.L_DYCOUNT>0
  FOR K=1 TO M.L_DYCOUNT
  SELECT VIEW_XMDY
  GO K
  if !delete()
  &&向'楼宇'父节点加入子节点'单元'KEY=DY,TEXT=单元实际编号
  THIS.NODES.ADD('LY'+VIEW_XMLY.LY_BH,4,'DY'+VIEW_XMDY.DY_BH,ALLTRIM(STR(VIEW_XMDY.DY_SJBH))+'单元')
  M.P_DYBH=VIEW_XMDY.DY_BH
  =REQUERY('VIEW_XMLC')
  M.L_LCCOUNT=RECCOUNT('VIEW_XMLC')
  IF M.L_LCCOUNT>0
  FOR L=1 TO M.L_LCCOUNT
  SELECT VIEW_XMLC
  GO L
  if !delete()
  &&向'单元'父节点加入子节点'楼层'KEY=LC,TEXT=楼层实际编号
  THIS.NODES.ADD('DY'+VIEW_XMDY.DY_BH,4,'LC'+VIEW_XMLC.LC_BH,ALLTRIM(STR(VIEW_XMLC.LC_SJCH))+'层')
  endif
  ENDFOR
  ENDIF
  endif
  ENDFOR
  ENDIF
  endif
  ENDFOR
  ENDIF
  endif
  ENDFOR
  源程序2如下:
  *** ActiveX 控件事件 ***
  LPARAMETERS node
  *** ActiveX Contro1l Event ***
  LOCAL M.L_NODES,M.L_SELECTED,L_INDEX
  M.L_SELECTED=THISform.Olecontrol1.SELECTEDITEM.INDEX
  M.L_NODES=THISFORM.OLECONTROL1.NODES(M.L_SELECTED)
  THISFORM.PAGEFRAME1.PAGE1.CAPTION='项目信息'
  THISFORM.PAGEFRAME1.PAGE2.CAPTION='楼宇信息'
  THISFORM.PAGEFRAME1.PAGE3.ENABLED=.F.
  THISFORM.PAGEFRAME1.PAGE3.CAPTION='单元信息'
  THISFORM.PAGEFRAME1.PAGE4.ENABLED=.F.
  THISFORM.PAGEFRAME1.PAGE4.CAPTION='楼层信息'
  DO CASE
  CASE M.L_NODES.KEY='XM'
控件的使用  THISFORM.PAGEFRAME1.ACTIVEPAGE=1
  CASE M.L_NODES.KEY='LY'
  THISFORM.PAGEFRAME1.ACTIVEPAGE=2
  CASE M.L_NODES.KEY='DY'
  THISFORM.PAGEFRAME1.PAGE3.ENABLED=.T.
  THISFORM.PAGEFRAME1.ACTIVEPAGE=3
  CASE M.L_NODES.KEY='LC'
  THISFORM.PAGEFRAME1.PAGE4.ENABLED=.T.
  THISFORM.PAGEFRAME1.ACTIVEPAGE=4
  ENDCASE
  if M.L_NODES.KEY<>'XM'
  DO CASE
  CASE M.L_NODES.KEY='LY'
  M.P_XMBH=substr(M.L_NODES.KEY,3,2)
  M.P_LYBH=RIGHT(M.L_NODES.KEY,LEN(M.L_NODES.KEY)-2)
  =REQUE
RY('VIEW_XMDY')
  IF RECCOUNT('VIEW_XMDY')=0
  SELE SF_LYXX
  SET ORDER TO LYBH
  SEEK M.P_LYBH
  IF FOUND()
  DYZS=SF_LYXX.LY_DYZS
  ENDIF
  FOR I=1 TO DYZS
  SELECT VIEW_XMDY
  APPEND BLANK
  THISFORM.PAGEFRAME1.PAGE3.GRID1.afterROWCOLCHANGE
  ENDFOR
  GO TOP
  THISFORM.PAGEFRAME1.fresh
  ENDIF
  THISFORM.PAGEFRAME1.PAGE2.CAPTION=ALLTRIM(M.L_NODES.TEXT)
  THISFORM.PAGEFRAME1.PAGE3.ENABLED=.T.
  THISFORM.PAGEFRAME1.PAGE1.CAPTION=ALLTRIM(des(M.L_SELECTED).FULLPATH,AT('\',des(M.L_SELECTED).FULLPATH)))
  =REQUERY('VIEW_XMLY')
  sele view_xmly
  CASE M.L_NODES.KEY='DY'
  M.P_XMBH=substr(M.L_NODES.KEY,3,2)
  M.P_lyBH=substr(M.L_NODES.KEY,3,4)
  M.P_DYBH=RIGHT(M.L_NODES.KEY,LEN(M.L_NODES.KEY)-2)
  =REQUERY('VIEW_XMLC')
  IF RECCOUNT('VIEW_XMLC')=0
  SELE SF_DYXX
  SET ORDER TO DYBH
  SEEK M.P_DYBH
  IF FOUND()
  LCZS=SF_DYXX.DY_LCS
  ENDIF
  FOR I=1 TO LCZS
  SELECT VIEW_XMLC
  APPEND BLANK
  THISFORM.PAGEFRAME1.PAGE4.GRID1.afterROWCOLCHANGE
  ENDFOR
  GO TOP
  ENDIF
  THISFORM.PAGEFRAME1.PAGE3.CAPTION=ALLTRIM(M.L_NODES.TEXT)
  THISFORM.PAGEFRAME1.PAGE4.ENABLED=.T.
  THISFORM.PAGEFRAME1.PAGE1.CAPTION=ALLTRIM(des(M.L_SELECTED).FULLPATH,AT('\',des(M.L_SELECTED).FULLPATH)))
  =REQUERY('VIEW_XMdy')
  sele view_xmdy
  CASE M.L_NODES.KEY='LC'
  M.P_XMBH=substr(M.L_NODES.KEY,3,2)
  M.P_lyBH=substr(M.L_NODES.KEY,3,4)
  M.P_dyBH=substr(M.L_NODES.KEY,3,6)
  M.P_LCBH=RIGHT(M.L_NODES.KEY,LEN(M.L_NODES.KEY)-2)
  THISFORM.PAGEFRAME1.PAGE4.CAPTION=ALLTRIM(M.L_NODES.TEXT)
  THISFORM.PAGEFRAME1.PAGE1.CAPTION=ALLTRIM(des(M.L_SELECTED).FULLPATH,AT('\',des(M.L_SELECTED).FULLPATH)))
  =REQUERY('VIEW_XMlc')
  sele view_xmlc
  ENDCASE
  ELSE
  THISFORM.PAGEFRAME1.PAGE1.CAPTION=des(M.L_SELECTED).TEXT)
  L_INDEX=M.L_SELECTED
  M.P_XMBH=RIGHT(this.NODES(M.L_SELECTED).KEY,LEN(this.NODES(M.L_SELECTED).KEY)-2)
  =REQUERY('VIEW_XMLY')
  IF RECCOUNT('VIEW_XMLY')=0
  SELE SF_XMXX
  SET ORDER TO XMBH
  SEEK M.P_XMBH
  IF FOUND()
  ZLS=SF_XMXX.XM_ZLS
  ENDIF
  FOR I=1 TO ZLS
  SELECT VIEW_XMLY
  APPEND BLANK
  THISFORM.PAGEFRAME1.PAGE2.GRID1.AFTERROWCOLCHANGE
  ENDFOR
  GO TOP
  ENDIF
  ENDIF
  THISFORM.REFRESH
  以上程序已经测试通过。
VFP使用OLE功能驱动EXECL
OLE(Object  Linking  and  Embedding)对象链接与嵌入,是WINDOWS应用程序间相互传递和共享数据的一种
有效方法。VFP借助于OLE不仅可共享其它应用程序的数据,而且还能以对象方式直接控制其它应用程序的运
行,从而进一步扩展VFP的功能。VFP支持直接在
程序中创建、使用和控制OLE对象,实现OLE自动化。作为OLE
客户VFP与作为OLE服务器的EXCEL具有良好的编程接口,下述程序段用OLE方式实现所要求的功能。
程序首先生成一个EXCEL的OLE对象OleApp以便对其进行操作,然后利用OLE功能从EXCEL表单中获取欲查询的
课程名,并控制EXCEL生成新的工作表,VFP的查询结果仍然使用剪切板的方式传递至EXCEL工作表。 
OleApp=CREATEOBJECT( "Excel.Application ")  &&  打开EXCEL,产生OLE对象
OleApp.Application.Caption= "VFP交互编程 "  &&  指定标题栏名称
OleApp.Application.Visible=.T.  &&  置EXCEL可见
OleApp.Application.WorkBooks.Open( "d:\vfp\VFP交互.xls ")  &&  打开EXCEL工作簿
DO  WHILE  .T.
WITH  OleApp.Application
nAnswer  =  MESSAGEBOX( "开始搜索? ",  32+4,  "搜索指定数据 ")  &&产生信息框
IF  (.NOT.(nAnswer=6))  &&  如按下“Yes "按钮,则开始搜索,反之退出
EXIT
ENDIF
.Sheets( "查询 ").Select  &&  选择“查询”工作表单
SLesson  =  OleApp.Application.Range( "课程名 ").value  &&  得到欲查询的课程名称
.Sheets.Add  &&  新建一工作表单
.ActiveSheet.Name  =  Slesson  &&  指定工作表单的名称
SCommand  =  "SELECT  学号,语文,数学  FROM  d:\vfp\学生成绩表  WHERE  "  +ALLTrim(SLesson)  +  " <60  INTO 
CURSOR  TEMP "  &&  形成VFP查询命令串
&Scommand  &&  执行VFP命令串
_VFP.DataToClip( "TEMP ",,3)  &&  将搜索结果以文本方式拷贝至剪切板
.Range( "a1:a1 ").Select  &&  指向拷贝目标区域左上角单元
.ActiveSheet.Paste  &&  粘贴搜索结果
ENDWITH
ENDDO
OleApp.Quit  &&  关闭EXCEL,保存更新后的工作簿文件

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。