VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - VB问题全功略(3)
发表评论(0)作者:不详, 平台:VB6.0+Win98, 阅读:11131, 日期:2002-01-26
VB问题全功略(3)

11、如何让用户自行输入方程式,并计算其结果?
12、如何解决VB中的Grid控件的打印问题
13、如何在VB中实现绘图区的大十字光标
14、如何充分扩充VB功能
15、成组更新控件属性
11、如何让用户自行输入方程式,并计算其结果?

假设我们要让使用者在“方程式”栏位中自由输入方程式,然后利用方程式进行计算,则引用ScriptControl控件可以很方便地做到。
( ScriptControl 控件附属于VB 6.0,如果安装后没有看到此一控件,可在光盘的 \Common\Tools\VB\Script 目录底下找此一控件, 其.文件名为Msscript.ocx。) 假设放在窗体上的ScriptControl控件名称为ScriptControl1,则在“计算”按钮的Click事件中编写如下代码: Dim Statement As String Statement = "X=" + Text1.Text + vbCrLf + _ "Y=" + Text2.Text + vbCrLf + _ "MsgBox ""计算结果="" & Y " ScriptControl1.ExecuteStatement( Statement )

12、如何解决VB中的Grid控件的打印问题

---- Grid 控 件 是Visual Basic 最 常 见 控 件 之 一, 从VB3.0 到VB5.0 都有 该 控 件。 也 是VB 爱 好 者 最 喜 爱 的 工 具 之 一。 用 它 可 以 以表 格 的 形 式 显 示、 浏 览 数 据, 特 别 是 数 据 库 应 用, 直 接 绑定 即 可 显 示 浏 览 数 据 库 信 息。 然 而, 美 中 不 足 的 是Grid 没有 编 辑 和 打 印 功 能, 列 与 列 的 位 置 不 能 相 互 交 换。 笔 者 曾尝 试 着 给Grid 增 添 了 这 些 功 能, 使 之 锦 上 添 花, 功 能 更 强大。 下 面 给 出 改 进 方 法 及 源 程 序, 读 者 只 需 按 步 骤 写 下 源程 序 即 可 使 你 的Grid 具 有 打 印 功 能。 该 程 序 笔 者 在HP5/100Window 95 环 境 下 用VB5.0 调 试 通 过。

---- 给Grid 控 件 增 加 打 印 方 法 有 三 种:1 是 直 接 打 印 控 件 的方 法,2 是 过 printer 来 实 现 打 印 功 能,3 是 通 过 调 用MS-WORD 及MS-EXCEl 来 实 现 打 印。
---- 首 先, 打 开 一 个 应 用, 在FORM1 中 增 加DATA 控 件DATA1, 把DATA1 的CONNECT 属 性 设 为dBASE III, 再 把DATABASENAME 属 性 设 为D:\PJXM.DBF。 然 后 再 在FORM1 中 增 加MSFLEXGRID 空 间GRID1, 并 把GRID1的DATASOURCE 属 性 设 为DATA1。 这 样 数 据 库PJXM.DBF 的 信 息 就 会 在GRID1 中 显 示 出 来。

---- 方 法 一: 直 接 打 印 窗 体 法, 在FORM1 中 增 加 命 令 按 钮(command),CAPTION 属 性 设 为 直 接 打 印, 再 写 入 下 列 编 码:

Sub command_click
Form1.printform
End sub

---- 这 样 即 可 通 过 打 印 窗 体FORM1 的 方 法 把GRID1 的 数 据 打 印出 来, 遗 憾 的 是 只 能 打 印GRID1 中 显 示 的 数 据 部 分, 显 示 不出 来 的 则 无 法 打 印, 而 且 这 种 打 印 方 法 很 象 屏 幕 硬 拷 贝把 其 他 控 件 也 打 印 出 来。 也 不 能 灵 活 的 控 制 字 体 等。

---- 方 法 二: 通 过PRINTER 实 现 打 印。 这 种 方 法

---- 1、 加 入 打 印 命 令 按 钮(command1)、 函 数(prnt1) 即 可 实 现 打印 功 能, 写 入 下 面 代 码, 读 者 稍 加 改 动 可 写 成 标 准 的 函 数或 过 程。

