2

私はこのことを一日中働かせようとしています。入力テキストを別の Windows アプリケーション (Chrome の URL バーとしましょう) のテキスト ボックスに貼り付けようとしています。

だから、テキストボックスの hwnd を動的に正確に見つける方法を理解しようとしています。私もSpy ++を試しましたが、何らかの理由ですべての子ウィンドウに同じhwndが表示されました。何か問題があったに違いありません。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("User32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);

        private static IntPtr WinGetHandle(string wName)
        {
            IntPtr hWnd = IntPtr.Zero;
            foreach (Process pList in Process.GetProcesses())
            {
                if (pList.MainWindowTitle.Contains(wName))
                {
                    hWnd = pList.MainWindowHandle;
                }
            }
            return hWnd;
        }
        static void Main(string[] args)
        {
            List<IntPtr> myList = GetChildWindows(WinGetHandle("chrome"));
            foreach(IntPtr ptr in myList) 
            {
                //No idea which one of those IntPtr is actually my textbox
                //SendMessage((IntPtr)788018, 0x000C, 0, "text here");
            }
            Console.ReadLine();
        }

        [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);
            //  You can modify this to check to see if you want to cancel the operation, then return a null here
            return true;
        }

        public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
    }
}
4

2 に答える 2

0

悲しいことに、思い通りにする方法を見つけることができませんでしたが、かなりうまく機能する回避策を見つけました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        static void Main(string[] args)
        {
            IntPtr hWnd = FindWindow(null, "Origin");
            if (!hWnd.Equals(IntPtr.Zero))
            {
                // activate Notepad window
                if (SetForegroundWindow(hWnd))
                {
                    // send "Hello World!"
                    SendKeys.SendWait("Hello World!");
                    // send key "Tab"
                    SendKeys.SendWait("{TAB}");
                    // send key "Enter"
                    SendKeys.SendWait("{ENTER}");
                }
            }
        }

    }
}
于 2013-10-26T22:03:33.227 に答える