如何使用 vb6 为 "save as" window 提供文件路径
How to give file path to "save as" window using vb6
我正在编写 VB6 代码。
它必须按顺序执行以下操作:
1. 检查 window 是否打开(完成!使用 FindWindows)
2. 按 Ctrl + S(完成!使用 SendKeys("^S")
3. 输入完整路径名(卡在这里!不知道如何继续)
4. 按回车键(完成!使用 SendKeys)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, _
ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
'--------------------------------------------------------
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal lhWndP As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal lhWndP As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function SetForegroundWindow Lib "user32" ( _
ByVal hWnd As Long) _
As Long
Private Const BM_CLICK = &HF5
Private Const WM_CLOSE = &H10
Private Const WM_SETTEXT As Long = &HC
'------------------------------------------------------------
Private Const GW_HWNDNEXT = 2
Private Sub Command1_Click()
Dim lhWndP As Long
Dim lhWndP1 As Long
Dim hWnd1 As Long
Dim hWnd11 As Long
If Dir$("C:\users\public3.txt") <> "" Then
Kill ("C:\users\public3.txt")
End If
If GetHandleFromPartialCaption(lhWndP, "Untitled - Notepad") = True Then
SetForegroundWindow lhWndP
DoEvents
Call VBA.SendKeys("^s")
DoEvents
Call VBA.SendKeys("C:\users\public3.txt") 'This is not working 100%
If GetHandleFromPartialCaption(lhWndP1, "Save As") = True Then
DoEvents
hWnd11 = FindWindowEx(lhWndP1, 0, "Button", "&Save")
If hWnd11 <> 0 Then
Call PostMessage(hWnd11, BM_CLICK, 0, 0)
Else
MsgBox "Button handle not found!"
End If
End If
hWnd11 = FindWindowEx(lhWndP1, 0, "Button", "&Save")
If hWnd11 <> 0 Then
Call PostMessage(hWnd1, BM_CLICK, 0, 0)
Else
MsgBox "Button handle not found!"
End If
End If
End
End Sub
Public Function GetHandleFromPartialCaption(ByRef lWnd As Long, ByVal sCaption As String) As Boolean
Dim lhWndP As Long
Dim sStr As String
GetHandleFromPartialCaption = False
lhWndP = FindWindow(vbNullString, vbNullString) 'PARENT WINDOW
Do While lhWndP <> 0
sStr = String$(GetWindowTextLength(lhWndP) + 1, Chr$(0))
GetWindowText lhWndP, sStr, Len(sStr)
sStr = Left$(sStr, Len(sStr) - 1)
If InStr(1, sStr, sCaption) > 0 Then
GetHandleFromPartialCaption = True
lWnd = lhWndP
Exit Do
End If
lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
Loop
End Function
我尝试了发送消息功能。但是 WM_SETTEXT 将一些垃圾设置到 window 标题而不是文件名字段中。
这个 WM_SETTEXT 有替代品吗?或者其他方法来完成任务?
注意:在这个例子中我使用了记事本。但实际应用使用了第三方window。我没有该应用程序的代码。
问题是您没有等待目标应用程序处理 SendKeys 文本。调用 DoEvents 与等待外部应用程序做某事不同。它允许你的应用程序刷新它的的其余部分事件队列。
如果您需要等待外部应用程序处理,快速而肮脏的方法是添加一个短暂的睡眠。将 API 函数声明为...
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
...然后试试这个:
'...
If GetHandleFromPartialCaption(lhWndP, "Untitled - Notepad") = True Then
SetForegroundWindow lhWndP
Sleep 100
Call VBA.SendKeys("^s")
Sleep 100
Call VBA.SendKeys("C:\users\public3.txt") 'This is not working 100%
If GetHandleFromPartialCaption(lhWndP1, "Save As") = True Then
Sleep 100
hWnd11 = FindWindowEx(lhWndP1, 0, "Button", "&Save")
If hWnd11 <> 0 Then
Call PostMessage(hWnd11, BM_CLICK, 0, 0)
Else
MsgBox "Button handle not found!"
End If
End If
hWnd11 = FindWindowEx(lhWndP1, 0, "Button", "&Save")
If hWnd11 <> 0 Then
Call PostMessage(hWnd1, BM_CLICK, 0, 0)
Else
MsgBox "Button handle not found!"
End If
End If
'...
如果仍然不起作用,请调整睡眠时间直到起作用。
我正在编写 VB6 代码。 它必须按顺序执行以下操作: 1. 检查 window 是否打开(完成!使用 FindWindows) 2. 按 Ctrl + S(完成!使用 SendKeys("^S") 3. 输入完整路径名(卡在这里!不知道如何继续) 4. 按回车键(完成!使用 SendKeys)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, _
ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
'--------------------------------------------------------
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal lhWndP As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal lhWndP As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function SetForegroundWindow Lib "user32" ( _
ByVal hWnd As Long) _
As Long
Private Const BM_CLICK = &HF5
Private Const WM_CLOSE = &H10
Private Const WM_SETTEXT As Long = &HC
'------------------------------------------------------------
Private Const GW_HWNDNEXT = 2
Private Sub Command1_Click()
Dim lhWndP As Long
Dim lhWndP1 As Long
Dim hWnd1 As Long
Dim hWnd11 As Long
If Dir$("C:\users\public3.txt") <> "" Then
Kill ("C:\users\public3.txt")
End If
If GetHandleFromPartialCaption(lhWndP, "Untitled - Notepad") = True Then
SetForegroundWindow lhWndP
DoEvents
Call VBA.SendKeys("^s")
DoEvents
Call VBA.SendKeys("C:\users\public3.txt") 'This is not working 100%
If GetHandleFromPartialCaption(lhWndP1, "Save As") = True Then
DoEvents
hWnd11 = FindWindowEx(lhWndP1, 0, "Button", "&Save")
If hWnd11 <> 0 Then
Call PostMessage(hWnd11, BM_CLICK, 0, 0)
Else
MsgBox "Button handle not found!"
End If
End If
hWnd11 = FindWindowEx(lhWndP1, 0, "Button", "&Save")
If hWnd11 <> 0 Then
Call PostMessage(hWnd1, BM_CLICK, 0, 0)
Else
MsgBox "Button handle not found!"
End If
End If
End
End Sub
Public Function GetHandleFromPartialCaption(ByRef lWnd As Long, ByVal sCaption As String) As Boolean
Dim lhWndP As Long
Dim sStr As String
GetHandleFromPartialCaption = False
lhWndP = FindWindow(vbNullString, vbNullString) 'PARENT WINDOW
Do While lhWndP <> 0
sStr = String$(GetWindowTextLength(lhWndP) + 1, Chr$(0))
GetWindowText lhWndP, sStr, Len(sStr)
sStr = Left$(sStr, Len(sStr) - 1)
If InStr(1, sStr, sCaption) > 0 Then
GetHandleFromPartialCaption = True
lWnd = lhWndP
Exit Do
End If
lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
Loop
End Function
我尝试了发送消息功能。但是 WM_SETTEXT 将一些垃圾设置到 window 标题而不是文件名字段中。
这个 WM_SETTEXT 有替代品吗?或者其他方法来完成任务?
注意:在这个例子中我使用了记事本。但实际应用使用了第三方window。我没有该应用程序的代码。
问题是您没有等待目标应用程序处理 SendKeys 文本。调用 DoEvents 与等待外部应用程序做某事不同。它允许你的应用程序刷新它的的其余部分事件队列。
如果您需要等待外部应用程序处理,快速而肮脏的方法是添加一个短暂的睡眠。将 API 函数声明为...
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
...然后试试这个:
'...
If GetHandleFromPartialCaption(lhWndP, "Untitled - Notepad") = True Then
SetForegroundWindow lhWndP
Sleep 100
Call VBA.SendKeys("^s")
Sleep 100
Call VBA.SendKeys("C:\users\public3.txt") 'This is not working 100%
If GetHandleFromPartialCaption(lhWndP1, "Save As") = True Then
Sleep 100
hWnd11 = FindWindowEx(lhWndP1, 0, "Button", "&Save")
If hWnd11 <> 0 Then
Call PostMessage(hWnd11, BM_CLICK, 0, 0)
Else
MsgBox "Button handle not found!"
End If
End If
hWnd11 = FindWindowEx(lhWndP1, 0, "Button", "&Save")
If hWnd11 <> 0 Then
Call PostMessage(hWnd1, BM_CLICK, 0, 0)
Else
MsgBox "Button handle not found!"
End If
End If
'...
如果仍然不起作用,请调整睡眠时间直到起作用。