C#如何等待弹出窗口并选择它进行输入

C#如何等待弹出窗口并选择它进行输入,c#,winforms,macros,ui-automation,user32,C#,Winforms,Macros,Ui Automation,User32,我基本上是在用C#编写一个专门的宏播放器/录音机。我需要能够做的一件事是等待弹出窗口(类似“另存为…”对话框),然后选择该窗口继续播放宏输入。理想情况下,我希望能够轮询打开的窗口,并通过它们的标题搜索匹配的窗口标题。 显然,我不能使用processs.GetProcesses(),因为对话框很可能不会显示为新进程 在哪里可以找到打开的窗口及其标题 我想您需要。如果您想轮询所有打开的窗口,您可以使用。我没有编译这段代码,但它应该非常接近函数 public class ProcessWindows

我基本上是在用C#编写一个专门的宏播放器/录音机。我需要能够做的一件事是等待弹出窗口(类似“另存为…”对话框),然后选择该窗口继续播放宏输入。理想情况下,我希望能够轮询打开的窗口,并通过它们的标题搜索匹配的窗口标题。 显然,我不能使用processs.GetProcesses(),因为对话框很可能不会显示为新进程


在哪里可以找到打开的窗口及其标题

我想您需要。

如果您想轮询所有打开的窗口,您可以使用。我没有编译这段代码,但它应该非常接近函数

public class ProcessWindows
{
    List<Window> visibleWindows = new List<Window>();
    List<IntPtr> allWindows = new List<IntPtr>();

    /// <summary>
    /// Contains information about visible windows.
    /// </summary>
    public struct Window
    {
        public IntPtr Handle { get; set; }
        public string Title { get; set; }
    }

    [DllImport("user32.dll")]
    static extern int EnumWindows(EnumWindowsCallback lpEnumFunc, int lParam);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern void GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

    delegate bool EnumWindowsCallback(IntPtr hwnd, int lParam);

    public ProcessWindows()
    {
        int returnValue = EnumWindows(Callback, 0);
        if (returnValue == 0)
        {
            throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(), "EnumWindows() failed");
        }
    }

    private bool Callback(IntPtr hwnd, int lParam)
    {
        const int WS_BORDER = 0x800000;
        const int WS_VISIBLE = 0x10000000;
        const int GWL_STYLE = (-16);

        // You'll have to figure out which windows you want here...
        int visibleWindow = WS_BORDER | WS_VISIBLE;
        if ((GetWindowLong(hwnd, GWL_STYLE) & visibleWindow) == visibleWindow)
        {
            StringBuilder sb = new StringBuilder(100);
            GetWindowText(hwnd, sb, sb.Capacity);

            this.visibleWindows.Add(new Window()
            {
                Handle = hwnd,
                Title = sb.ToString()
            });
        }

        return true; //continue enumeration
    }

    public ReadOnlyCollection<Window> GetVisibleWindows()
    {
        return this.visibleWindows.AsReadOnly();
    }
}
}
公共类进程窗口
{
List visibleWindows=新建列表();
List allWindows=new List();
/// 
///包含有关可见窗口的信息。
/// 
公共结构窗口
{
公共IntPtr句柄{get;set;}
公共字符串标题{get;set;}
}
[DllImport(“user32.dll”)]
静态外部int EnumWindows(EnumWindows回调lpEnumFunc,int lParam);
[DllImport(“user32.dll”,SetLastError=true,CharSet=CharSet.Auto)]
静态外部intgetWindowLong(IntPtr hWnd,intnindex);
[DllImport(“user32.dll”,CharSet=CharSet.Unicode,SetLastError=true)]
私有静态外部void GetWindowText(IntPtr hWnd、StringBuilder lpString、int nMaxCount);
委托bool EnumWindowsCallback(IntPtr hwnd,intlparam);
公共进程Windows()
{
int returnValue=EnumWindows(回调,0);
如果(返回值==0)
{
抛出新的System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(),“EnumWindows()失败”);
}
}
私有bool回调(IntPtr hwnd、intlparam)
{
常量int WS_BORDER=0x800000;
常量int WS_VISIBLE=0x10000000;
常量int GWL_STYLE=(-16);
//你必须弄清楚你想在这里打开哪个窗口。。。
int visibleWindow=WS|u BORDER | WS|u VISIBLE;
if((GetWindowLong(hwnd,GWL_样式)&visibleWindow)==visibleWindow)
{
StringBuilder sb=新StringBuilder(100);
GetWindowText(hwnd、sb、sb容量);
this.visibleWindows.Add(新窗口()
{
Handle=hwnd,
Title=sb.ToString()
});
}
返回true;//继续枚举
}
公共只读集合GetVisibleWindows()
{
返回此.visibleWindows.AsReadOnly();
}
}
}

一条评论,我无法理解您所说的WindowTitle.GetText()是什么意思。我不知道我没有导入什么库,也不知道我遗漏了什么。我使用了另一个user32函数,静态extern int GetWindowText(int-hWnd、StringBuilder-text、int-count);哦,对不起。这是对我的一个应用程序中另一个类的引用。我将编辑我的答案以显示我在做什么…好的,修复了。请注意GetWindowText的新pinvoke语句及其调用,其中WindowTitle.GetText()以前是。(显然,这基本上就是你所做的。)