Function prnt1 (x As Integer, y As Integer,
font As Single, txt As String)
printer.CurrentX = x
printer.CurrentY = y
printer.FontBold = False
printer.FontSize = font
printer.Print txt
End Function

Sub command1_click
Dim fnt As Single
Dim pp as integer
Pp=0注释:设置开始页码0
Dim stry,strx,strx1,stry1,linw,page1,p As Integer
Static a(8) As Integer注释:定义打印的列数
ss$ = "内部结算存入款对帐单"注释:定义表头
kan = 0
For i = 0 To 8
a(i) = 1500注释:定义每列宽
kan = kan + a(i)注释:计算表格总宽度
Next

page1 = 50注释:定义每页行数
strx = 200
strx1 = 200注释:定义X方向起始位置
stry = 1400
stry1 = 1400注释:定义Y方向起始位置
linw = 240注释:定义行宽
fnt = 8注释:定义字体大小
printer.fontname = "宋体"注释:定义字体

dd = prnt1(4000, 700, 18, ss$)注释:打印标题
printer.Line (strx - 50, stry - 30)
-(strx + kan - 10, stry - 30)
For j = 0 To gridrow - 1注释:gridrow为所要打印的行数
grid1.row = j
strx = strx1
printer.Line (strx - 50, stry - 30)
-(strx + kan - 10, stry - 30)
p = p + 1
For i = 0 To 8
grid1.col = i
dd = prnt1(strx, stry, fnt, grid1.text)
strx = strx + a(i)
Next

If p > page1 Then注释:next page
p = 0
strx = strx1
注释:line last line
printer.Line (strx - 50, stry + linw)
-(strx + kan - 10, stry + linw)
stry = stry1
注释:line col
For n = 0 To 8
printer.Line (strx - 30, stry - 30)
-(strx - 30, stry + (page1 + 2) * linw)
strx = strx + a(n)
Next
printer.Line (strx - 30, stry - 30)
-(strx - 30, stry + (page1 + 2) * linw)
pp=pp+1
foot$="第 "+cstr(pp)+"页"
dd = prnt1(strx - 30-1000, stry + (page1 + 2)
* linw+100, 10, foot$)注释:打印页角码

printer.NewPage注释:next page
dd = prnt1(4000, 700, 18, ss$) 注释:打印标题
strx = strx1
stry = stry1
printer.Line (strx - 50, stry - 30)-
(strx + kan - 10, stry - 30)注释: print first row
Else
stry = stry + linw
End If
Next
st = stry
If p < page1 Then 注释:在最后页剩余划空行
For o = p To page1 + 1
strx = strx1
printer.Line (strx - 50, stry - 30)
-(strx + kan - 10, stry - 30)
stry = stry + linw
Next
End If
stry = stry1
strx = strx1
stry = stry1 注释:line col
For n = 0 To 8
printer.Line (strx - 30, stry - 30)-
(strx - 30, stry + (page1 + 2) * linw)
strx = strx + a(n)
Next
printer.Line (strx - 30, stry - 30)-
(strx - 30, stry + (page1 + 2) * linw)
pp=pp+1
foot$="第 "+cstr(pp)+"页"
dd = prnt1(strx - 30-1000, stry + (page1 + 2)
* linw+100, 10, foot$)注释:打印页角码

printer.EndDoc注释:打印结束
Endsub

---- 这 种 方 法 通 过 灵 活 的 编 程 可 以 方 便 地 调 整 字 体、 字 型、线 形、 页 面、 纸 张 大 小 等。 可 打 印 出 比 较 满 意 的 效 果。 如果 你 的 计 算 机 上 装 有MICROSOFT WORD 和MICRO EXCEL, 最 精 彩 的 用法 还 是 把GRID 的 表 格 通 过VB 发 送 到MICROSOFT WORD 及MICRO EXCEL。生 成MICROSOFT WORD 和MICRO EXCEL 表 格。 这 样 就 可 以 充 分 利 用MICROSOFT WORD 和MICRO EXCEL 的 打 印、 编 辑 功 能 打 印 出 更 理 想 的效 果。 下 面 逐 一 介 绍。

