這個是我們在vb 和 VC 中的應用程序與EXCEL 透過 DDE處理數據的方法. Public Declare Function DdeCreateDataHandle Lib "user32" (ByVal idInst As Long, pSrc As Byte, ByVal cb As Long, ByVal cbOff As Long, ByVal hszItem As Long, ByVal wFmt As Long, ByVal afCmd As Long) As Long Public Declare Function DdeCreateStringHandle Lib "user32" Alias "DdeCreateStringHandleA" (ByVal idInst As Long, ByVal psz As String, ByVal iCodePage As Long) As Long Public Declare Function DdeUninitialize Lib "user32" (ByVal idInst As Long) As Long Public Declare Function DdeInitialize Lib "user32" Alias "DdeInitializeA" (pidInst As Long, ByVal pfnCallback As Long, ByVal afCmd As Long, ByVal ulRes As Long) As Integer Public Declare Function DdeNameService Lib "user32" (ByVal idInst As Long, ByVal hsz1 As Long, ByVal hsz2 As Long, ByVal afCmd As Long) As Long Public Declare Function DdeCmpStringHandles Lib "user32" (ByVal hsz1 As Long, ByVal hsz2 As Long) As Long Public Declare Function DdeQueryString Lib "user32" Alias "DdeQueryStringA" (ByVal idInst As Long, ByVal hsz As Long, ByVal psz As String, ByVal cchMax As Long, ByVal iCodePage As Long) As Long Public Declare Function DdeFreeStringHandle Lib "user32" (ByVal idInst As Long, ByVal hsz As Long) As Long Public Declare Function DdeFreeDataHandle Lib "user32" (ByVal hdata As Long) As LongPublic Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Public Const CF_TEXT = 1Public Const DNS_REGISTER = &H1 Public Const DNS_UNREGISTER = &H2Public Const XTYPF_NOBLOCK = &H2 ' CBR_BLOCK will not workPublic Const APPCLASS_STANDARD = &H0&Public Const CP_WINANSI = 1004 ' default codepage for windows old DDE convs.Public Const DMLERR_NO_ERROR = 0 ' must be 0 Public Const DMLERR_LOW_MEMORY = &H4007Public Const XCLASS_BOOL = &H1000 Public Const XCLASS_DATA = &H2000Public Const XCLASS_NOTIFICATION = &H8000 Public Const XTYP_DISCONNECT = (&HC0 Or XCLASS_NOTIFICATION Or XTYPF_NOBLOCK) Public Const XTYP_UNREGISTER = (&HD0 Or XCLASS_NOTIFICATION Or XTYPF_NOBLOCK) Public Const XTYP_CONNECT = (&H60 Or XCLASS_BOOL Or XTYPF_NOBLOCK) Public Const XTYP_REQUEST = (&HB0 Or XCLASS_DATA) Public DDE_SERVICESRV As Long Public DDE_TOPICSRV As Long Public DDE_TOPICACC As LongPublic DDE_INST As LongPublic DDE_ITEMSRVDS As Long Public DDE_ITEMSRVSRV As Long Public DDE_ITEMSRVUSER As Long Public DDE_ITEMSRVPWD As LongPublic Const TOPIC_ACC = "Acc" Public Const SERVICE_SRV = "KAL" Public Const TOPIC_SRV = "System"Public Const ITEM_SRV_DS = "DS" Public Const ITEM_SRV_USER = "USER" Public Const ITEM_SRV_SRV = "SRV" Public Const ITEM_SRV_PWD = "PWD"Public bData As Byte Public bCompInfo As Byte Public Function DDECallBack(ByVal uType As Long, ByVal uFmt As Long, ByVal hConv As Long, ByVal hsz1 As Long, ByVal hsz2 As Long, ByVal data As Long, ByVal data1 As Long, ByVal data2 As Long) As Long On Error GoTo ERR_CODE Dim accdat As String * 20 Dim Load_Buf As String * 256 Dim i As Integer Dim straccdat As String Dim p As String Dim strSql As String Dim period_offset As Long, period_to As Long, period_before As Long Dim rstmp As ADODB.Recordset Select Case uType Case XTYP_CONNECT DDECallBack = True Case XTYP_UNREGISTER DDECallBack = True Case XTYP_REQUEST If Not DdeCmpStringHandles(hsz1, DDE_TOPICACC) Then DdeQueryString DDE_INST, hsz2, accdat, 15, CP_WINANSI For i = 1 To Len(accdat) If Mid$(accdat, i, 1) = Chr$(0) Then Exit For End If straccdat = straccdat & Mid$(accdat, i, 1) Next i If StrComp(Mid$(straccdat, 1, 4), "DATE", vbTextCompare) = 0 Then strSql = "SELECT " & straccdat & " FROM FINSTMT" end if Set rstmp = New ADODB.Recordset rstmp.Open strSql, ConGamma If Not (rstmp.EOF And rstmp.BOF) Then accdat = rstmp.Fields(0) & Chr$(0) Else accdat = "0" & Chr$(0) End If rstmp.Close Set rstmp = Nothing CopyMemory bData, ByVal accdat, Len(accdat) DDECallBack = DdeCreateDataHandle(DDE_INST, bData, Len(accdat), 0, DDE_TOPICACC, CF_TEXT, 0) Exit Function End If p = Mid$(straccdat, 2, 1) If IsNumeric(Mid$(p, 1, 1)) Then period_offset = Val(p) Else period_offset = Asc(p) - Asc("a") + 10 End If Set rstmp = New ADODB.Recordset If UserInfo.CompanyCode <> "" Then rstmp.Open "select min(P2) from FINSTMT WHERE COMPCODE='" & UserInfo.CompanyCode & "'", ConGamma Else rstmp.Open "select min(P2) from FINSTMT", ConGamma End If If Not IsNull(rstmp.Fields(0)) Then period_to = rstmp.Fields(0) period_before = PeriodSub(period_to, period_offset) End If rstmp.Close Set rstmp = Nothing Select Case LCase$(Mid$(straccdat, 1, 1)) Case "c" Case "u" Case "a" Case "q" Case "w" strSql = "select round(sum(isnull(CR,0)),2) from FINSTMT where PARENT='" & UCase$(Trim$(Right$(straccdat, Len(straccdat) - 2))) & "' and PERIOD=" & period_before End Select CopyMemory bData, ByVal accdat, Len(accdat) DDECallBack = DdeCreateDataHandle(DDE_INST, bData, Len(accdat), 0, DDE_TOPICACC, CF_TEXT, 0) Exit Function
Else If Not DdeCmpStringHandles(hsz1, DDE_TOPICSRV) Then DdeQueryString DDE_INST, hsz2, accdat, 15, CP_WINANSI If DdeCmpStringHandles(hsz2, DDE_ITEMSRVDS) = 0 Then accdat = Trim$(UserInfo.DBName) & Chr$(0) CopyMemory bData, ByVal accdat, Len(accdat) data = DdeCreateDataHandle(DDE_INST, bData, Len(accdat), 0, DDE_TOPICSRV, CF_TEXT, 0) ElseIf DdeCmpStringHandles(hsz2, DDE_ITEMSRVSRV) = 0 Then accdat = Trim$(UserInfo.DBServer) & Chr$(0) CopyMemory bData, ByVal accdat, Len(accdat) data = DdeCreateDataHandle(DDE_INST, bData, Len(accdat), 0, DDE_TOPICSRV, CF_TEXT, 0) ElseIf DdeCmpStringHandles(hsz2, DDE_ITEMSRVUSER) = 0 Then accdat = UserInfo.userName & Chr$(0) CopyMemory bData, ByVal accdat, Len(accdat) data = DdeCreateDataHandle(DDE_INST, bData, Len(accdat), 0, DDE_TOPICSRV, CF_TEXT, 0) ElseIf DdeCmpStringHandles(hsz2, DDE_ITEMSRVPWD) = 0 Then accdat = "caladus" & Chr$(0) CopyMemory bData, ByVal accdat, Len(accdat) data = DdeCreateDataHandle(DDE_INST, bData, Len(accdat), 0, DDE_TOPICSRV, CF_TEXT, 0) ElseIf UCase$(Mid$(accdat, 1, 2)) = "CO" Then Load_Buf = strCompanyName & Chr$(0) CopyMemory bCompInfo, ByVal Load_Buf, Len(Load_Buf) DDECallBack = DdeCreateDataHandle(DDE_INST, bCompInfo, Len(Load_Buf), 0, DDE_TOPICSRV, CF_TEXT, 0) Exit Function Else DdeQueryString DDE_INST, hsz2, Load_Buf, Len(Load_Buf), CP_WINANSI If UCase$(Mid$(Load_Buf, 1, 4)) = "CURR" Then If UserInfo.CompanyCode <> "" Then strSql = "select CURR from COMPANYINFO WHERE COMPCODE='" & UserInfo.CompanyCode & "'" Else strSql = "select CURR from COMPANYINFO" End If Set rstmp = New ADODB.Recordset rstmp.Open strSql, ConGamma Load_Buf = Trim$(rstmp.Fields(0)) & Chr$(0) rstmp.Close Set rstmp = Nothing CopyMemory bData, ByVal Load_Buf, Len(Load_Buf) data = DdeCreateDataHandle(DDE_INST, bData, Len(Load_Buf), 0, DDE_TOPICSRV, CF_TEXT, 0) End If End If DDECallBack = data End If End If End Select Set rstmp = Nothing Exit Function ERR_CODE: MsgBox Err.Description Set rstmp = Nothing End FunctionPublic Sub Init_DDE() DDE_INST = 0
result = DdeUninitialize(DDE_INST) End If End SubPrivate Function PeriodSub(ByVal period As Long, ByVal offset As Long) As Long On Error GoTo Err_HandleEnd Function
所谓DDE技术,就是动态数据交换技术。也许你很奇怪,这与本文所讨论的内容有什么相干的?且听我慢慢讲来。 为了实现拒绝运行并把已经运行的程序激活并实现各种功能,我们可以先用本文开头提到的方法,检测一下程序有没有被运行过,如果没有,就正常运行,如果已经被运行过,就打通与它的DDE通道,传给它一个(或一些)数据,然后由已经运行的程序对数据进行处理,再去实现各种“意想不到”的功能,这时也许就有人对这你的程序喊:“酷、酷……” 好了,耳听为虚,眼见为实,下面让我们动点真格的。 打开VB,新建一个工程,选择菜单中的“工程->工程1 属性”,把工程名称改为“P1”,把已有的一个窗体的“LinkTopic”属性改为“FormDDE”,把“LinkMode”属性改为“1 - Source”,添加一个PictureBox控件作为DDE执行控件,命名为picDDE。然后添加一个 TextBox控件,命名为“txtInfo”,并把“MultiLine”属性设置为“True”,以便显示多行文本,作为消息显示控件。 最后在窗体代码区输入以下代码: Const COMMANDLINE = "CommandLine=" 注释: 还是为了省事,定义一个常量Private Sub Form_LinkExecute(CmdStr As String, Cancel As Integer) Static lngCount As Long Dim Info As StringInfo = txtInfo.Text 注释: 保留原有信息Select Case CmdStr 注释: CmdStr 是DDE程序传送过来的参数 Case "Max" Me.WindowState = 2 Info = Info + vbNewLine + "窗体已被最大化" Case "ShowTime" Info = Info + vbNewLine + "最后一次运行这个程序的时间是:" + Str(Now) Case "Count" lngCount = lngCount + 1 Info = Info + vbNewLine + "你已经第" + Str(lngCount) + "次重复调用这个程序。" _ + vbNewLine + "但怕您不多给工资,所以只运行了一个 ^_^" End SelectIf Left(CmdStr, Len(COMMANDLINE)) = COMMANDLINE Then Info = Info + vbNewLine + "新程序曾以命令行形式运行" + vbNewLine + "命令行为:" _ + vbNewLine + Right(CmdStr, Len(CmdStr) - Len(COMMANDLINE)) End IftxtInfo.Text = Info 注释: 把信息显示出来Cancel = False End Sub Private Sub LinkAndSendMessage(ByVal Msg As String) Dim t As Long picDDE.LinkMode = 0 注释:-- picDDE.LinkTopic = "P1|FormDDE" 注释: |______连接DDE程序并发送数据/参数 picDDE.LinkMode = 2 注释: | “|”为管道符,是“退格键”旁边的竖线, picDDE.LinkExecute Msg 注释:-- 不是字母或数字! t = picDDE.LinkTimeout 注释:-- picDDE.LinkTimeout = 1 注释: |______终止DDE通道。当然,也可以用别的方法 picDDE.LinkMode = 0 注释: | 这里用的是超时强制终止的方法 picDDE.LinkTimeout = t 注释:-- End Sub Private Sub Form_Load() If App.PrevInstance Then 注释: 程序是否已经运行Me.LinkTopic = "" 注释: 这两行用于清除新运行的程序的DDE服务器属性, Me.LinkMode = 0 注释: 否则在连接DDE程序时会出乱子的LinkAndSendMessage "Max" 注释:-- LinkAndSendMessage "Count" 注释: |-----连接DDE接受程序并传送数据/参数 LinkAndSendMessage "ShowTime" 注释:--If Command <> "" Then 注释: 如果有命令行参数,就传递过去 LinkAndSendMessage COMMANDLINE + Command End If End 注释: 结束新程序的运行 End If End Sub 测试一下: 把工程“P1”编译成EXE文件(设名称为 P1.EXE ) 1、打开“我的电脑”,找到 P1.EXE 并执行。可以看到程序正常运行了。 2、再运行一次,这次新程序没有运行成功,而原来运行的程序却被最大化了,而且文本框中有以下字符: 窗体已被最大化 你已经第 1次重复调用这个程序 但怕您不多给工资,所以只运行了一个 。 最后一次运行这个程序的时间是:05-2-6 7:11:01 3、打开 MS-DOS方式 ,用命令行方式再次运行程序,如 “P1 How Are You?”,这时原来运行的程序文本框中又多了几行字: 窗体已被最大化 你已经第 2次重复调用这个程序。 但怕您不多给工资,所以只运行了一个 最后一次运行这个程序的时间是:05-2-6 7:14:32 新程序曾以命令行形式运行 命令行为: How Are You? OK,运行完全正确,然后你就可以把它应用的你的程序中了。
比如:a.exe运行过程中要调用 b.exe程序,但要告诉B从哪里开始运行,B从A处得到数据,再判断数据,就知道怎么运行了
还有就是在程序快捷方式后面加参数运行,你看Windows优化大师,QQ,等好多程序的快捷方式都可以加参数以启动不同的功能该怎么用 我也只知道设置哪LinkMode、LinkTopic属性,你看哪个实例嘛,一句一句的研究嘛,很容易懂的,再自己写个简单的就OK了,慢慢来
建一个工程名叫:DDESOURCE,FORM1的LINKMODE属性设为:1-source; LINKTOPIC属性设为:FORM1
上面放一个TEXT控件,名为:TEXT1
编译成EXE,运行之.再建一个工程:FORM1上放一个LABEL控件:
在FORM_LOAD 事件中写代码:
Private Sub Form_Load()
Label1.LinkTopic = "DDESOURCE|FORM1"
Label1.LinkItem = "TEXT1"
Label1.LinkMode = 1 'AUTO
End Sub编译成EXE,运行之.你可以看到LABEL1上显示的就是DDESOURCE的TEXT1上的内容了,并且你更改TEXT1中的内容,第二个程序上的LABEL1上的内容也会同步更改.一定要先运行第一个工程,否则第二个工程运行时会找不到数据源报错
Public Declare Function DdeCreateDataHandle Lib "user32" (ByVal idInst As Long, pSrc As Byte, ByVal cb As Long, ByVal cbOff As Long, ByVal hszItem As Long, ByVal wFmt As Long, ByVal afCmd As Long) As Long
Public Declare Function DdeCreateStringHandle Lib "user32" Alias "DdeCreateStringHandleA" (ByVal idInst As Long, ByVal psz As String, ByVal iCodePage As Long) As Long
Public Declare Function DdeUninitialize Lib "user32" (ByVal idInst As Long) As Long
Public Declare Function DdeInitialize Lib "user32" Alias "DdeInitializeA" (pidInst As Long, ByVal pfnCallback As Long, ByVal afCmd As Long, ByVal ulRes As Long) As Integer
Public Declare Function DdeNameService Lib "user32" (ByVal idInst As Long, ByVal hsz1 As Long, ByVal hsz2 As Long, ByVal afCmd As Long) As Long
Public Declare Function DdeCmpStringHandles Lib "user32" (ByVal hsz1 As Long, ByVal hsz2 As Long) As Long
Public Declare Function DdeQueryString Lib "user32" Alias "DdeQueryStringA" (ByVal idInst As Long, ByVal hsz As Long, ByVal psz As String, ByVal cchMax As Long, ByVal iCodePage As Long) As Long
Public Declare Function DdeFreeStringHandle Lib "user32" (ByVal idInst As Long, ByVal hsz As Long) As Long
Public Declare Function DdeFreeDataHandle Lib "user32" (ByVal hdata As Long) As LongPublic Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Public Const CF_TEXT = 1Public Const DNS_REGISTER = &H1
Public Const DNS_UNREGISTER = &H2Public Const XTYPF_NOBLOCK = &H2 ' CBR_BLOCK will not workPublic Const APPCLASS_STANDARD = &H0&Public Const CP_WINANSI = 1004 ' default codepage for windows old DDE convs.Public Const DMLERR_NO_ERROR = 0 ' must be 0
Public Const DMLERR_LOW_MEMORY = &H4007Public Const XCLASS_BOOL = &H1000
Public Const XCLASS_DATA = &H2000Public Const XCLASS_NOTIFICATION = &H8000
Public Const XTYP_DISCONNECT = (&HC0 Or XCLASS_NOTIFICATION Or XTYPF_NOBLOCK)
Public Const XTYP_UNREGISTER = (&HD0 Or XCLASS_NOTIFICATION Or XTYPF_NOBLOCK)
Public Const XTYP_CONNECT = (&H60 Or XCLASS_BOOL Or XTYPF_NOBLOCK)
Public Const XTYP_REQUEST = (&HB0 Or XCLASS_DATA)
Public DDE_SERVICESRV As Long
Public DDE_TOPICSRV As Long
Public DDE_TOPICACC As LongPublic DDE_INST As LongPublic DDE_ITEMSRVDS As Long
Public DDE_ITEMSRVSRV As Long
Public DDE_ITEMSRVUSER As Long
Public DDE_ITEMSRVPWD As LongPublic Const TOPIC_ACC = "Acc"
Public Const SERVICE_SRV = "KAL"
Public Const TOPIC_SRV = "System"Public Const ITEM_SRV_DS = "DS"
Public Const ITEM_SRV_USER = "USER"
Public Const ITEM_SRV_SRV = "SRV"
Public Const ITEM_SRV_PWD = "PWD"Public bData As Byte
Public bCompInfo As Byte
Public Function DDECallBack(ByVal uType As Long, ByVal uFmt As Long, ByVal hConv As Long, ByVal hsz1 As Long, ByVal hsz2 As Long, ByVal data As Long, ByVal data1 As Long, ByVal data2 As Long) As Long
On Error GoTo ERR_CODE
Dim accdat As String * 20
Dim Load_Buf As String * 256
Dim i As Integer
Dim straccdat As String
Dim p As String
Dim strSql As String
Dim period_offset As Long, period_to As Long, period_before As Long
Dim rstmp As ADODB.Recordset
Select Case uType
Case XTYP_CONNECT
DDECallBack = True
Case XTYP_UNREGISTER
DDECallBack = True
Case XTYP_REQUEST
If Not DdeCmpStringHandles(hsz1, DDE_TOPICACC) Then
DdeQueryString DDE_INST, hsz2, accdat, 15, CP_WINANSI
For i = 1 To Len(accdat)
If Mid$(accdat, i, 1) = Chr$(0) Then
Exit For
End If
straccdat = straccdat & Mid$(accdat, i, 1)
Next i
If StrComp(Mid$(straccdat, 1, 4), "DATE", vbTextCompare) = 0 Then
strSql = "SELECT " & straccdat & " FROM FINSTMT"
end if
Set rstmp = New ADODB.Recordset
rstmp.Open strSql, ConGamma
If Not (rstmp.EOF And rstmp.BOF) Then
accdat = rstmp.Fields(0) & Chr$(0)
Else
accdat = "0" & Chr$(0)
End If
rstmp.Close
Set rstmp = Nothing
CopyMemory bData, ByVal accdat, Len(accdat)
DDECallBack = DdeCreateDataHandle(DDE_INST, bData, Len(accdat), 0, DDE_TOPICACC, CF_TEXT, 0)
Exit Function
End If
p = Mid$(straccdat, 2, 1)
If IsNumeric(Mid$(p, 1, 1)) Then
period_offset = Val(p)
Else
period_offset = Asc(p) - Asc("a") + 10
End If
Set rstmp = New ADODB.Recordset
If UserInfo.CompanyCode <> "" Then
rstmp.Open "select min(P2) from FINSTMT WHERE COMPCODE='" & UserInfo.CompanyCode & "'", ConGamma
Else
rstmp.Open "select min(P2) from FINSTMT", ConGamma
End If
If Not IsNull(rstmp.Fields(0)) Then
period_to = rstmp.Fields(0)
period_before = PeriodSub(period_to, period_offset)
End If
rstmp.Close
Set rstmp = Nothing
Select Case LCase$(Mid$(straccdat, 1, 1))
Case "c"
Case "u"
Case "a"
Case "q"
Case "w"
strSql = "select round(sum(isnull(CR,0)),2) from FINSTMT where PARENT='" & UCase$(Trim$(Right$(straccdat, Len(straccdat) - 2))) & "' and PERIOD=" & period_before
End Select
CopyMemory bData, ByVal accdat, Len(accdat)
DDECallBack = DdeCreateDataHandle(DDE_INST, bData, Len(accdat), 0, DDE_TOPICACC, CF_TEXT, 0)
Exit Function
If Not DdeCmpStringHandles(hsz1, DDE_TOPICSRV) Then
DdeQueryString DDE_INST, hsz2, accdat, 15, CP_WINANSI
If DdeCmpStringHandles(hsz2, DDE_ITEMSRVDS) = 0 Then
accdat = Trim$(UserInfo.DBName) & Chr$(0)
CopyMemory bData, ByVal accdat, Len(accdat)
data = DdeCreateDataHandle(DDE_INST, bData, Len(accdat), 0, DDE_TOPICSRV, CF_TEXT, 0)
ElseIf DdeCmpStringHandles(hsz2, DDE_ITEMSRVSRV) = 0 Then
accdat = Trim$(UserInfo.DBServer) & Chr$(0)
CopyMemory bData, ByVal accdat, Len(accdat)
data = DdeCreateDataHandle(DDE_INST, bData, Len(accdat), 0, DDE_TOPICSRV, CF_TEXT, 0)
ElseIf DdeCmpStringHandles(hsz2, DDE_ITEMSRVUSER) = 0 Then
accdat = UserInfo.userName & Chr$(0)
CopyMemory bData, ByVal accdat, Len(accdat)
data = DdeCreateDataHandle(DDE_INST, bData, Len(accdat), 0, DDE_TOPICSRV, CF_TEXT, 0)
ElseIf DdeCmpStringHandles(hsz2, DDE_ITEMSRVPWD) = 0 Then
accdat = "caladus" & Chr$(0)
CopyMemory bData, ByVal accdat, Len(accdat)
data = DdeCreateDataHandle(DDE_INST, bData, Len(accdat), 0, DDE_TOPICSRV, CF_TEXT, 0)
ElseIf UCase$(Mid$(accdat, 1, 2)) = "CO" Then
Load_Buf = strCompanyName & Chr$(0)
CopyMemory bCompInfo, ByVal Load_Buf, Len(Load_Buf)
DDECallBack = DdeCreateDataHandle(DDE_INST, bCompInfo, Len(Load_Buf), 0, DDE_TOPICSRV, CF_TEXT, 0)
Exit Function
Else
DdeQueryString DDE_INST, hsz2, Load_Buf, Len(Load_Buf), CP_WINANSI
If UCase$(Mid$(Load_Buf, 1, 4)) = "CURR" Then
If UserInfo.CompanyCode <> "" Then
strSql = "select CURR from COMPANYINFO WHERE COMPCODE='" & UserInfo.CompanyCode & "'"
Else
strSql = "select CURR from COMPANYINFO"
End If
Set rstmp = New ADODB.Recordset
rstmp.Open strSql, ConGamma
Load_Buf = Trim$(rstmp.Fields(0)) & Chr$(0)
rstmp.Close
Set rstmp = Nothing
CopyMemory bData, ByVal Load_Buf, Len(Load_Buf)
data = DdeCreateDataHandle(DDE_INST, bData, Len(Load_Buf), 0, DDE_TOPICSRV, CF_TEXT, 0)
End If
End If
DDECallBack = data
End If
End If
End Select
Set rstmp = Nothing
Exit Function
ERR_CODE:
MsgBox Err.Description
Set rstmp = Nothing
End FunctionPublic Sub Init_DDE()
DDE_INST = 0
If DdeInitialize(DDE_INST, AddressOf DDECallBack, APPCLASS_STANDARD, 0) <> DMLERR_NO_ERROR Then
MsgBox "DDEªì©l¤Æ¿ù»~,­«·s¸ü¤J!", vbExclamation, "¿ù»~"
Else
DDE_TOPICSRV = DdeCreateStringHandle(DDE_INST, TOPIC_SRV, CP_WINANSI)
DDE_SERVICESRV = DdeCreateStringHandle(DDE_INST, SERVICE_SRV, CP_WINANSI)
DdeNameService DDE_INST, DDE_SERVICESRV, 0, DNS_REGISTER
DDE_TOPICACC = DdeCreateStringHandle(DDE_INST, TOPIC_ACC, CP_WINANSI)
DDE_ITEMSRVDS = DdeCreateStringHandle(DDE_INST, ITEM_SRV_DS, CP_WINANSI)
DDE_ITEMSRVUSER = DdeCreateStringHandle(DDE_INST, ITEM_SRV_USER, CP_WINANSI)
DDE_ITEMSRVSRV = DdeCreateStringHandle(DDE_INST, ITEM_SRV_SRV, CP_WINANSI)
DDE_ITEMSRVPWD = DdeCreateStringHandle(DDE_INST, ITEM_SRV_PWD, CP_WINANSI)
End If
End SubPublic Sub Free_DDE()
Dim result As Boolean
If DDE_INST <> 0 Then
DdeNameService DDE_INST, DDE_SERVICESRV, 0, DNS_UNREGISTER
DdeFreeStringHandle DDE_INST, DDE_SERVICESRV
DdeFreeStringHandle DDE_INST, DDE_TOPICSRV
DdeFreeStringHandle DDE_INST, DDE_TOPICACC
DdeFreeStringHandle DDE_INST, DDE_ITEMSRVDS
DdeFreeStringHandle DDE_INST, DDE_ITEMSRVUSER
DdeFreeStringHandle DDE_INST, DDE_ITEMSRVSRV
DdeFreeStringHandle DDE_INST, DDE_ITEMSRVPWD
result = DdeUninitialize(DDE_INST)
End If
End SubPrivate Function PeriodSub(ByVal period As Long, ByVal offset As Long) As Long
On Error GoTo Err_HandleEnd Function
Const COMMANDLINE = "CommandLine=" 注释: 还是为了省事,定义一个常量Private Sub Form_LinkExecute(CmdStr As String, Cancel As Integer)
Static lngCount As Long
Dim Info As StringInfo = txtInfo.Text 注释: 保留原有信息Select Case CmdStr 注释: CmdStr 是DDE程序传送过来的参数
Case "Max"
Me.WindowState = 2
Info = Info + vbNewLine + "窗体已被最大化"
Case "ShowTime"
Info = Info + vbNewLine + "最后一次运行这个程序的时间是:" + Str(Now)
Case "Count"
lngCount = lngCount + 1
Info = Info + vbNewLine + "你已经第" + Str(lngCount) + "次重复调用这个程序。" _
+ vbNewLine + "但怕您不多给工资,所以只运行了一个 ^_^"
End SelectIf Left(CmdStr, Len(COMMANDLINE)) = COMMANDLINE Then
Info = Info + vbNewLine + "新程序曾以命令行形式运行" + vbNewLine + "命令行为:" _
+ vbNewLine + Right(CmdStr, Len(CmdStr) - Len(COMMANDLINE))
End IftxtInfo.Text = Info 注释: 把信息显示出来Cancel = False End Sub
Private Sub LinkAndSendMessage(ByVal Msg As String)
Dim t As Long
picDDE.LinkMode = 0 注释:--
picDDE.LinkTopic = "P1|FormDDE" 注释: |______连接DDE程序并发送数据/参数
picDDE.LinkMode = 2 注释: | “|”为管道符,是“退格键”旁边的竖线,
picDDE.LinkExecute Msg 注释:-- 不是字母或数字! t = picDDE.LinkTimeout 注释:--
picDDE.LinkTimeout = 1 注释: |______终止DDE通道。当然,也可以用别的方法
picDDE.LinkMode = 0 注释: | 这里用的是超时强制终止的方法
picDDE.LinkTimeout = t 注释:--
End Sub
Private Sub Form_Load()
If App.PrevInstance Then 注释: 程序是否已经运行Me.LinkTopic = "" 注释: 这两行用于清除新运行的程序的DDE服务器属性,
Me.LinkMode = 0 注释: 否则在连接DDE程序时会出乱子的LinkAndSendMessage "Max" 注释:--
LinkAndSendMessage "Count" 注释: |-----连接DDE接受程序并传送数据/参数
LinkAndSendMessage "ShowTime" 注释:--If Command <> "" Then 注释: 如果有命令行参数,就传递过去
LinkAndSendMessage COMMANDLINE + Command
End If
End 注释: 结束新程序的运行
End If
End Sub 测试一下: 把工程“P1”编译成EXE文件(设名称为 P1.EXE ) 1、打开“我的电脑”,找到 P1.EXE 并执行。可以看到程序正常运行了。 2、再运行一次,这次新程序没有运行成功,而原来运行的程序却被最大化了,而且文本框中有以下字符: 窗体已被最大化
你已经第 1次重复调用这个程序 但怕您不多给工资,所以只运行了一个 。 最后一次运行这个程序的时间是:05-2-6 7:11:01 3、打开 MS-DOS方式 ,用命令行方式再次运行程序,如 “P1 How Are You?”,这时原来运行的程序文本框中又多了几行字: 窗体已被最大化
你已经第 2次重复调用这个程序。
但怕您不多给工资,所以只运行了一个
最后一次运行这个程序的时间是:05-2-6 7:14:32 新程序曾以命令行形式运行 命令行为: How Are You? OK,运行完全正确,然后你就可以把它应用的你的程序中了。
例子,就是用API处理.
你把完整的例子贴出来好么?我看我能不能明白.