c# Pinvoke无法在List count第一次为0后找到控件的Hwnd

本文关键字:控件 Hwnd 第一次 Pinvoke count List | 更新日期: 2023-09-27 18:05:52

我正在尝试单击另一个应用程序中的按钮(从我的程序中启动Process.Start)

问题:我需要等到加载屏幕消失,GUI弹出…

我的想法是读取所有(Hwnd)控件,直到从GUI找到特定控件(按钮:"杀死客户端")(=GUI打开)。

但这只有在我手动等待GUI并按下"搜索控制"按钮时才有效。

如果我按下"搜索按钮",如果加载屏幕是活跃的,我得到一个Hwnd = 0(列表<'IntPtr>计数也是0…),如果我再次按下它,如果GUI打开它是0再次(列表<'IntPtr>计数太…)!!

这里是我的代码:

 public class WndSearcher
 {
    [DllImport("user32")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
    public static List<IntPtr> GetChildWindows(IntPtr parent)
    {
        List<IntPtr> result = new List<IntPtr>();
        GCHandle listHandle = GCHandle.Alloc(result);
        try
        {
            EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
            EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
        }
        finally
        {
            if (listHandle.IsAllocated)
                listHandle.Free();
        }
        return result;
    }
    private static bool EnumWindow(IntPtr handle, IntPtr pointer)
    {
        GCHandle gch = GCHandle.FromIntPtr(pointer);
        List<IntPtr> list = gch.Target as List<IntPtr>;
        if (list == null)
        {
            throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
        }
        list.Add(handle);
        return true;
    }
}

按钮:

List<IntPtr> AllControlHandles = WndSearcher.GetChildWindows(selectedCharacter.Botprocess.MainWindowHandle);
IntPtr ControlHandle = AllControlHandles.Find(x => PInvoke.GetWindowTextRaw(x) == "Kill Client" ? true : false);
MessageBox.Show(ControlHandle.ToString());

PInvoke (Class)部分:

const int WM_GETTEXT = 0x000D;
const int WM_GETTEXTLENGTH = 0x000E;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, [Out] StringBuilder lParam);
public static string GetWindowTextRaw(IntPtr hwnd)
    {
        // Allocate correct string length first
        int length = (int)SendMessage(hwnd, WM_GETTEXTLENGTH, IntPtr.Zero, null);
        StringBuilder sb = new StringBuilder(length + 1);
        SendMessage(hwnd, WM_GETTEXT, (IntPtr)sb.Capacity, sb);
        return sb.ToString();
    }

c# Pinvoke无法在List count第一次为0后找到控件的Hwnd

至今没有找到解决办法。

所以我决定将AutoHotKey与c#结合使用。

在c#中,我启动AutoHotKey脚本并等待脚本完成。(然后外部程序完全启动)

起始参数:Processid 2。NewExternalProgramName

这是我的AutoHotKey脚本:
counter := 0
Loop, %0%  ; For each parameter:
{
    param := %A_Index%
    if (counter = 0) ; do sth with parameter 1
        winwait, ahk_pid %param% ; Not logged in ;wait until the text "Not logged in" can be read (Program started completely)
    if (counter = 1) ; do sth with parameter 2
        WinSetTitle, %param%
    counter += 1
}