---- 方 法 三: 通 过 生 成MICROSOFT WORD 表 格 打 印

---- 1、 在declaration 中 写 入:

Dim msword As Object

---- 2、 加 入 打 印 命 令 按 钮(command2),CAPTION 设 为" 生 成WORD 表
格", 写 入 下 面 代 码,

Private Sub command2_Click()

screen.MousePointer = 11
Set msword = CreateObject("word.basic")

Dim AppID, ReturnValue
appID = Shell("d:\office97\office\WINWORD.EXE", 1)
注释: Run Microsoft Word.

msword.AppActivate "Microsoft Word"
注释:msword.AppActivate "Microsoft Word", 1
full
Screen.MousePointer = 0
End Sub

---- 2、 写 入 以 下 过 程full()

Sub full()
Dim i As Integer, j As Integer,
col As Integer, row As Integer
Dim cellcontent As String
Me.Hide
cols = 4注释:表格的列数
row = gridrow注释:打印表的行数
msword.filenewdefault
msword.MsgBox "正在建立MS_WORD报表,
请稍候.......", "", -1
msword.leftpara
msword.screenupdating 0
msword.tableinserttable , col, row, , , 16, 167
msword.startofdocument
for j=0 to gridrow注释: 表格的行数
grid1.row=j
For i = 1 To cols
Gri1d.col=i
If IsNull(grid1.text) Then
cellcontent$ = ""
Else
cellcontent$ = grid1.text
End If
msword.Insert cellcontent$
msword.nextcell
Next i
Next j
msword.tabledeleterow
msword.startofdocument
msword.tableselectrow
msword.tableheadings 1
msword.centerpara
注释:msword.startdocument
msword.screenrefresh
msword.screenupdating 1
msword.MsgBox " 结束", "", -1
Me.Show

End Sub

---- 方 法 四: 通 过 发 送 到MICROSOFT EXCEL 实 现 表 格 打 印

---- 1、 加 入 打 印 命 令 按 钮(command3),CAPTION 设 为" 生 成EXCEL 表
格", 写 入 下 面 代 码

Private Sub command3_Click()
Dim i As Integer
Dim j As Integer
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
Dim xlSheet As Excel.Worksheet

Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
注释:Set xlBook = xlApp.Workbooks.Add
注释:On Error Resume Next
Set xlBook = xlApp.Workbooks.Add 注释:Open("d:\text2.xls")
Set xlSheet = xlBook.Worksheets(1)
xlSheet.Cells(6, 1) = "i"
For i = 0 To gridrow
grid1.Row = i
For j = 0 To 6
Grid1.Col = j

If IsNull(Grid1.Text) = False Then
xlSheet.Cells(i + 5, j + 1) = Grid1.Text
End If
Next j
Next i
Exit Sub

13、如何在VB中实现绘图区的大十字光标

有时,我们需要用VB快速开发一个试验数据绘图处理程序,将绘图控件内的鼠标光标改变成与AutoCAD软件中使用的大十字光标的形式,将可以比普通的箭头光标达到更好的效果。那么我们如何实现这样的大十字光标呢?
---- 首先,我们明确一下要达到的效果,假若我们在一个Picture控件中绘图,那么,鼠标移动到这个控件上时,鼠标光标立即改变为大十字形状,光标中的横线从控件的左边界到右边界,竖线从控件的上边界到下边界,即大十字光标将绘图控件分割为四个象限。当鼠标移动到控件外时,光标则又恢复成原来的形式。

---- 要实现这样的光标,得我们自己通过画线的方式实现。如鼠标在绘图控件内,先在鼠标的当前位置画上光标的横线和竖线;当鼠标位置移动,先擦除原先的光标横线和竖线,然后再在新的位置画光标的横线和竖线,那么我们就要响应绘图控件的MouseMove事件。当然,绘图控件内无论有什么内容,我们擦除光标线和重画光标线时都不能破坏原先的内容,因此我们要将绘图控件的DrawMode设置为vbXorPen(异或方式),绘制光标的横线和竖线时,用异或的方式将横线和竖线的象素点颜色设为光标的颜色和原先的象素点色彩的异或值,再用异或的方式在同样的位置绘制一遍竖线和横线,横线和竖线上的象素点再一次和光标颜色进行异或操作,就擦除了光标的横线和竖线,且又恢复了绘图控件内原先的内容。

