[英]C# Pinvoke can't find the Hwnd of Controls after List count was 0 at first time
I'm trying to click a Button in another Application (started from my Programm with Process.Start) 我试图单击另一个应用程序中的按钮(从我的Programm中以Process.Start开始)
The problem: I need to wait until the Loading screen is disappeared and the GUI pop's up... 问题:我需要等到“加载”屏幕消失并且GUI弹出窗口出现...
My idea was to read all (Hwnd)Controls until a specific Control (Button: "Kill Client") from the GUI was found (=GUI Opened). 我的想法是读取所有(Hwnd)控件,直到从GUI找到特定控件(按钮:“ Kill Client”)为止(= GUI已打开)。
But this only works if I wait manually for the GUI and press a "Search Control" button. 但这仅在我手动等待GUI并按“搜索控制”按钮时有效。
If I press the "Search Button" if the Loading Screen is aktive I get a Hwnd = 0 (List<'IntPtr> Count is also 0...) and if i press it again if the GUI is opened it is 0 again(List<'IntPtr> Count too...) !!! 如果在加载屏幕处于活动状态时按“搜索按钮”,则会得到Hwnd = 0(List <'IntPtr>计数也为0 ...),如果在打开GUI时再次按该按钮,则它将再次为0( List <'IntPtr>也算...)!!!
Here my Code: 这是我的代码:
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;
}
}
My Button: 我的按钮:
List<IntPtr> AllControlHandles = WndSearcher.GetChildWindows(selectedCharacter.Botprocess.MainWindowHandle);
IntPtr ControlHandle = AllControlHandles.Find(x => PInvoke.GetWindowTextRaw(x) == "Kill Client" ? true : false);
MessageBox.Show(ControlHandle.ToString());
Part of PInvoke (Class): PInvoke(类)的一部分:
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();
}
Found no solution till now. 直到现在都找不到解决方案。
So I decided to use AutoHotKey in combination with C#. 因此,我决定将AutoHotKey与C#结合使用。
In C# I start my AutoHotKey Script and wait until the Script is finished. 在C#中,我启动AutoHotKey脚本,然后等待脚本完成。 (Then the external Programm is started completely)
(然后,外部程序将完全启动)
Starting Arguments: 1.Processid 2.NewExternalProgramName 起始参数:1.Processid 2.NewExternalProgramName
Here my AutoHotKey Script: 这是我的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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.