Dostęp do combobox w zewnętrznej aplikacji.

0

Cześć! Będę bardzo wdzięczny za wskazówki jak dobrać się do mojego problemu,
Szczerze mówiąc to nie wiedziałem nawet jak wpisać zapytanie w google aby znaleźć to zagadnienie,

Już tłumaczę o co chodzi:
Potrzebuję zaznaczyć konkretną opcję z rozwijanej listy combobox w zewnętrznej aplikacji.

Flow wygląda tak:

  • uruchom aplikację X
  • po uruchomieniu aplikacja w osobnym oknie pyta o opcję z listy
    title

tu chciałbym wykryć wypisane opcje i zaznaczyć właściwą po czym zatwierdzić...

0

Napisz bota, która kliknie :) Np. Selenium ?

0

Wpisz w google: "c# click button another application".

1

Dzięki za porady
**sharper_99 **- boty, macra, skrypty odpadają, muszę mieć to zaimplementowane w projekcie c#
**Dyzma **- dzięki za wskazówkę, tak już szukałem.

Może pokaże do czego udało mi się dotrzeć:

definicja zmiennych i podstawowych funkcji z których korzystam dalej:

private int hwnd = 0;
private IntPtr hwndChildOK = IntPtr.Zero;
private IntPtr hwndChildCancel = IntPtr.Zero;
private IntPtr hwndChildCombo = IntPtr.Zero;
private const int WM_CLOSE = 16;
private const int BN_CLICKED = 245;

[DllImport("User32.dll")]
public static extern Int32 FindWindow(String lpClassName, String lpWindowName);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(int hWnd, int msg, int wParam, IntPtr lParam);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);

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

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

public static string GetText(IntPtr hWnd)
{
        int length = GetWindowTextLength(hWnd);
        StringBuilder sb = new StringBuilder(length + 1);
        GetWindowText(hWnd, sb, sb.Capacity);
        return sb.ToString();
}

public class WindowHandleInfo
{
        private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr lParam);
        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr lParam);
        private IntPtr _MainHandle;

        public WindowHandleInfo(IntPtr handle)
        {
            this._MainHandle = handle;
        }

        public List<IntPtr> GetAllChildHandles()
        {
            List<IntPtr> childHandles = new List<IntPtr>();

            GCHandle gcChildhandlesList = GCHandle.Alloc(childHandles);
            IntPtr pointerChildHandlesList = GCHandle.ToIntPtr(gcChildhandlesList);

            try
            {
                EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
                EnumChildWindows(this._MainHandle, childProc, pointerChildHandlesList);
            }
            finally
            {
                gcChildhandlesList.Free();
            }

            return childHandles;
        }

        private bool EnumWindow(IntPtr hWnd, IntPtr lParam)
        {
            GCHandle gcChildhandlesList = GCHandle.FromIntPtr(lParam);

            if (gcChildhandlesList == null || gcChildhandlesList.Target == null)
            {
                return false;
            }

            List<IntPtr> childHandles = gcChildhandlesList.Target as List<IntPtr>;
            childHandles.Add(hWnd);

            return true;
        }
    }

znaleźć uchwyt okienka oraz guziki OK i Cancel to nie problem robię to tak:

hwnd = FindWindow(null, "Camera Selection");
hwndChildOK = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "Button", "OK");
hwndChildCancel = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "Button", "Cancel");

klikać po guzikach... też nie problem:

SendMessage((int)hwndChildOK, BN_CLICKED, 0, IntPtr.Zero); //kliknij OK
SendMessage((int)hwndChildCancel, BN_CLICKED, 0, IntPtr.Zero); //kliknij Cancel

Problem to odnaleźć ComboBox i coś z nim zrobić...
mając handle okienka próbowałem wy-listować wszystkie uchwyty kontrolerek-dzieci:

var allChildWindows = new WindowHandleInfo((IntPtr)hwnd).GetAllChildHandles();
foreach (int i in allChildWindows)
{
        textBox1.Text += "hwnd: [" + i + "] " + GetText((IntPtr)i) + Environment.NewLine;               
}

czego wynikiem jest:

hwnd: [5442228] OK
hwnd: [1706796] Cancel
hwnd: [985776] Please select the camera to connect to from the list below:
hwnd: [1772120] 

i tutaj właśnie utknąłem
czy ten *1772120 * z którego nie da się wyciągnąć opisu to ComboBox jeśli tak to jak wyciągnąć z niego opcje które są wyświetlane na rozwijanej liście (ta kontrola nie ma żadnych "dzieci" pod sobą), jak zaznaczyć wybraną opcję...

Udało mi się dotrzeć jeszcze do GetComboBoxInfo ale opisy są bardzo skąpe i nie wiem jak to zastosować

1

//temat rozwiązany, udało mi się użyć GetComboBoxInfo,
być może komuś jeszcze się przyda:

definicja niezbędnych funkcji

[DllImport("user32.dll")]
public static extern bool GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi);

public static string GetText(IntPtr hWnd)
{
        int length = GetWindowTextLength(hWnd);
        StringBuilder sb = new StringBuilder(length + 1);
        GetWindowText(hWnd, sb, sb.Capacity);
        return sb.ToString();
}

public struct COMBOBOXINFO
{
        public int cbSize;
        public RECT rcItem;
        public RECT rcButton;
        public int stateButton;
        public IntPtr hwndCombo;
        public IntPtr hwndEdit;
        public IntPtr hwndList;
}

public struct RECT
{
        public int left;
        public int top;
        public int right;
        public int bottom;
}

private const int CB_SETCURSEL = 0x014E;
private void SetSelectedIndex(IntPtr comboBoxHandle, int index)
{
        SendMessage(comboBoxHandle, CB_SETCURSEL, index, 0);
}

no i do tego połączenie wcześniejszych opcji:

private void SelectCamera(int nrCamera)
{
        hwnd = FindWindow(null, "Camera Selection");
        hwndChildOK = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "Button", "OK");
        hwndChildCancel = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "Button", "Cancel");

        if (hwnd != 0)
        {
                foreach (int i in new WindowHandleInfo((IntPtr)hwnd).GetAllChildHandles())
                {
                    if (GetText((IntPtr)i) == "")
                    {
                        hwndChildCombo = (IntPtr)i;
                    }
                }

                COMBOBOXINFO info = new COMBOBOXINFO();
                info.cbSize = Marshal.SizeOf(info);

                if (GetComboBoxInfo(hwndChildCombo, ref info))
                {
                    SetSelectedIndex(info.hwndCombo, nrCamera);
                    SendMessage((int)hwndChildOK, BN_CLICKED, 0, IntPtr.Zero);
                }
            }
            else
            {
                textBox1.Text += "brak okna wyboru aparatu" + Environment.NewLine;
            }
        }

dzięki temu można wywołać funkcję:

SelectCamera(1); //wybierz drugi z listy

1 użytkowników online, w tym zalogowanych: 0, gości: 1