Laden...

Controls einers anderen Prozesses füllen

Erstellt von TruKasi vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.060 Views
T
TruKasi Themenstarter:in
2 Beiträge seit 2017
vor 4 Jahren
Controls einers anderen Prozesses füllen

Hallo zusammen,

nachdem ich die Forumsuche nun sehr strapaziert habe, muss ich nun doch eine Frage stellen.
Ich möchte (wie einige andere hier auch) ein Formular einer anderen Application füllen.

Das hab ich bereits mit UIAutomation und mit SendMessage probiert. Beides funktioniert, naja so halb...

Wenn ich mir die Handles des Prozesses rekursiv (also auch die Kinder der Kinder usw...) auslesen lassen, bekomme ich ca. 1500 Handles. In diese habe ich testweise einfach mal überall mit SendMessage etwas reingeschrieben. Bei einer Textbox, wird der Wert eingefügt, aber auf allen anderen nicht.

Was fehlt mir hier noch, damit ich die Textbox erreiche?
Dazu noch die Info, dass ich mit Spy++ und Inspect irgendwie auch nicht klar rausbekomme, um welchen Handle bzw AutomationID es sich handelt. Wenn ich das "Fenster suchen" Feature von Spy++ benutze, dann zeichnet sich über der von mir gesuchten Textbox ein viel größere schwarzer Rahmen ab. Hier wird anscheinend nur ein übergeordnetes Element gefunden (Vielleicht weis jemand warum?). Wenn ich über die Textbox gehe, bei welcher das Manipulieren funktioniert, dann wird direkt das Element ausgewählt, und die ControlID bzw Handle ausgegeben.

Das ganze hab ich wie oben schon erwähnt auch schon mit UIAutomation probiert. Hier sieht es ganz genauso aus. Die eine Textbox kann ich beschrieben, die andere nicht.

Hier der Testweise QC.

Danke schonmal vorab für eure Tipps.

        const uint WM_SETTEXT = 0x000C;

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        public static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, string lParam);

        [DllImport("user32.dll", SetLastError = true)]
        static extern int PostMessageA(int hwnd, int wMsg, int wParam, int lParam);

        [DllImport("user32.dll", SetLastError = true)]
        static extern int PostMessage(int hwnd, int wMsg, int wParam, int lParam);


        List<IntPtr> DeepChilds = new List<IntPtr>();
        public List<IntPtr> GetChildsOfActiveHandle(IntPtr wndhndl)
        {
            WindowHandleInfo WhI = new WindowHandleInfo(wndhndl);
            List<IntPtr> Childs = WhI.GetAllChildHandles();           

            foreach (IntPtr a1 in Childs)
            {
                DeepChilds.Add(a1);
                GetChildsOfActiveHandle(a1);
            }
            return DeepChilds;
        }

        public void GetChildsOfActiveHandleRec()
        {
            IntPtr activeWindowHandle = GetForegroundWindow();
            DeepChilds.Clear();
            List<IntPtr> Childs = GetChildsOfActiveHandle(activeWindowHandle);

            for(int a=0; a < Childs.Count; a++)
            {
                HandleRef hrefHWndTarget = new HandleRef(null, Childs[a]);
                SendMessage(hrefHWndTarget, (int)WM_SETTEXT, (IntPtr)0, Convert.ToString(a));
            }
        }

Sowie:


    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;
        }
    }
}
1.665 Beiträge seit 2006
vor 4 Jahren

Hallo,

falls es sich hierbei um eine App handelt, deren Quellcode du hast, könntest du per IPC über ein eigens definiertes Interface die App ansprechen.

Ansonsten bist du, so wie ich das sehe, schon mal auf dem richtigen Weg. Bezühlich Spy++ kann ich dir leider nichts über das Herausfinden der Handles sagen.