С# Pinvoke не может найти Hwnd of Controls после того, как счетчик списка был равен 0 в первый раз

Я пытаюсь нажать кнопку в другом приложении (начав с моей программы с помощью Process.Start)

Проблема: мне нужно подождать, пока экран загрузки не исчезнет и не появится всплывающее окно с графическим интерфейсом...

Моя идея заключалась в том, чтобы прочитать все (Hwnd) элементы управления, пока не будет найден определенный элемент управления (кнопка: «Убить клиент») из графического интерфейса (= графический интерфейс открыт).

Но это работает только в том случае, если я вручную жду графический интерфейс и нажимаю кнопку «Управление поиском».

Если я нажимаю кнопку «Поиск», если экран загрузки активен, я получаю Hwnd = 0 (List‹'IntPtr> Count также равен 0...), и если я нажимаю ее снова, если графический интерфейс открыт, он снова равен 0 ( List‹'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 (класс):

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();
    }

person Mikle20    schedule 30.05.2014    source источник
comment
Thread.Sleep() — это очевидный способ ожидания.   -  person Hans Passant    schedule 30.05.2014
comment
вы можете использовать цикл while (пока hwnd = 0, спать в течение нескольких миллисекунд), а затем сразу после этого код, который вы хотите.   -  person Scott Solmer    schedule 30.05.2014
comment
@Scott Я пробовал так, но если список в первый раз Count=0, то он будет каждый раз 0 ... (по этой причине я пробовал это с помощью кнопки, но здесь та же проблема (если я управляю поиском, если экран загрузки активен).   -  person Mikle20    schedule 30.05.2014
comment
@ Ганс, я знаю, но я хочу по-другому :)   -  person Mikle20    schedule 30.05.2014
comment
Ожидается, что вы будете использовать автоматизацию для этого   -  person David Heffernan    schedule 31.05.2014
comment
да. (нужна какая-то функция, которая сообщает мне, когда загрузочный экран закончился)   -  person Mikle20    schedule 31.05.2014


Ответы (1)


Пока решения не нашел.

Поэтому я решил использовать AutoHotKey в сочетании с C#.

В С# я запускаю свой скрипт AutoHotKey и жду, пока скрипт не завершится. (Затем полностью запускается внешняя программа)

Начальные аргументы: 1.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
}
person Mikle20    schedule 16.06.2014