基本上,我编写了一些代码,用于监听应用程序内弹出的“另存为”对话框,当它弹出时,它会按下“保存”,所有这些都是通过代码实现的。这很好用,但是我需要能够在保存之前将文件路径设置为我想要的路径。
到目前为止,这是我的代码:
using System;
using System.Diagnostics;
using System.ComponentModel;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using HWND = System.IntPtr;
using System.Text;
/// <summary>Contains functionality to get all the open windows.</summary>
public static class OpenWindowGetter
{
private const int BN_CLICKED = 245;
/// <summary>Returns a dictionary that contains the handle and title of all the open windows.</summary>
/// <returns>A dictionary that contains the handle and title of all the open windows.</returns>
public static IDictionary<HWND, string> GetOpenWindows()
{
HWND shellWindow = GetShellWindow();
Dictionary<HWND, string> windows = new Dictionary<HWND, string>();
EnumWindows(delegate (HWND hWnd, int lParam)
{
if (hWnd == shellWindow) return true;
if (!IsWindowVisible(hWnd)) return true;
int length = GetWindowTextLength(hWnd);
if (length == 0) return true;
StringBuilder builder = new StringBuilder(length);
GetWindowText(hWnd, builder, length + 1);
if (builder.ToString() == "Export Selection") //Check for the export selection window
{
//Press the "save" button through code here
IntPtr hwndChild = FindWindowEx((IntPtr)hWnd, IntPtr.Zero, "Button", "&Save");
SendMessage((HWND)(int)hwndChild, BN_CLICKED, (HWND)0, IntPtr.Zero);
}
windows[hWnd] = builder.ToString();
return true;
}, 0);
return windows;
}
private delegate bool EnumWindowsProc(HWND hWnd, int lParam);
[DllImport("USER32.DLL")]
private static extern int SetWindowText(HWND hWnd, String lpString);
[DllImport("USER32.DLL")]
private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);
[DllImport("USER32.DLL")]
private static extern int GetWindowText(HWND hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("USER32.DLL")]
private static extern int GetWindowTextLength(HWND hWnd);
[DllImport("USER32.DLL")]
private static extern bool IsWindowVisible(HWND hWnd);
[DllImport("USER32.DLL")]
private static extern IntPtr GetShellWindow();
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);
[DllImport("User32.dll")]
public static extern Int32 SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
}
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
while (true)
{
foreach (KeyValuePair<IntPtr, string> window in OpenWindowGetter.GetOpenWindows())
{
IntPtr handle = window.Key;
string title = window.Value;
//Console.WriteLine("{0}: {1}", handle, title);
}
}
}
}
}
我一直在使用 FindWindowEx 和 SendMessage 来控制窗口句柄。这对于“保存”按钮非常有效,但现在我尝试访问窗口的工具栏部分并将其文本设置到所需的目录。我什至不确定这种方法是否有效,但这似乎是最简单的。我附上了一张屏幕截图以供参考(红色圆圈区域是我在“按”保存之前尝试访问并更改为给定文件路径的句柄)
如图所示,我一直在使用 Spy++ 来获取有关窗口及其句柄的信息。例如,如果我尝试这样做来获取指向该句柄的指针:
IntPtr hwndChildToolbar= FindWindowEx((IntPtr)hWnd, IntPtr.Zero, "ToolbarWindow32", "Address: "+"C:\\Windows\\System32");
这不起作用。 Spy++ 应用程序中看到的“Caption”值会更改为当前目录名称,因此尝试访问它似乎没有意义。
下一行代码确实给了我一个返回的指针,但它不是正确的地址。值得注意的是,该窗口上有多个属于 ToolbarWindow32 类的句柄:
IntPtr hwndChildToolbar= FindWindowEx((IntPtr)hWnd, IntPtr.Zero, "ToolbarWindow32", null);
如果我能找到一种方法来获取正确的句柄,那么从这里我只想使用 SetWindowText(如果可能)并将其值设置为我想要的文件路径的字符串。
总而言之,我需要某种方法来轻松设置目录,并且我不确定这种方法是否可行。我的 C# 知识有限,所以一切都有帮助!