---- 我们还得保证鼠标移动到绘图控件内时,普通的鼠标光标消失,只有绘制的大十字光标出现,因此还应该设置绘图控件的MousePointer属性为vbCuntom,即用户自定义。绘图控件的MousePointer属性设置为vbCustom后,其MouseIcon属性中应装入相应的用户自定义图形,因为我们希望绘图控件内只有我们绘制的光标,而没有其它的光标,故应该装入一个空的(透明的)光标图形。可以任找一个光标文件,通过任意一个资源编辑器对其进行编辑,用透明的方式填充整个光标图形,保存成我们所需的NoIcon.cur即可。

---- 通过以上的关键设置和操作,我们就可以实现大十字光标了。利用异或方式进行绘图,我们还可以实现一般绘图软件中常有的“橡皮筋”效果,即用鼠标定义一个点后,动态拖动鼠标来定义另外一个点,动态拖动鼠标过程中,所要绘的图形也动态相应变化。

---- 以下我们通过一个示例来完整实现绘图控件中的大十字光标,还演示如何实现用“橡皮筋”效果来画矩形:

---- 在VB中新建一个标准EXE工程,在Form1中加入一个Picture控件,其Name设为PicDraw,可以装入一个图象文件,PicDraw的大小和其中的图象大小基本上覆盖大部分的Form1即可。实现代码如下所示。此程序在VB5.0中运行通过。

Option Explicit
Private Old_X As Single
Private Old_Y As Single
Private isMouseDown As Boolean
Private Box_X0 As Single
Private Box_Y0 As Single
Private Box_X1 As Single
Private Box_Y1 As Single
Private PenColor As Long
Private CrossColor As Long

Private Sub Form_Load()
    CrossColor = QBColor(8)
    PenColor = QBColor(15)
    picDraw.DrawMode = vbXorPen
picDraw.MouseIcon = LoadPicture
(App.Path & "\no.cur")
    picDraw.MousePointer = vbCustom
    isMouseDown = False
    Box_X0 = Box_X1 = Box_Y0 = Box_Y1 = 0
End Sub

Private Sub picDraw_MouseDown
(Button As Integer,
Shift As Integer, X As Single, Y As Single)
If isMouseDown = True Then   
注释:先前已经用鼠标定义了一个点
       Box_X1 = X
       Box_Y1 = Y
       isMouseDown = False
       picDraw.DrawMode = vbCopyPen
       picDraw.Line (Box_X0, Box_Y0)-
(Box_X1, Box_Y1),
PenColor, B
       picDraw.DrawMode = vbXorPen
       注释:画一个光标
   picDraw.Line (0, Y)-(picDraw.ScaleWidth, Y),
CrossColor
  picDraw.Line (X, 0)-(X, picDraw.ScaleHeight),
CrossColor
       Old_X = X
       Old_Y = Y
    Else
       注释:定义了一个矩形的第一个顶点,则擦除光标
       picDraw.Line (0, Y)-(picDraw.ScaleWidth, Y),
CrossColor
       picDraw.Line (X, 0)-(X, picDraw.ScaleHeight),
CrossColor
       Box_X0 = X
       Box_Y0 = Y
       isMouseDown = True
    End If
End Sub

Private Sub picDraw_MouseMove(Button As Integer,
Shift As Integer, X As Single, Y As Single)
    If isMouseDown = True Then
       注释:拖动鼠标来定义矩形的另外一个顶点,
此时擦除前一个矩形,绘制新的矩形
       picDraw.Line (Box_X0, Box_Y0)-(Old_X, Old_Y),
