【问题标题】:Click save button and input filename with Windows API in VBA单击保存按钮并在 VBA 中使用 Windows API 输入文件名
【发布时间】:2021-01-10 10:01:17
【问题描述】:

我为这个主题搜索了很多,但我没有找到解决方案。

我正在使用 IE 登录一个网站,在某些时候有一个print dialogbox,我需要点击打印按钮,然后点击随后的“保存按钮”;另外我需要为保存添加pdf文件名。

我解决了单击打印按钮的问题:

Private Declare PtrSafe Function FindWindow Lib "User32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare PtrSafe 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 SendMessage Lib "User32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Sub ClickPrintButtonWindowsAPI()
    Dim hw As Long, op As Long
    hw = FindWindow(vbNullString, "Print")
    op = FindWindowEx(hw, 0&, "Button", vbNullString)
    Call SendMessage(op, BM_CLICK, 0, 0)
End Sub

但是会打开一个新窗口,要求输入文件名和保存按钮。

  • 打印机是“Microsoft Print to PDF”,因此输出将是 PDF 文件。

** 我已经下载了 spy++,但我没有使用它的经验。经过多次尝试,我可以在对话框中选择file name 字段,这是一个快照

现在我尝试了这样的行

Dim hw1 As Long
hw1 = FindWindow(vbNullString, "Save Print Output As")
Dim hw2 As Long, hw3 As Long
hw2 = FindWindowEx(hw1, 0&, "DUIViewWndClassName", vbNullString)
Dim hw4 As Long, hw5 As Long, hw6 As Long
hw3 = FindWindowEx(hw2, 0&, "DirectUIHWND", vbNullString)
hw4 = FindWindowEx(hw3, 0&, "FloatNotifySink", vbNullString)
hw5 = FindWindowEx(hw4, 0&, "ComboBox", vbNullString)
hw6 = FindWindowEx(hw5, 0&, "Edit", vbNullString)
Call SendMessageByString(hw6, &HC, 0, "Sample Text")
Dim sv As Long
sv = FindWindowEx(hw2, 0&, "Save", vbNullString)
Call SendMessage(sv, BM_CLICK, 0, 0)

一个问题:有没有办法让这样的地图更简单?

我现在无法单击Save 按钮并输入文件名。你能帮我解决这个问题吗?

【问题讨论】:

  • 嗨!你试过什么?例如,您是否查看过 FindWindow API?我想,曾几何时,我为您指出了一个关于使用它们与对话框进行交互的示例here
  • 是的,我看过了。但事实上我完全迷失在这方面。如何指定窗口然后指定Print 按钮然后最后单击它?也许对你来说很简单,但对我来说,我在 Windows API 方面很弱。
  • 我找到了一个可以让我点击打印按钮的代码。你能看看更新的问题吗?
  • 你有什么理由避免UI Automation
  • 使用等待功能不可靠,应使用WinEvents获取对话框创建事件,使用UIAutomation自动点击保存按钮。检查此similar question 并回答

标签: excel vba winapi


【解决方案1】:

这是我的最终解决方案,但我欢迎任何想法

Private Declare PtrSafe Function FindWindow Lib "User32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare PtrSafe 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 SendMessage Lib "User32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare PtrSafe Function SendMessageByString Lib "User32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam 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

Sub ClickPrintButtonWindowsAPI()
    Dim hw As Long, op As Long
    hw = FindWindow(vbNullString, "Print")
    op = FindWindowEx(hw, 0&, "Button", vbNullString)
    Call SendMessage(op, BM_CLICK, 0, 0)
    
    Dim hw1 As Long
    hw1 = FindWindow(vbNullString, "Save Print Output As")
    Dim hw2 As Long, hw3 As Long
    hw2 = FindWindowEx(hw1, 0&, "DUIViewWndClassName", vbNullString)
    Dim hw4 As Long, hw5 As Long, hw6 As Long
    hw3 = FindWindowEx(hw2, 0&, "DirectUIHWND", vbNullString)
    hw4 = FindWindowEx(hw3, 0&, "FloatNotifySink", vbNullString)
    hw5 = FindWindowEx(hw4, 0&, "ComboBox", vbNullString)
    hw6 = FindWindowEx(hw5, 0&, "Edit", vbNullString)
    Call SendMessageByString(hw6, &HC, 0, "Sample Text")
    Dim sv As Long
    sv = FindWindowEx(hw1, 0, "Button", "&Save")
    Call SendMessage(sv, BM_CLICK, 0, 0)
End Sub

【讨论】:

  • 这仅在我使用 F8 逐步运行代码时才有效。有什么想法吗?
  • F8解决问题通常是什么意思?
  • 我想我必须排队等候.. 也许吧!
  • ^^bingo... 或需要满足的某些条件。条件通常比硬编码的等待时间更可靠。值得一提的是 F5/Run 时哪个阶段失败。
  • 在使用 UI 自动化或任何使用 winAPI/AA/UIAutomation 等的点击自动化时,关键概念是等待元素出现在屏幕上。您应该将“等待元素”功能设置为标准
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
  • 2021-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多