如何获取 VBA 消息框的窗口句柄
本文关键字:消息 窗口句柄 VBA 何获取 获取 | 更新日期: 2023-09-27 18:36:36
我在大量 Excel 工作簿上运行 C# 脚本,该脚本涉及在每个工作簿中调用一个宏;由于错误处理程序,宏有时会生成 MsgBox,这会暂停脚本的执行,直到我在 MsgBox 中单击"确定"。
MsgBox 的标题文本是"进程子中的错误",正文是"错误(类型不匹配)"。
我想也许我可以有一个并发线程来查找所有当前打开的窗口,如果它找到 MsgBox,请单击"确定"。 我正在尝试使用类似的东西找到窗口:
using System.Diagnostics;
public Process getErrorWindow()
{
Process[] processList = Process.GetProcesses();
foreach (Process process in processList)
{
if (process.MainWindowTitle=="Error in processSub")
{
return process;
}
}
}
但这什么也找不到。 当我浏览processList[]
时,它似乎只找到主Excel窗口,而不是其VBA代码生成的任何子窗口。 有没有办法找到消息框并单击其"确定"按钮?
您可以使用 winapi 函数 FindWindow 按标题和类检索窗口的句柄。 将以下代码添加到程序中:
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
public static IntPtr FindExcelErrorPopup()
{
return FindWindow(null, "Error in processSub");
}
要单击该按钮:
IntPtr hwnd = FindExcelErrorPopup();
if (hwnd != IntPtr.Zero)
{
SetForegroundWindow(hwnd); // activates the window
SendKeys.SendWait("{ENTER}"); // send ENTER key
}
如果默认按钮不是"确定",请在 ENTER 之前发送一些 TAB 键笔划以选择它。不要忘记为DllImport
放using System.Runtime.InteropServices;
.
编辑:对于远程桌面,请尝试以下本机方法:
[DllImport("user32.dll")]
private static extern void keybd_event(Keys bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
private const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
private const uint KEYEVENTF_KEYUP = 0x0002;
const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
const uint KEYEVENTF_KEYUP = 0x0002;
并像这样举起密钥:
keybd_event(Keys.Enter, 0x45, KEYEVENTF_EXTENDEDKEY, UIntPtr.Zero); // key down
keybd_event(Keys.Enter, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, UIntPtr.Zero); // key up