540 likes | 724 Views
Visual FoxPro 程序设计教程. 第 9 章. 菜单与工具栏. 9.1 设计菜单. 9.2 创建自定义工具栏. 9.1 设计菜单. 无论是定制已有的 VFP 系统菜单,还是开发一个全新的自定义菜单,创建一个完整的菜单系统都需要以下步骤: (1) 规划系统:确定需要哪些菜单、出现在界面的何处以及哪几个菜单要有子菜单等等。 (2) 创建菜单和子菜单。 (3) 为菜单系统指定任务:指定菜单所要执行的任务,例如显示表单或对话框等。另外,如果需要,还可以包含初始化代码和清理代码。 (4) 选择“预览”按钮预览整个菜单系统。
E N D
第 9 章 菜单与工具栏 9.1 设计菜单 9.2 创建自定义工具栏
9.1 设计菜单 无论是定制已有的VFP系统菜单,还是开发一个全新的自定义菜单,创建一个完整的菜单系统都需要以下步骤: (1) 规划系统:确定需要哪些菜单、出现在界面的何处以及哪几个菜单要有子菜单等等。 (2) 创建菜单和子菜单。 (3) 为菜单系统指定任务:指定菜单所要执行的任务,例如显示表单或对话框等。另外,如果需要,还可以包含初始化代码和清理代码。 (4) 选择“预览”按钮预览整个菜单系统。 (5) 从“菜单”菜单上选择“生成”命令,生成菜单程序。 (6) 运行生成的程序,测试菜单系统。 教学进程
1 在顶层表单中添加菜单 若要在顶层表单中添加菜单,可以按以下步骤操作: ① 创建顶层表单的菜单。即在“常规选项”对话框中,用鼠标选中“顶层表单”复选框。 ② 将表单的ShowWindow属性设置为“2 – 作为顶层表单”。 ③ 在表单的Init事件中,运行菜单程序并传递两个参数: DO menuname.mpr WITH oForm, lAutoRename 其中,oForm是表单的对象引用。在表单的Init事件中,THIS 作为第一个参数进行传递。 IAutoRename指定了是否为菜单取一个新的唯一的名字。如果计划运行表单的多个实例,则将.T.传递给lAutoRename。 例如,可以使用下列代码给调用名为mySDImenu的菜单: DO mySDImenu.mpr WITH THIS, .T. 教学进程
2 自定义菜单的设计 创建一个自定义菜单 ● 【例9-1】在例4-16中使用菜单来改变标题板中文本的字体与风格。如图9-8所示。 图9-8 改变标题板中文本的字体与风格 教学进程
设计步骤如下: (1) 设计菜单。 ① 规划菜单系统。 ② 创建菜单和子菜单。 在菜单设计器中输入菜单名:“文本字体(\<Z)”和“文本风格(\<F)”,如图9-9所示。 图9-9 输入菜单名
单击“创建”按钮,分别输入子菜单项名(图9-10、图9-11)。单击“创建”按钮,分别输入子菜单项名(图9-10、图9-11)。 图9-10 文本字体子菜单 图9-11 文本风格子菜单
③ 编写菜单代码。 在“菜单级”下拉列表框中选择“菜单栏”,回到顶层菜单。选择“文本字体”,用鼠标单击其右边“编辑”按钮,重新进入“文本字体Z”的编辑对话框。在主菜单中选择“显示”中的“菜单选项”,打开菜单选项对话框(图9-4),单击“编辑…”按钮,然后单击“确定”按钮,打开编辑器,为“文本字体Z”编写通用过程: DO CASE CASE BAR() = 1 && 函数BAR()返回最近一次选择的菜单项的编号 a = "宋体" CASE BAR() = 2 a = "黑体" CASE BAR() = 3 a = "楷体_GB2312" CASE BAR() = 4 a = "隶书" ENDCASE _VFP.ActiveForm.Container1.Label1.FontName = a 教学进程
在“菜单级”下拉列表框中选择“菜单栏”,回到图9-9。再用鼠标单击“文本风格”子菜单的“编辑”按钮,进入“文本风格F”的编辑对话框。分别选中各菜单项的“创建”按钮,为其创建过程代码。在“菜单级”下拉列表框中选择“菜单栏”,回到图9-9。再用鼠标单击“文本风格”子菜单的“编辑”按钮,进入“文本风格F”的编辑对话框。分别选中各菜单项的“创建”按钮,为其创建过程代码。 “粗体”菜单项: L = NOT _VFP.ActiveForm.Container1.Label1.FontBold SET MARK OF BAR 1 OF "文本风格F" L&& 为第1个菜单选项设置或清除标记符号 _VFP.ActiveForm.Container1.Label1.FontBold = L “斜体”菜单项: L = NOT _VFP.ActiveForm.Container1.Label1.FontItalic SET MARK OF BAR 2 OF "文本风格F" L && 为第2个菜单选项设置或清除标记符号 _VFP.ActiveForm.Container1.Label1.FontItalic = L “下划线”菜单项: L = NOT _VFP.ActiveForm.Container1.Label1.FontUnderline SET MARK OF BAR 3 OF "文本风格F" L && 为第3个菜单选项设置或清除标记符号 教学进程
④ 生成菜单码。 (2) 修改表单。 修改表单的ShowWindow属性为2 - 作为顶层表单 编写表单的Init事件代码: DO menu1.mpr WITH THIS, .T. (3) 运行表单。 教学进程
● 2. 在自定义菜单中使用系统菜单项 【例9-2】在例3-6的文本编辑器中使用菜单代替命令按钮,并且使用系统菜单项设计“编辑”子菜单,使之具有更加强大的功能(如图9-12) 图9-12 “编辑”菜单中的系统菜单项 教学进程
设计步骤如下: (1) 设计菜单。 ① 规划菜单系统。 ② 创建菜单和子菜单。 ③ 编写菜单代码。 用鼠标单击“编辑…”按钮,然后单击“确定”,打开编辑器,为菜单栏编写如下两个通用过程: PROCEDURE Save0 && 文件另存 cfile = PUTFILE("") IF cfile != "" nhandle = FCREATE(cfile,0) cc = FWRITE(nhandle,_VFP.ActiveForm.Edit1.Value) = FCLOSE(nhandle) IF cc < 0 = MESSAGEBOX('文件不能保存') ELSE _VFP.ActiveForm.Caption = cfile _VFP.ActiveForm.Tag = '' ENDIF ENDIF 教学进程
PROCEDURE Save && 保存文件 cFile = _VFP.ActiveForm.Caption IF cfile == "未命名" DO Save0 ELSE nhandle = FOPEN(cfile,1) = FWRITE(nhandle,_VFP.ActiveForm.Edit1.Value) _VFP.ActiveForm.Tag = '' = FCLOSE(nhandle) ENDIF 教学进程
用鼠标单击“编辑…”按钮,然后单击“确定”,打开编辑器,为“文件”菜单编写如下通用过程:用鼠标单击“编辑…”按钮,然后单击“确定”,打开编辑器,为“文件”菜单编写如下通用过程: DO CASE CASE BAR() = 1 IF _VFP.ActiveForm.Tag = "T" A = MESSAGEBOX("是否保存编辑过的文件",4+48,"信息窗口") IF A = 6 DO Save ENDIF ENDIF _VFP.ActiveForm.Edit1.Value = "" _VFP.ActiveForm.Caption = "未命名" 教学进程
CASE BAR() = 2 IF _VFP.ActiveForm.Tag = 'T' A = MESSAGEBOX("是否保存编辑过的文件",4+48,"信息窗口") IF A = 6 DO Save ENDIF ENDIF cfile = GETFILE("") IF cfile != "" nhandle = FOPEN(cfile) nend = FSEEK(nhandle,0,2) IF nend <= 0 = MESSAGEBOX('文件是空的') 教学进程
ELSE = FSEEK(nhandle,0,0) _VFP.ActiveForm.Edit1.Value = FREAD(nhandle,nend) _VFP.ActiveForm.Caption = cfile = FCLOSE(nhandle) ENDIF ENDIF CASE BAR() = 3 DO Save CASE BAR() = 4 DO Save0 ENDCASE _VFP.ActiveForm.Refresh _VFP.ActiveForm.Edit1.SetFocus 关闭编辑器,返回菜单设计器。在“退出”选项的右边填入命令: _VFP.ActiveForm.Release ④ 生成菜单码。 教学进程
(2) 设计表单。 ① 建立应用程序用户界面。 ② 设置对象属性。 ③ 编写程序代码。 ●编写表单的事件代码: Resize事件: WITH THIS.Edit1 .Top = 0 .Left = 0 .Height = THIS.Height .Width = THIS.Width ENDWITH Init事件: SET EXACT ON DO menu1.mpr WITH THIS, .T. ●编写编辑框Edit1的InteractiveChange事件代码: THISFORM.Tag = 'T' 教学进程
3 在MDI表单中使用菜单 【例9-3】设计一个简易的多文本编辑器。 设计步骤如下: (1) 设计菜单。 ① 菜单界面。 ② 菜单代码。 为“文件”菜单编写通用过程代码: DO CASE CASE BAR() = 1 && 新建 &fform..new && 运行主表单中的自定义方法:new CASE BAR() = 2 && 打开 &fform..open && 运行主表单中的自定义方法:open CASE BAR() = 5 && 保存 _VFP.ActiveForm.save && 运行子表单中的自定义方法:save CASE BAR() = 6 && 另存 _VFP.ActiveForm.save0 && 运行子表单中的自定义方法:save0 ENDCASE _VFP.ActiveForm.Refresh _VFP.ActiveForm.Edit1.SetFocus 教学进程
再为“退出”选项编写过程代码: mes = MESSAGEBOX("是否放弃编辑过的文件,退出本程序?",1+48,"信息窗口") IF mes = 1 RELEASE mychild RELEASE POPUP RELEASE MENUS &fform..Release ENDIF ③ 生成菜单码。 教学进程
(2) 设计主表单。 ① 表单界面。 ② 编写主表单的事件代码。 Init事件代码: PUBLIC fn fn = 1 PUBLIC fform fform = "表单1" DO menu1.mpr WITH THIS, .T. Activate事件代码: SET EXACT ON DO FORM mychild NAME THISFORM.aforms(1) THISFORM.aforms(1).Caption = "未命名" 教学进程
QueryUnload事件代码: q = MESSAGEBOX("是否在退出之前关闭文件?",32+3,_VFP.ActiveForm.Caption) DO CASE CASE q = 6 _VFP.ActiveForm.Release NODEFAULT CASE q = 7 flag = 0 THIS.Release OTHERWISE NODEFAULT ENDCASE Destroy事件代码: SET SYSMENU TO DEFAULT 教学进程
自定义的new方法代码: fn = fn+1 DIME THIS.aForms[fn] AINS(THIS.aForms,1) DO FORM mychild NAME THIS.aForms[1] LINKED THIS.aForms[1].Caption = "未命名" THIS.aForms[1].Edit1.Value = "" 自定义open方法代码: cfile = GETFILE("") nhandle = FOPEN(cfile) IF cfile != "" nend = FSEEK(nhandle,0,2) IF nend <= 0 = MESSAGEBOX('文件是空的') ELSE 教学进程
fn = fn + 1 DIME THIS.aForms[fn] AINS(THIS.aForms,1) DO FORM mychild NAME THIS.aForms[1] LINKED = FSEEK(nhandle,0,0) THIS.aForms[1].Edit1.Value = FREAD(nhandle,nend) THIS.aForms[1].Caption = cfile = FCLOSE(nhandle) ENDIF ENDIF ③ 以表单1.scx为文件名保存主表单。 教学进程
(3) 设计子表单。 ① 表单界面。 ② 编写代码。 表单的Activate事件代码: WITH this .Top = 0 .Left = 0 .Height = &Fform..Height – 32 .Width = &Fform..Width – 8 ENDWITH 表单的ReSize事件代码: WITH THIS.Edit1 .Top = 0 .Left = 0 .Height = THIS.Height .Width = THIS.Width ENDWITH 教学进程
表单的自定义Save方法代码: cFile = THIS.Caption IF cfile == "未命名" THIS.save0 ELSE nhandle = FOPEN(cfile,1) = FPUT(nhandle,THIS.Edit1.Value,len(THIS.Edit1.Value)) = FCLOSE(nhandle) ENDIF
表单的Save0方法代码: cfile = PUTFILE("") IF cfile != "" nhandle = FCREATE(cfile,0) cc = FWRITE(nhandle,THIS.Edit1.Value) = FCLOSE(nhandle) IF cc < 0 = MESSAGEBOX('文件不能保存') ELSE THIS.Caption = cfile ENDIF ENDIF ③ 以mychild.scx为文件名保存子表单。
9.2 创建自定义工具栏 1 创建自定义工具栏的3种方法 创建一个自定义工具栏有三种方法: ●利用“容器”控件创建一个工具栏。 ●利用与VFP一起发布的ActiveX控件。 ●利用Visual FoxPro提供的工具栏基类,创建一个自 定义工具栏的类,然后将其添加到表单集中。 教学进程
2 使用容器控件制作的工具栏 【例9-4】利用容器控件设计一个工具栏,可以随时改变电子标题板的文本字体、风格、前景色和背景色(如图9-24、9.25所示)。 图9-24 利用工具栏改变字体与颜色 教学进程
在例4-16的基础上进行设计,设计步骤如下: (1) 修改程序界面。 进入表单设计器后,在原有的基础上增加一个容器控件Container1,将其SpecialEffect属性改为:1 – 凹下。用鼠标右键单击容器控件,在弹出菜单中选择“编辑”,然后在容器中添加两个组合框和三个复选框。如图9-26所示。 图9-25 利用工具栏改变颜色的设置 图9-26 修改程序界面 教学进程
(2) 设置容器中对象的属性。 (3) 增加程序代码。 ●编写容器中下拉列表框Combo1的事件代码: Init事件: DIMENSION x[1] = afont(x) FOR i = 1 TO ALEN(x) THIS.AddItem(x[i]) ENDFOR THIS.DisplayValue='宋体' InteractiveChange事件: THISFORM.Container1.Label1.FontName = THIS.DisplayValue
●编写容器中下拉列表框Combo2的事件代码: Init事件: THIS.AddItem("颜色") THIS.AddItem("设置前景色...") THIS.AddItem("设置背景色...") THIS.ListIndex = 1 InteractiveChange事件: DO CASE CASE THIS.Value = 1 RETURN CASE THIS.Value = 2 && 设置前景色 nForeColor = GETCOLOR() IF nForeColor > –1 THISFORM.SetAll('ForeColor', nForeColor, 'label') ENDIF CASE THIS.Value = 3 && 设置背景色 教学进程
nBackColor = GETCOLOR() IF nBackColor > –1 THISFORM.SetAll('BackColor', nBackColor, 'Container') ENDIF ENDCASE THIS.Value = 1 ●编写容器中复选框Check1的Click事件代码: THISFORM.Container1.Label1.FontBold = THIS.Value ●编写容器中复选框Check2的Click事件代码: THISFORM.Container1.Label1.FontItalic = THIS.Value ●编写容器中复选框Check3的Click事件代码: THISFORM.Container1.Label1.FontUnderLine = THIS.Value
3 使用ActiveX控件制作的工具栏 1. 添加ActiveX控件 ImageList控件与ToolBar控件是与VFP一起发布的ActiveX控件,专门用来创建工具栏。在使用ImageList控件与ToolBar控件之前,必须首先将其添加到“表单控件”工具栏中。具体步骤如下: (1) 用鼠标单击“工具”中的“选项”菜单,打开“选项”对话框。在“控件”选项卡中用鼠标选择: Microsoft ImageList Control, version 6.0 Microsoft ToolBar Control, version 6.0 如图9-27,然后按“确定”退出“选项”对话框。 (2) 在“表单控件”工具栏中选择“查看类”,在弹出菜单中选择“ActiveX控件”(图9-28)。 即可将ImageList和ToolBar控件添加到“表单控件”工具栏中。 教学进程
图9-28 选择“ActiveX控件” 图9-27 添加ActiveX控件 教学进程
2. 创建具有Office97风格的工具栏 【例9-5】在文本编辑器中使用ActiveX控件制作工具栏,使之具有Office97的风格(如图9-29)。 图9-29 使用ActiveX控件制作的工具栏 教学进程
在例9-2的基础上进行修改,具体设计步骤如下:在例9-2的基础上进行修改,具体设计步骤如下: (1) 对表单的改进。 ① 表单界面。在表单上依次增加“ImageList控件”Olecontrol1和“ToolBar控件”Olecontrol2,并将Olecontrol2的Style属性改为:1 – Transparent。如图9-30所示。 图9-30 增加“ImageList控件”和“ToolBar控件”
② 设置ImageList控件的属性。 ③ 设置ToolBar控件的属性。 ④ 修改表单代码。首先在系统菜单中选择“表单”中的“新建方法程序”,为表单添加4个自定义方法:new()、open()、save()、Save0(),然后分别编写事件或方法代码。 修改表单的Init事件代码: SET EXACT ON THIS.Caption = "未命名" DO menu1.mpr WITH THIS, .T. 修改表单的Resize事件代码: WITH THIS.Edit1 .Top = THIS.Olecontrol2.Height .Left = 0 .Height = THIS.Height-.Top .Width = THIS.Width ENDWITH
●编写自定义的new方法: IF THIS.Tag = "T" A = MESSAGEBOX("是否保存编辑过的文件",4+48,"信息窗口") IF A = 6 THIS.Save ENDIF ENDIF THIS.Edit1.Value = "" THIS.Caption = “未命名” ●编写自定义的open方法: IF THIS.Tag = 'T' A = MESSAGEBOX("是否保存编辑过的文件",4+48,"信息窗口") IF A = 6 THIS.Save ENDIF ENDIF 教学进程
cfile = GETFILE("") IF cfile != "" nhandle = FOPEN(cfile) nend = FSEEK(nhandle,0,2) IF nend <= 0 = MESSAGEBOX('文件是空的') ELSE = FSEEK(nhandle,0,0) THIS.Edit1.Value = FREAD(nhandle,nend) THIS.Caption = cfile = FCLOSE(nhandle) ENDIF ENDIF 教学进程
●编写自定义的save方法: cFile = THIS.Caption IF cfile == "未命名" THIS.Save0 ELSE nhandle = FOPEN(cfile,1) = FWRITE(nhandle,THIS.Edit1.Value) THIS.Tag = "" = FCLOSE(nhandle) ENDIF 教学进程
●编写自定义的save方法: cFile = THIS.Caption IF cfile == "未命名" THIS.Save0 ELSE nhandle = FOPEN(cfile,1) = FWRITE(nhandle,THIS.Edit1.Value) THIS.Tag = "" = FCLOSE(nhandle) ENDIF
●编写自定义的Save0(文件另存)方法: cfile = PUTFILE("") IF cfile != "" nhandle = FCREATE(cfile,0) cc =FWRITE(nhandle,THIS.Edit1.Value) = FCLOSE(nhandle) IF cc<0 = MESSAGEBOX('文件不能保存') ELSE THIS.Caption = cfile THIS.Tag = "" ENDIF ENDIF ●编写编辑框Edit1的InteractiveChange事件代码: THISFORM.Tag='T'
⑤ 编写工具栏控件OleControl2的代码: Init事件代码: WITH THIS .Imagelist = THISFORM.OleControl1 && 连接ImageList控件 .Buttons(1).Image = 1 && 设置按钮的图标 .Buttons(2).Image = 2 .Buttons(3).Image = 3 .Buttons(5).Image = 4 .Buttons(6).Image = 5 .Buttons(7).Image = 6 .Buttons(9).Image = 7 .Buttons(10).Image = 8 endwith ButtonClick事件代码: LPARAMETERS button DO CASE CASE button.Index = 1 THISFORM.new
CASE button.Index = 2 THISFORM.open CASE button.Index = 3 THISFORM.save CASE button.Index = 5 SYS(1500, '_MED_cut', '_MEDIT') CASE button.Index = 6 SYS(1500, '_MED_copy', '_MEDIT') CASE button.Index = 7 SYS(1500, '_MED_paste', '_MEDIT') CASE button.Index = 9 SYS(1500, '_MED_undo', '_MEDIT') CASE button.Index = 10 SYS(1500, '_med_redo', '_MEDIT') ENDCASE 说明:函数SYS(1500)用来激活一个VFP系统菜单项。其使用的语法格式为: SYS(1500,〈系统菜单项名〉,〈菜单名〉)
(2) 对菜单的修改。 各菜单选项的名称保持不变,只需修改菜单代码。首先删除“菜单栏”的通用过程,修改“文件”子菜单的通用过程: DO CASE CASE BAR() = 1 _VFP.ActiveForm.Parent.new CASE BAR() = 2 _VFP.ActiveForm.Parent.open CASE BAR() = 3 _VFP.ActiveForm.Parent.save CASE BAR() = 4 _VFP.ActiveForm.Parent.Save0 ENDCASE _VFP.ActiveForm.Refresh _VFP.ActiveForm.Parent.Edit1.SetFocus 然后编写“文件”子菜单中“退出”菜单项的命令: _VFP.ActiveForm.Parent.release
4 使用VFP的工具栏控件 【例9-6】在例9-3中的多文本编辑器中使用工具栏(图9-33)。 图9-33 在多文本编辑器中使用工具栏 设计步骤如下: (1) 创建自定义工具栏类。 ① 在系统菜单中选择“文件”中的“新建”,或在系统工具栏中选择“新建”按钮。打开“新建”对话框。
②用鼠标选择“文件类型”中的“类”,并单击“新建文件”按钮,打开“新建类”对话框。 ③ 在“类名”框中,键入新类的名称sditb1 ④从“派生于”框中,选择“toolbar”,以使用工具栏基类。或者单击三点按钮,选择其他工具栏类。 ⑤ 在“存储于”框中,键入类库名sditbar,保存创建的新类。或者单击三点按钮选择一个已有的类库。如图9-34所示。 单击“确定”按钮,关闭对话框,并打开“类设计器”窗口,如图9-35所示。 图9-34 “新建类”对话框 图9-35 “类设计器”
“类设计器”不仅形式与“表单设计器”相似,其各种操作也是相似的。“类设计器”不仅形式与“表单设计器”相似,其各种操作也是相似的。 ⑥ 在新建的工具栏类中添加六个命令按钮Command1~Command6和一个分隔符控件Separator1。 其中分隔符应加在第三和第四个按钮之间。 修改命令按钮的Picture属性,如图9-36所示。 图9-36 设计“工具栏类” ⑦为新建的工具栏类添加一个自定义属性:oFormRef。
⑧编写事件代码。 工具栏的Init事件代码: PARAMETER oForm THIS.oFormRef = oForm 工具栏的AfterDock事件代码: WITH _VFP.ActiveForm .Top = 0 .Left = 0 .Height = THISFORM.oformref.Height – 32 .Width = THISFORM.oformref.Width – 8 ENDWITH ●命令按钮Command1的Click事件代码: THISFORM.oformref.new ●命令按钮Command2的Click事件代码: THISFORM.oformref.open
●命令按钮Command3的Click事件代码: _VFP.ActiveForm.save ●命令按钮Command4的Click事件代码: SYS(1500,"_med_cut","_medit") ●命令按钮Command5的Click事件代码: SYS(1500,"_med_copy","_medit") ●命令按钮Command6的Click事件代码: SYS(1500,"_med_paste","_medit") 自定义工具栏类完成后,将保存为类文件sditbar.vcx。