FoxPro 宣告方式:
DECLARE INTEGER ShellExecute IN shell32;
INTEGER hwnd,;
STRING lpOperation,;
STRING lpFile,;
STRING lpParameters,;
STRING lpDirectory,;
INTEGER nShowCmd
参数:
hwnd
Handle to a parent window. This window receives any message boxes
that an application produces, such as error reporting.
lpOperation
对指定档案执行时所做的动作,有下列几种选择:
edit 编辑
explore 浏览
find 搜寻
open 开启
print 列印
lpFile
所指定的档案
lpParameters
若指定档案是一个可执行档案(executable file),且其后可下参数时,lpParameters
就是存放该执行档的参数内容。
lpDirectory
指定档案所在的路径。若未指定,它会依预设的方式一一寻找。
nShowCmd
指定执行该档案时,其应用程式的显示模式:(除了下列两种外,应该还有其他)
0 不显示
1 一般大小
传回值:
1.若执行成功,传回大于 32 的数值。
2.若失败,有下列几种回应值:
2 错误的关联 (例如:不合法的 URL)
29 关联失败
30 关联应用程式忙碌中...
31 没有关联任何应用程式
范例:(先宣告此 API)
1.与指定的电脑之时间同步
M_cComputerName --> 指定的电脑名称
=ShellExecute(0,"Open","NET.EXE","time \\"+M_cComputerName+" /set /yes","",0)
2.档案复制
VFP 本身就有 COPY FILE ... 命令,但来源档案必须是未被使用中才行,
否则 VFP 会出现错误讯息,但改用下列方式就不会了。
M_cSourceFile --> 来源档案名称
M_cTargFile --> 目的档案名称
=ShellExecute(0,"Open",GETENV("COMSPEC"),"COPY "+M_cSourceFile+" "+M_cTargFile,"",0)
备注:
1.若是 Win2000 以下的 OS,请将 CMD.EXE 换成 COMMAND.COM。
不過在 VFP 中直接用 GETENV("COMSPEC") 就可以了,VFP 會自行判斷。
(2003/09/08 修改)
2.事实上它就是在 DOS 模式下执行 DOS 内部指令 COPY 的动作,以 VFP 的做法如下
! COPY &M_cSourceFile. &M_cTargFile.
3.将 nShowCmd 设为 0 就可令那讨厌的 DOS 视窗完全不会出现;
其他的 DOS 指令也可依此模式去做。
后记:
这是我使用此 API 的心得,当中若有不正确或须补充的地方,烦请各位能告知我,
以便将此 API 的说明更加完备
ShellExecute() 函数说明文件 2 (API)
加强及补充前次发表的文件
ShellExecute() 函数说明文件(API)
FoxPro 宣告方式:
DECLARE INTEGER ShellExecute IN shell32;
INTEGER hwnd,;
STRING lpOperation,;
STRING lpFile,;
STRING lpParameters,;
STRING lpDirectory,;
INTEGER nShowCmd
参数:
hwnd
1.指定一个父视窗的代码(Handle)值。
(一个指派给视窗的数值,供作业系统追踪视窗属性)
2.该应用程式所产生的视窗若有错误发生时会收到一个类似错误报告的讯息方块。
3.一般都设为 0。
lpOperation
对指定档案执行时所做的动作,有下列几种选择:(依该档案所能提供的动作而定)
edit 编辑
explore 浏览
find 搜寻
open 开启
print 列印
备注:
该档案所能提供的动作可由 档案总管 --> 工具 --> 资料夹选项 --> 档案类型
--> 进阶 --> 执行动作 可以查知。
lpFile
指定执行所指派动作的档案(可含完整路径名称)或物件名称。
lpParameters
若指定档案是一个可执行档案(executable file),且其后可下参数时,lpParameters
就是存放该执行档的参数内容。若无参数,补上 "" 即可。
lpDirectory
程式执行的工作目录。若为 "",表示采用预设的目录。
nShowCmd
指定执行该档案时,其应用程式以何种方式显示视窗:
0 不显示
1 最大化
2 最小化
传回值:
1.若执行成功,传回大于 32 的数值。
2.若失败,有下列几种回应值:
2 错误的关联 (例如:不合法的 URL)
29 关联失败
30 关联应用程式忙碌中...
31 没有关联任何应用程式
范例:(先宣告此 API)
* ---------------------------------------------------------------------------- *
1.与指定的电脑之时间同步
M_cComputerName --> 指定的电脑名称
=ShellExecute(0,"Open","NET.EXE","time \\"+M_cComputerName+" /set /yes","",0)
* ---------------------------------------------------------------------------- *
2.档案复制
VFP 本身就有 COPY FILE ... 命令,但来源档案必须是未被使用中才行,
否则 VFP 会出现错误讯息,但改用下列方式就不会了。
M_cSourceFile --> 来源档案名称
M_cTargFile --> 目的档案名称
=ShellExecute(0,"Open","CMD.EXE","COPY "+M_cSourceFile+" "+M_cTargFile,"",0)
=ShellExecute(0,"Open",GETENV("COMSPEC"),"COPY "+M_cSourceFile+" "+M_cTargFile,"",0)
备注:
1.若是 Win2000 以下的 OS,请将 CMD.EXE 换成 COMMAND.COM。
不过在 VFP 中直接用 GETENV("COMSPEC") 就可以了,VFP 会自行判断。
2.事实上它就是在 DOS 模式下执行 DOS 内部指令 COPY 的动作,以 VFP 的做法如下
! COPY &M_cSourceFile. &M_cTargFile.
3.将 nShowCmd 设为 0 就可令那讨厌的 DOS 视窗完全不会出现;
其他的 DOS 指令也可依此模式去做。
* ---------------------------------------------------------------------------- *
3.发送一个给指定电脑的“信差服务”讯息方块
会提供这个案例,是公司有内部控管的需求。VFP 应用程式放在公司伺服器所在的电脑
M_cSeverComputerName --> 公司伺服器所在的电脑名称
M_cUserIdR --> 接收讯息的使用者名称
* 在那一台电脑执行本程式
M_cCurComputerName = ALLTRIM(LEFT(SYS(0),AT("#",SYS(0))-1))
* 发送讯息的使用者名称
M_cUserIdS = ALLTRIM(SUBSTR(SYS(0),AT("#",SYS(0))+1))
* 在伺服器电脑上工作阶段连线的电脑及其使用者
* ---------------------------------- *
* M_aSessionInfo(*,1) = C 使用者名称
* M_aSessionInfo(*,2) = C 电脑名称
* ---------------------------------- *
DIMENSION M_aSessionInfo(1,2)
STORE "" TO M_aSessionInfo
* 只有伺服器的电脑才能产生 NetSession.TXT
IF M_cCurComputerName == M_cSeverComputerName
=STRTOFILE("NET.EXE SESSION > NetSession.TXT","Net.Bat")
=ShellExecute(0,"Open","Net.Bat","","",0)
ENDIF
* 取得伺服器电脑上工作阶段连线的电脑及其使用者
IF ADIR(W1_aAdir,"NetSession.TXT") > 0
W1_mComment = FILETOSTR("NetSession.TXT")
STORE "" TO M_aSessionInfo
W1_nRowOfSessionInfo = 0
FOR W1_SUB_A = 1 TO MEMLINES(W1_mComment)
W1_cLINE = MLINE(W1_mComment,W1_SUB_A,0)
W1_cHandle = SUBSTR(W1_cLINE,1,2) && 每列的表头
W1_cUserName = ALLTRIM(SUBSTR(W1_cLINE,24,20)) && 使用者名称
W1_cComputerName = ALLTRIM(SUBSTR(W1_cLINE,3,20)) && 电脑名称
IF !W1_cHandle = "\\"
LOOP
ENDIF
W1_nRowOfSessionInfo = W1_nRowOfSessionInfo + 1
DIMENSION M_aSessionInfo(W1_nRowOfSessionInfo,2)
M_aSessionInfo(W1_nRowOfSessionInfo,1) = W1_cUserName
M_aSessionInfo(W1_nRowOfSessionInfo,2) = W1_cComputerName
ENDFOR
ENDIF
* 传送“信差服务”
M_nCurRowOfSessionInfo = ASCAN(M_aSessionInfo,UPPER(ALLTRIM(M_cUserId)),1,-1,1,14)
IF M_nCurRowOfSessionInfo > 0
M_mMessage = "send " + M_aSessionInfo(M_nCurRowOfSessionInfo,2) + ;
" " + M_cUserIdS + "发讯息给 " + ALLTRIM(M_cUserId) + ;
":" + CHR(13) + CHR(10) + CHR(13) + CHR(10) + ;
"有一封信件到管理室领取"
=ShellExecute(0,"Open","net.exe",M_mMessage,"",0)
ENDIF
备注:
1.本 ASCAN() 函数的参数使用是 7.0 版的环境,6.0 版或以下版本,请自行改写。
2.实际上 NetSession.TXT 的产生是公司伺服器将程式放在工作排程中执行,
且每 5 分钟更新一次(这细节不便说明)。
3.传送后,接收讯息的使用者就会在其桌面出现“信差服务”讯息方块。
4.传送“信差服务”这一段实际上是在一个 SCAN ... ENDSCAN 中,
在这里简化内容。若要做个简单测试,将电脑名称都指定自己的电脑,
发送及接收的使用者名称也指定自己(就是一开始进入 Windows 登录的名称),
我想这样在自己的单机上测试就可达到效果。
* ---------------------------------------------------------------------------- *
后记:
1.这是我使用此 API 的心得,当中若有不正确或须补充的地方,烦请各位能告知我,
以便将此 API 的说明更加完备。
2.以后若有实际上应用的范例会继续提供,也希望各位若有实际应用的例子,
也祈盼分享出来。