Visual Basic 技巧库
第 12 部分 (111-120)
显示动画鼠标图标 显示动画鼠标图标 声明: Public Const GCL_HCURSOR =
-12 Declare Function ClipCursor Lib "user32" (lpRect As Any) As
Long Declare Function DestroyCursor Lib "user32" (ByVal hCursor As Any) As
Long Declare Function LoadCursorFromFile Lib "user32" Alias
"LoadCursorFromFileA" (ByVal lpFileName As String) As Long Declare Function
SetClassLong Lib "user32" Alias "SetClassLongA" (ByVal hwnd As Long, ByVal
nIndex As Long, ByVal dwNewLong As Long) As Long Declare Function
GetClassLong Lib "user32" Alias "GetClassLongA" (ByVal hwnd As Long, ByVal
nIndex As Long) As Long 使用: Dim mhBaseCursor As Long, mhAniCursor As
Long Dim lResult As Long mhAniCursor =
LoadCursorFromFile("c:\windows\cursors\appstart.ani") lResult =
SetClassLong((hwnd), GCL_HCURSOR, mhAniCursor)
显示盘中所有的目录 显示盘中所有的目录 以下的代码把盘中所有的目录都显示在 Listbox
中。需要一个 DriveListBox 和一个 DirListBox。如果 DirListBox 隐藏的话,处理可以快一些。
Dim iLevel As Integer, iMaxSize As Integer Dim i As Integer, j As
Integer ReDim iDirCount(22) As Integer '最大 22 级目录 ReDim
sdirs(22, 1) As String 'drive1 是 DriveListBox 控件 'dir1 是 DirListBox
控件 iLevel = 1 iDirCount(iLevel) = 1 iMaxSize = 1 sdirs(iLevel,
iDirCount(iLevel)) = Left$(drive1.Drive, 2) & "\" Do
iLevel = iLevel + 1 iDirCount(iLevel) = 0 For j = 1
To iDirCount(iLevel - 1) dir1.Path = sdirs(iLevel - 1,
j) dir1.Refresh If iMaxSize <
(iDirCount(iLevel) + dir1.ListCount)
Then ReDim Preserve sdirs(22,
iMaxSize + dir1.ListCount + 1) As
String iMaxSize = dir1.ListCount +
iDirCount(iLevel) + 1 End If For i = 0
To dir1.ListCount -
1 iDirCount(iLevel) =
_ iDirCount(iLevel)
+ 1
'子目录记数 sdirs(iLevel,
iDirCount(iLevel)) = dir1.List(i) Next i Next
j '所有名称放到 List1 中 list1.Clear If iDirCount(iLevel) = 0
Then '如果无自目录 For i = 1 To
iLevel For j = 1 To
iDirCount(i) list1.AddItem
sdirs(i, j) Next
j Next i Exit Do End If Loop
延时函数 定义函数: Public Function Delay(Mins%, Secs%, Optional
ByRef StopFlag) As Long Dim EndOfDelay EndOfDelay = DateAdd("n", Mins,
Now) EndOfDelay = DateAdd("s", Secs, EndOfDelay) Delay = 0 Do While
(Now < EndOfDelay) DoEvents If Not IsMissing(StopFlag) Then If
StopFlag Then Delay = 1 StopFlag = False Exit Do End If End
If Loop End Function 使用例子:
Dim StopTheTimer As Boolean
Private Sub Command1_Click() '开始延时 Dim lRetval& lRetval =
Delay(1, 5, StopTheTimer) If lRetval = 0 Then MsgBox
"时间到!" Else MsgBox "取消延时!" End If End Sub Private Sub
Command2_Click() '取消延时 StopTheTimer = True End Sub
移动文件到回收站 移动文件到回收站 98-7-04 声明: Public Type
SHFILEOPSTRUCT hwnd As Long wFunc As Long pFrom As String pTo As
String fFlags As Integer fAnyOperationsAborted As Long hNameMappings As
Long lpszProgressTitle As Long End Type
Public Declare Function SHFileOperation Lib _ "shell32.dll" Alias
"SHFileOperationA" (lpFileOp _ As SHFILEOPSTRUCT) As Long
Public Const FO_DELETE = &H3 Public Const FOF_ALLOWUNDO = &H40
代码: Dim SHop As SHFILEOPSTRUCT Dim strFile as string
With SHop .wFunc = FO_DELETE .pFrom = strFile .fFlags =
FOF_ALLOWUNDO End With
隐藏和显示任务栏 隐藏和显示任务栏
任务栏一般是显示在窗口的最底下,但有时我们需要隐藏它。 声明: Dim hWnd1 As Long Private Declare
Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As
String, ByVal lpWindowName As String) As Long Private Declare Function
SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long,
ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal
wFlags As Long) As Long Const SWP_HIDEWINDOW = &H80 Const
SWP_SHOWWINDOW = &H40 隐藏的例子: hWnd1 = FindWindow("Shell_traywnd",
"") Call SetWindowPos(hwnd1, 0, 0, 0, 0, 0, SWP_HIDEWINDOW) 显示的例子: Call
SetWindowPos(hwnd1, 0, 0, 0, 0, 0, SWP_SHOWWINDOW)
应用中集成浏览器 在应用中集成浏览器 从 MS IE 3.0 开始就包括了一个名为 "WebBrowser"
的 ActiveX 控件。利用该控件,你可以开发强大的基于浏览器的应用。下面讨论如何进行集成。 1. 在 工程 菜单中, 选择 部件 。 2. 选择
Microsoft Internet Controls 。 3. 增加一个 WebBrowser 控件。
4. 使用以下的代码可连接到 VB 加油站:
WebBrowser1.Navigate "http://vbtt.yeah.net"
用DATA控件绑定报表控件打印报表 用DATA控件绑定报表控件打印报表 98-8-09 1
在数据库中生成一TEMP表。 2 用报表生成器生成报表,然后删除数据库中的TEMP表。 3
在VB中打开数据库,用OPENRECORDSET语句生成一个RECORDSET (此RECORDSET的结构要与第一步生成的TEMP表一样,但记录数可以 用WHERE子句限制) 用SET
DATA1.RECORDSET=RS(RECORDSET)将RECORDSET的数据赋予数据控件。 4
设定报表控件的REPORTFILENAME属性为报表文件名; REPORTSOURCE属性为3; DATASOURCE属性为数据控件名 5
执行ME.CR1.ACTION=1即可打印。 但我不知如何直接利用RECORDSET中的数据,如果你知道请告知。 感谢由 FENG
提供该技巧。
用ODBC
API访问ODBC数据库 编写直接使用ODBC
API 访问ODBC 数据库的VB 程序
---- 开放数据库互连(ODBC)已经成为Client /Server
数据 库应用系统中访问远程数据库的一个标准。做为强大 的前端开发工具,MS Visual Basic 为开发者提供了多种访 问ODBC
数据源的途径,如JET 数据库引擎、ODBC API 函数、RDO 接口等。比较而言,直接使用ODBC API
函数的编程难度最 大,但由此获得的存取数据库的性能也是最佳。诚然, VB 4.0 企业版提供的RDO 接口的性能已经接近ODBC
API,但 是遗憾的是,这个接口只能在32 位Windows 环境中运行, 而ODBC API 函数则没有这个限制。
ODBC API 函数的声明方法
---- 与使用其它动态库函数一样,在VB 中使用ODBC API 函 数之前,必须事先声明将要使用的函数、常量和数据 结构。ODBC
API 函数驻留在ODBC 运行动态库ODBC.DLL(16 位) 或ODBC32.DLL(32 位)中,该动态库位于Windows
子目录system 中。通常做法是在VB 项目中单独使用一个模块文件,然 后将ODBC API
声明语句加入其中,如下所示,就是本文实 例中使用的模块文件module1.bas 的内容:
---- Declare Function SQLAllocEnv Lib "odbc32.dll" (phenv&)
As Integer ---- Declare Function SQLAllocConnect Lib "odbc32.dll" (ByVal
henv&, phdbc&) As Integer ---- Declare Function SQLAllocStmt Lib
"odbc32.dll" (ByVal hdbc&, phstmt&) As Integer ---- Declare
Function SQLConnect Lib "odbc32.dll" (ByVal hdbc&, ByVal szDSN$, ByVal
cbDSN%, ByVal szUID$, ByVal cbUID%, ByVal szAuthStr$, ByVal cbAuthStr%) As
Integer ---- Declare Function SQLColAttributesString Lib "odbc32.dll"
Alias "SQLColAttributes" (ByVal hstmt&, ByVal icol%, ByVal
fDescType%, ByVal rgbDesc As String, ByVal cbDescMax%, pcbDesc%, pfDesc&)
As Integer ---- Declare Function SQLDisconnect Lib "odbc32.dll" (ByVal
hdbc&) As Integer ---- Declare Function SQLExecDirect Lib
"odbc32.dll" (ByVal hstmt&, ByVal szSqlStr$, ByVal cbSqlStr&) As
Integer ---- Declare Function SQLFetch Lib "odbc32.dll" (ByVal hstmt&)
As Integer ---- Declare Function SQLFreeConnect Lib "odbc32.dll" (ByVal
hdbc&) As Integer ---- Declare Function SQLFreeEnv Lib "odbc32.dll"
(ByVal henv&) As Integer ---- Declare Function SQLFreeStmt Lib
"odbc32.dll" (ByVal hstmt&, ByVal fOption%) As Integer Declare Function
SQLGetData Lib "odbc32.dll" (ByVal hstmt&, ByVal icol%, ByVal fCType%,
ByVal rgbValue As String, ByVal cbValueMax&, pcbValue&) As Integer
---- Declare Function SQLNumResultCols Lib "odbc32.dll"
(ByVal hstmt&, pccol%) As Integer ---- Global Const SQL_C_CHAR As
Long = 1 ---- Global Const SQL_COLUMN_LABEL As Long = 18 ---- Global
Const SQL_DROP As Long = 1 ---- Global Const SQL_ERROR As Long = -1 ----
Global Const SQL_NO_DATA_FOUND As Long = 100 ---- Global Const SQL_SUCCESS
As Long = 0
---- 需要说明的是,在函数声明时,应该根据程序的运 行环境选择相应的动态库。在VB
子目 录samples\remauto\db_odbc 中有两个正文文件ODBC16.TXT 和ODBC32.TXT,分别存有所有16 位和32
位ODBC API 函数、常量 和数据结构的声明语句,编程时可以从中拷贝所需的 声明语句。
使用ODBC API 的编程方法
---- 在VB 中调用ODBC API 函数访问ODBC 数据库,代码编制一 般是按照下列过程进行的:
一、初始化ODBC
---- 在这个过程中,应用程序将通过调用SQLAlloEnv 函数 初始化ODBC 接口,获取ODBC 环境句柄。ODBC
环境句柄是其 它所有ODBC 资源句柄的父句柄,因此无论程序将建立多 少个ODBC 连接,这个过程只需执行一次即可。例如:
---- Dim rc As Integer 'ODBC 函数的返回码 ---- Dim henv As Long 'ODBC
环境句柄 ---- rc = SQLAllocEnv(henv) ' 获取ODBC 环境句柄
二、与ODBC 数据源建立连接
---- 这个过程由下列两个步骤组成:
---- 1、调用SQLAllocConnect 函数获取连接句柄。例如: ---- Dim hdbc As Long '
连接句柄 ---- rc = SQLAllocConnect(henv, hdbc) ' 获取连接句柄
---- 2、建立连接。这个步骤可以通过多种方法实现, 最简单直观的方法是调用SQLConnect 函数。例如: ---- Dim
DSN As String, UID As String, PWD As String ---- DSN = "DataSourceName"
'ODBC 数据源名称 ---- UID = "UserID" ' 用户帐号 ---- PWD = "Password" '
用户口令 ---- rc = SQLConnect(hdbc, DSN, Len(DSN), UID, Len(UID),
PWD, Len(PWD)) ' 建立连接
三、存取数据
---- 用户对ODBC 数据源的存取操作,都是通过SQL 语句实 现的。在这个过程中,应用程序将通过连接向ODBC
数据 库提交SQL 语句,以完成用户请求的操作。具体步骤如 下:
---- 1、调用SQLAllocStmt 函数获取语句句柄。例如: ---- Dim hstmt As Long ---- rc
= SQLAllocStmt(hdbc, hstmt)
---- 2、执行SQL 语句。执行SQL 语句的方法比较多,最简 单明了的方法是调用SQLAllocStmt 函数,例如: ----
Dim SQLstmt As String ---- SQLstmt = "SELECT * FROM authors" ---- rc =
SQLExecDirect(hstmt, SQLstmt, Len(SQLstmt))
四、检索结果集
---- 如果SQL
语句被顺利提交并正确执行,那么就会产 生一个结果集。检索结果集的方法有很多,最简单最 直接的方法是调用SQLFetch 和SQLGetData
函数。SQLFetch 函数 的功能是将结果集的当前记录指针移至下一个记录, SQLGetData
函数的功能是提取结果集中当前记录的某个 字段值。通常可以采用一个循环以提取结果集中所有 记录的所有字段值,该循环重复执行SQLFetch
和SQLGetData 函数,直至SQLFetch 函数返回SQL_NO_DATA_FOUND,这表示已经 到达结果集的末尾。
---- Dim ColVal As String * 225 ---- ColVal = String(255, 0) ----
Do Until SQLFetch(hstmt) = SQL_NO_DATA_FOUND ---- rc = SQLGetData(hstmt, i,
SQL_C_CHAR, ColVal, Len(ColVal), SQL_NULL_DATA) ---- Loop
五、结束应用程序
---- 在应用程序完成数据库操作,退出运行之前,必须 释放程序中使用的系统资源。这些系统资源包括:语 句句柄、连接句柄和ODBC
环境句柄。完成这个过程的步 骤如下:
---- 1、调用SQLFreeStmt 函数释放语句句柄及其相关的系 统资源。例如: ---- rc =
SQLFreeStmt(hstmt, SQL_DROP)
---- 2、调用SQLDisconnect 函数关闭连接。例如: ---- rc = SQLDisconnect(hdbc)
---- 3、调用SQLFreeConnect 函数释放连接句柄及其相关的 系统资源。例如: ---- rc =
SQLFreeConnect(hdbc)
---- 4、调用SQLFreeEnv 函数释放环境句柄及其相关的系 统资源,停止ODBC 操作。例如: ---- rc =
SQLFreeEnv(henv)
---- 此外,在编制程序时还有一个需要重点考虑的问 题,这就是错误处理。所有ODBC API
函数,若在执行期间 发生错误,都将返回一个标准错误代码SQL_ERROR。一般 来讲,在每次调用ODBC API
函数之后,都应该检查该函数 返回值,确定该函数是否成功地执行,再决定是否继 续后续过程。而详细的错误信息,可以调用SQLError
函数 获得。SQLError 函数将返回下列信息:
标准的ODBC 错误状态码 ODBC
数据源提供的内部错误编码 错误信息串
简单应用实例
---- 本实例将编制一个客户机端VB 应用程序,通过 Windows NT 局域网查询服务器端MS SQL Server 6.5
样板数据 库PUBS 中的AUTHORS 数据表,并在一个Grid 控件中显示查询 结果。首先,使用Windows 控制面板中的ODBC
驱动管理器新 建一个ODBC
数据源,定义数据源名称为ODBC_API_DEMO,定义 登录数据库为PUBS,其它信息应根据用户的环境正确设 置。然后,启动VB,新建一个项目Project1,在缺省窗体 Form1
中加入一个Grid 控件Grid1、两个CommandButton 控 件cmdQuery 和cmdClose,在Project1
中插入一个模块Module1,将 前面列举的声明语句加入其中。程序代码如下:
Private Sub Form_Load() Dim rc As Integer rc =
SQLAllocEnv(henv) If rc <> 0 Then MsgBox "
无法初始化ODBC" End End If rc =
SQLAllocConnect(henv, hdbc) If rc <> 0
Then MsgBox " 无法获得连接句柄" rc =
SQLFreeEnv(henv) End End If Dim DSN As String,
UID As String, PWD As String DSN = "ODBC_API_DEMO" UID =
"guest" PWD = "" rc = SQLConnect(hdbc, DSN, Len(DSN), UID,
Len(UID), PWD, Len(UID)) If rc = SQL_ERROR
Then MsgBox " 无法建立与ODBC
数据源的连接" End End If End Sub Private Sub
cmdQuery_Click() Dim hstmt As Long Dim SQLstmt As String Dim RSCols As
Integer, RSRows As Long Dim rc As Integer, i As Integer, j As Integer Dim
ColVal As String * 1024 Dim ColValLen As Long, ColLabLen As Integer, larg As
Long rc = SQLAllocStmt(hdbc, hstmt) If rc <> SQL_SUCCESS
Then MsgBox " 无法获得SQL 语句句柄" Exit
Sub End If SQLstmt = "SELECT * FROM authors" rc =
SQLExecDirect(hstmt, SQLstmt, Len(SQLstmt)) If rc <> SQL_SUCCESS
Then MsgBox "SQL 语句执行失败" Exit
Sub End If rc = SQLNumResultCols(hstmt, RSCols) If
RSCols > 1 Then Grid1.Cols =
RSCols Grid1.Rows = 10 Grid1.Row =
0 Else Exit Sub End If For i = 1
To RSCols rc = SQLColAttributesString(hstmt, i,
SQL_COLUMN_LABEL, ColVal, 255, ColLabLen,
larg) Grid1.Col = i - 1 Grid1.Text =
Left(ColVal, ColLabLen) Next i Do Until SQLFetch(hstmt) =
SQL_NO_DATA_FOUND ColVal = String$(1024,
0) If Grid1.Row + 1 >= Grid1.Rows
Then Grid1.Rows = Grid1.Rows +
1 End If Grid1.Row = Grid1.Row +
1 For i = 1 To RSCols rc =
SQLGetData(hstmt, i, SQL_C_CHAR,
ColVal, Len(ColVal),
ColValLen) Grid1.Col = i -
1 Grid1.Text = Left$(ColVal,
ColValLen) Next i Loop rc =
SQLFreeStmt(hstmt, SQL_DROP) End Sub Private Sub cmdClose_Click() Dim
rc As Integer If hdbc <> 0 Then rc =
SQLDisconnect(hdbc) End If rc =
SQLFreeConnect(hdbc) If henv <> 0 Then rc =
SQLFreeEnv(henv) End If End End Sub
---- 实例程序是使用Visual Basic 4.0 在Windows 95 环境下开发的。
用VB5.0开发分布式应用 用VB5.0开发分布式应用
西安奥林岛公司-张吉龙
---- 微软推出的VB5.0
是一个功能强大的开发平 台。它在“代码重用性”上地加强是一个引人注 目的特点。我们可以将需要多次重复使用的功 能单元开发成Active
X 组件(Active X Control, Active X Exe, Active X
Dll),然后在新程序中象使用VB 标准 控件及类一样使用这些组件。
---- Active X
组件给开发网络应用带来很大方便。 我们可以将这些组件分布在网络的不同机器 上,构成分布式应用,就好象所有组件都在同一 台器上一样。很多朋友都有开发本地Active
X 组 件的经验,本文将结合实例介绍一下如何将 Active X
组件分布在网络上构成分布式应用。
一、概述
---- “Active X"
是微软为分布式计算制定的一套 标准,它的前身就是大家所熟知的“OLE
Automation "。当分布式应用通过网络通讯时,Active X
可以 使用两种不同的机制对客户请求作出响应。一 种称为“分布组件对象模式(DCOM)”,只可以在 Windows
NT 和Windows95 上使用;另一种是“远程自动 化(Remote Automation)",它可以在16
位环境下构造 分布式应用。
----
这两种分布式机制,有着极其引人的特点: 与组件物理位置的无关性。也就是说,当你构造 一个Active
X
组件时,无需知道它将分布在那一台 机器上。同样的组件,即可以将它放在本机,也 可以将它分布在其它机器上而不需要从新编 译。这样,根据网络的性能和网络结构的变化, 我们可以方便的调整组件的分布策略。
---- 当然,用Active X
构建分布式应用的各个独立 组件,还有其它优点:
构造远程组件和构造本地组件的编程方法 一模一样,无须特殊的工程经验。 可以用Active
X 组件在服务器端实现复杂的商 业规则。比起用DBMS(如SQL
Server)来完成同样 的工作,我们有更好地编程、维护、排错手 段。 有大量的商业组件可以使用。而且这样的组 件会越来越多。我们只需将特殊的商业规则 开发成组件,与购买的组件配合使用。
二、开发和调试
----
开发分布式组件和开发本地组件相同,调试 也可以在本地完成,本文不在赘述。(可以参看 VB5.0
所带的例子: \Sample\CliSvr\BookSale\Client\book_cli.vbp
客户端程序; \Sample\CliSvr\BookSale\Client\book_svr.vbp
服务器程序 。)在开发分布式服务器段组件时,请注意下列 问题:
服务器端的Project 应为Active X
EXE(进程外的 Active X
组件)。这也很容易理解,不可能在 两台机器上完成同一个进程,所以,不可能 使用Active
X DLL(进程内的组件)。 在Project Properties
对话框的组件栏目下,应设 为Remote Server
File。这样,在程序编译时会生 成一个VBR
文件,在生成安装盘时要用。大家 知道,Windows
程序在系统注册表中有注册,此 文件与注册有关。 Class
属性应设为Mutiuse,以便多个客户应用 可以使用它。、
三、生成安装盘
----
服务器端组件及客户端程序将安装在不同 的机器上,应利用Setup Wizard 分别生成安装程序。
----
当生成客户端程序安装盘时,需提供服务器 组件所在的机器名(以后可以修改),这将影响 客户端机器的注册项,这些注册项告诉客户端 程序,到那里去寻找相应的服务(即服务器端组 件提供的服务)。微软提供了工具,可以根据需 要随时修改这些注册项。如果使用Remote
Automation 机制,可使用RemAuto Connection Manager;如使用DCOM
机 制,可使用Dcom Configuration Manager。RemAuto
Connector Manager 在VB5.0
软件包中即有,在生成安装盘时将 自动包括它。Windows NT 4.0 中包含Dcom
Configuration Manager,可直接使用。对于Windows
95,需从 www.Microsoft.com 下载Dcom95.exe 及Dcom95cfg.exe
并运行, 可得到Dcom Configuration
Manager(注意要重新启动机 器)。
---- 利用上述工具,可实现如下功能:
1.可以随时切换服务器组件是在本地还是远 程。这样可以方便的在本机调试远程组件。 2.可随时改变服务器组件的安装位置。
---- 如何生成服务器端安装程序:
1.使用Setup Wizard,按要求指明Project
文件所在 的路径,并指明“产生安装程序”。 2.在进入“Share
Active
Application”画面时,选择 ?安装为一个共享组件”。如果你准备使用 Remote
Automation,在画面下方选择“Yes";如使 用Dcom,选择“No”。如果使用Remote
Automation, RemAuto Connection
Manager(racmgr32.exe)、Remote Automation
Manager(autmgr32.exe)将自动包含在安 装程序内。
---- 如何生成客户端安装程序:
1.使用Setup Wizard,按要求指明Project
文件所在 的路径,并指明“产生安装程序”。 2.进入“Active
X 组件”画面时,按Add Remote 按纽 指定服务器组件对应的vbr
文件(包含服务器 组件的Object Id
等注册信息)。 3.这是,会弹出“Remote Connection
Details”对话 框。选择使用Remote automation
或DCOM;输入服务 器的机器名。如果使用Remote
Automation,还需 确定通讯协议,如TCP/IP
等。验证级别用来保 证客户端与服务器间通讯的安全性。这是一 个较为复杂的问题,为了简化期间,选择None 即可。 4.返回“Active
X Server
Components”画面。如果你的 程序使用多个远程组件,可逐一加入。相关 的本地组件,可按“Add
Local”一一加入。注 意,系统缺省会将一些组件当作本地组件, 不要将同一组件即当作远程组件,又当作本 地组件。
四、安装与使用
---- Windows NT 4.0 支持DCOM,可直接安装DCOM
分布式 应用。对于Windows 95,需要安装附加程序,以支持 DCOM
分布式应用。但,Windows 95 可直接安装Remote Automation 应用。
---- Remote Automation 模式:
----
分别在服务器及客户端机器上安装相应程 序。在服务器端,要先启动Automation
Manager (Autmgr32.exe,安装程序会自动将该文件拷到系 统目录下),客户端才可建立连接。这种模式对 操作系统要求较低,Windows
3.1 , Windows95 , Windows NT 等均可做服务器或客户端。
----
本方法提供的安全性较差,无法限制那些用 户可以连接或不可以连接。不过,系统还是提供 了许多安全管理措施。读者在学习时不妨做简 化处理:
---- 在服务器端启动Remote Automation
Connection Manager(RACMGR32.exe),在左侧选相应的Server
组件, 在右侧Client Access 栏目下,选择Allow all
remote creates 。
---- 关于客户端的安装,我们前面作过讨论。利 用Remote
Automation Connection Manager(RACMGR32.exe),在 Server
Connection 栏目下,我们可以随时调整服务 器组件的分布位置。
---- Remote automation
这种模式提供了很大的灵活 性,在安全性要求不高的场合,可以使用该模 式。
---- DCOM 模式:
---- 要构造DCOM 应用,服务器端最好使用Windows
NT Server 或Windows NT
Workstation,客户端可使用Windows NT 或Windows95
。这也符合实际应用的策略,Server Component
要求有较高的可靠性,一般分布在专用 服务器上。
---- 在服务器组件安装完毕后,要确定RPC
Service 是启动的。在客户端能够建立连接之前,还需要 配置访问权限。
---- 为了简单期间,你可以这样做:
1.运行Dcomcfg.exe
(在系统目录下)。 2.选择相应组件,设置其Properties。 3.在Location
栏目下,设为:Run app on this
computer ;在Security
栏目下,选择定制安全性,并将 权限给Everyone
Full Control 。
----
在客户端的机器上,通过Dcomcfg.exe,在Location 栏目下,可以指定服务器组件的安装位置。
---- 在Windows 95 下构建DCOM 应用的特殊考虑:
---- 如果使用Windows95 做客户端,应从VB5.0
的光盘 或从www.microsoft.com 找如下两个文件:Dcom95.exe
, Dcm95cfg.exe。安装并重新启动机器即可。
---- 如Server 端使用Windows 95,须考虑下列问题:
1.安全性将受到限制。 2.应手工在Startup 中加进Server
组件的启动程 序。 3.运行RPCSS.exe
后,客户端才可建立连接。 4.由于Server Component
是一个Class,当没有客户程 序参照它时,它会自动终止。可是,Windows
95 没有自动启动它的机制。所以,要保证Server Component
不会从内存卸载。办法是:在Server Component 中加入一个Form,Visible
为False。程序 从Form 启动。 5.应从VB5.0
的光盘或从www.microsoft.com 找如下两 个文件:Dcom95.exe ,
Dcm95cfg.exe。安装并重新启 动机器。 6.手工改变注册表:HKEY_LOCAL_MACHINE\
Software \Microsoft \OLE \Enable Remote
connection 改为“Y"。 否则,会出现“Run Time Error, Active
Component Cannot Be Create
” 7.如同在Windows NT 上一样,运行Dcomcfg.exe
并进行 配置。
运行其他程序等其结束 运行其他程序,并等待执行完毕 在程序中,我们可能要打开一个程序,如:Notepad,并要求在该程序结束后,才继续其他的操作。以下的代码完成这样的要求。 声明: Const
SYNCHRONIZE = &H100000 Const INFINITE = &HFFFFFFFF Declare
Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal
bInheritHandle As Long, ByVal dwProcessId As Long) As Long Declare Function
CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Declare Function
WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds
As Long) As Long 例子:(以 Notepad 为例) Dim pId As Long, pHnd As Long pId =
Shell("Notepad", vbNormalFocus) pHnd = OpenProcess(SYNCHRONIZE, 0, pId) ' 取得
Process Handle If pHnd <> 0 Then Call WaitForSingleObject(pHnd,
INFINITE) ' 等待程序结束 Call CloseHandle(pHnd) End If
|