PenColor, B
       picDraw.Line (Box_X0, Box_Y0)-(X, Y), PenColor, B
    Else
       注释:消除旧光标线
       picDraw.Line (0, Old_Y)-(picDraw.ScaleWidth, Old_Y),
CrossColor
       picDraw.Line (Old_X, 0)-(Old_X, picDraw.ScaleHeight),
CrossColor
       注释:画新的光标线
       picDraw.Line (0, Y)-(picDraw.ScaleWidth, Y),
CrossColor
       picDraw.Line (X, 0)-(X, picDraw.ScaleHeight),
CrossColor
    End If
    Old_X = X
    Old_Y = Y
End Sub

14、如何充分扩充VB功能

Visual Basic for Windowss3.0(简称VB)是目前开发WINDOWS应用软件的最有效工具之一,它综合运用了BAIC语言和新的可视化设计工具,不仅功能强大,而且简单易学。其次,VB具有事件驱动的编程机制,它充分利用WINDOWS图形环境的特点,能让开发人员快速地构造强大的应用程序。
那么在开发VB应用软件时,如何充分地扩充VB的功能呢?这就要求在不同的层次上要很好地利用VB最具威力和特色的部分:
●在函数层调用动态链接库。
●在控件层使用VBX。●在应用层执行其他应用程序。
一、在函数层调用功能态链接库(DLL)
WINDOWS操作系统实际上是由许多功能强大的动态链接库(DLL)组合而成。VB考虑到有些工作超过自身语言所及的能力范围,所以提供了直接调用操作系统中这些DLL子程序的能力。例如:在正常情况下,窗口的控制菜单提供了七种功能:还原、移动、大小、最小化、最大化、关闭和切换。而在实际应用中,我们希望窗口按设计时的大小显示,不允许用户随意改变窗口大小,也不允许切换到其他窗口,这就要求在设计时必须删除控制菜单中除“移动”和“关闭”选项以外的所有控制菜单项。要完成这一任务,我们首先可把窗体的MaxButton属性和MinButton属性设置为False,不允许窗体最小化和最大化,窗体也就不能还原。然后再把窗体的BorderSstyle属性设置为1-Fixed Single或3-Fixed Double,不允许窗体改变大小。但VB本身却无法删除“切换”选项和两条分隔线。幸运的是,通过调用WINDOWS DLL就很容易做到。
通常,要使用WINDOWS DLL,首先必须说明要使用的DLL子程序,我们可在两个地方说明所使用的DLL子程序,即在全局模块中说明,或者在窗体层的说明部分中说明。其格式是:
Declare Sub子程序名Lib“库名”[Alias“别名”][([参数])]
Declare Function子程序名Lib“库名”[Aliass“别名”][([参数])][AS数据类型]
第一种格式表示过程没有返回值,第二种格式表示过程返回一个值,该值可用于表达式中,库名如果用的是WINDOWS操作环境(在System目录下)中的库,如“USER.EXE”,“KERNEL.EXE”或者“GDI.EXE”等,就用此名作为库名。如果用的是其他来源的DLL,则用包括路径的文件名称(如:“C:\WINDOWS\BRUSH.DLL”)。别名(Alias)是允许另外使用别的名称来称呼子程序,尤其是当外来子程序名与VB保留字相同时,它就显得特别有用,参数指要被传递到子程序的参数值,数据类型指的是函数返回值的数据类型,它可能是Integer,Long,Single,Double,Currency或String。下面就是所要使用的DLL子程序的说明:
Declare Function GetSystemMenu% Lib"User"(ByValhWnd%,ByValbRevert%)
Declare \function \RemoveMenu% Lib"User"(ByValhMenu%,ByValnPosition%,ByValwFlags%)
当说明完DLL子程序后,执行DLL子程序的方法,就象在VB中执行通用过程(函数)一样。下面我们编写一个名为Remove-Items-From-System的过程来完成上面例子中提到的功能,过程中调用了上述说明过的两个DLL子程序:
Sub remove-Items-From-Sysmenu(A-Form As Form)
注释:获取窗体系统菜单句炳
HSysMenu=GetSystemMenu(A-Form.hWnd,0)
注释:删除除“移动”和“关闭”外的所有菜单项, 删除时必须从最后一个菜单项开始
R=RemoveMenu(HSysMenu,8,MF-BYPOSITION) 注释:删除切换
R=RemoveMenu(HSysMenu,7,MF-BYPOSITION) 注释:删除第一条分隔线
R=RemoveMenu(HSysMenu,5,MF-BYPOSITION) 注释:删除第二条分隔线
End Sub
有了这个过程,在任一窗体的Form-Load事件中加入下面一行代码就可以删除该窗体除“移动”和“关闭”选项以外的所有控制菜单项:
Remove-Items-From-Sysmenu Me
二、在控件层使用VBX
VB功能强大的第二个部分是VBX的使用,即其开放及无限扩增的特性。虽然VB工具箱(ToolBox)已经尽量将设计应用软件所需的工具包括在内,但是,为了不断扩充VB的功能,VB提供了一套开发工具(Custom Control Development Kit)供第三方开发者来设计所需要的控件。当设计完控件文件后(其文件扩展名为“.VBX”)可以从菜单“file”项下选“Add File...”命令,结果画面上出现一个"Add File"对话框,双击所需的VBX文件名即可将该VBX加入到VB中,这些控件装入VB后,VB会将这些外来控件加到原有工具箱中,与其他控件一起合并使用。正是因为有了这一技术,VB才能够不断发展,使用VB编程也更为方便、迅速和有效,这是VB区别于其他程序开发环境的主要特色之一。自从VB推出以来,第三方软件公司设计了大量的新控件,下面是开发WINDOWS应用程序时几个非常有用的VBX:
●三维控件Threed.vbx
它提供了包括命令按钮、复选框、单选钮 、框架、下推按钮和面板在内的六种三维控件,使用这些控件可使窗体更具有立体感。
●图形控件Graph.vbx
向图形控件发送数据后,图形控件可绘制二维或三维饼图,、直方图、趋势图,并且可以打印或拷贝到剪贴板上。
●通讯控件Mscomm.vbx
它提供了串行通讯的能力,可用于串行端口之间传送和接收数据。
●数据网格控件Truegrid.vbx
它既可以作为一般的数据显示表格,也可把一个数据库和一个网格联系起来,它是制作数据库浏览器或数据显示的理想工具。
二、在应用层执行其他应用程序
在编制复杂的大型软件时,我们经常会需要有一些功能相对独立和完善的专用程序,如编辑程序,而这些程序通常是通用和流行并经实践检验的。如果由开发者重新编制这些程序,不仅大大增加了程序工作量以及调试过程,而且功能上很难比得上这些通用程序。显然,如果我们能直接调用这些程序是最为理想的。令人欣喜的是,VB提供了一个可用来调用其他应用程序的Shell函数,使VB的某些功能可直接由其他应用程序来完成,从而大大地减少了编程任务。
格式是Shell(命令字符串[,窗口类型])
其中的命令字符串是欲执行的应用程序名,可执行文件的扩展名只限于“.COM”,“.EXE”,“.BAT”,“.PIF”,缺省扩展名为.EXE文件,窗口类型是一整数值,它对应于程序执行时的显示窗口风格,是可选 的,共有下列5种选择:
窗口类型值
窗口类型 1,5,9
正常窗口,具有指针 2
最小窗口,具有指针(缺省) 3
最大窗口,具有指针 4,8
正常窗口,不具指针 6,7
最小窗口,不具指针
当Shell函数成功地调用某一个应用程序时,返回一个任务标识(Task ID),该ID表示正在执行的程序的唯一标识。
[例]
X=Shell("C:\WINDOWS/NOTEPAD.EXE",1)
该语句调用WINDOWS附件中的记事本NOTEPAD.EXE作为编辑程序来使用,并返回1个ID值到X。

15、成组更新控件属性

Sub EnableAll(Enabled As Boolean, ParamArray objs() As Variant)
Dim obj As Variant
For Each obj In objs
obj.Enabled = Enabled
Next obj
End Sub
应用:
EnableAll True, Text1, Text2, Command1, Command2