none
Webbrowserに表示しているPDFに対して、キー送信 RRS feed

  • 質問

  • Windows XP SP3
    Visual Studio 2008 C#
    .Net 3.5
    Acrobat10

    WebbrowserコントロールにPDFファイルを表示しています。

    このPDFファイルに対して、Control + F キーを送信して
    Adobeの簡易検索ボックスを表示したいのですが
    うまくいきません。

    以下ソースです。

    Windows32APIのEnumChildWindowsを使用して、
    Webbrowserコントロール配下から、PDFファイルをウィンドウタイトル名とする
    ウィンドハンドウルを獲得します。

            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);

            [DllImport("user32.dll")]
            public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

            public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);
            private void getSearchTextBoxHandle()
            {
                    Win32Callback callback = new Win32Callback(callback_EnumChildWindows);
                    EnumChildWindows(webBrowser1.Handle, callback, IntPtr.Zero);  //WIN32APIを使用
            }

            bool callback_EnumChildWindows(IntPtr childWindowHandle, IntPtr lParam)
            {
                bool ret = false;
                try
                {
                    const int CAPACITY = 256;

                    //ウィンドウタイトル取得
                    StringBuilder get_windowTitle = new StringBuilder();
                    get_windowTitle.Capacity = CAPACITY;
                    GetWindowText(childWindowHandle, get_windowTitle, CAPACITY);  //WIN32APIを使用

                    if (get_windowTitle.ToString().Contains("test.pdf"))
                    {
                        //PDFファイルのウィンドハンドルを取得
                        textBox1.Text = childWindowHandle.ToString();
                    }
                    ret = true;
                }
                catch (Exception)
                {
                }
                return ret;
            }

    上記は、ウィンドハンドルを取得

    以下、上記で取得したウィンドハンドルに対して、Control+Fのキーを送信する
    public partial class Form1 : Form
        {
            public void button1_Click(object sender, EventArgs e)
            {
          
                //上記で取得したハンドルをアクティブにする
                IntPtr hand =  SetActiveWindow((IntPtr)int.Parse(textBox1.Text));
                Console.WriteLine("SetActiveWindow:" + hand);

                System.Threading.Thread.Sleep(200);  //ほかのサイトを参考にSleepする

                List<SendKeysWrap.INPUT> inputs = new List<SendKeysWrap.INPUT>();

                SendKeysWrap.INPUT input = new test_webbrowser.SendKeysWrap.INPUT();
                input.type = test_webbrowser.SendKeysWrap.type.INPUT_KEYBOARD;
                input.ki.wVk = test_webbrowser.SendKeysWrap.wVk.VK_CONTROL;
                input.ki.dwFlags = SendKeysWrap.dwFlags.KEYEVENTF_KEYDOWN;
                input.ki.wScan = 0;
                input.ki.time = 0;
                input.ki.dwExtraInfo = SendKeysWrap.GetMessageExtraInfo();
                inputs.Add(input);

                input = new test_webbrowser.SendKeysWrap.INPUT();
                input.type = test_webbrowser.SendKeysWrap.type.INPUT_KEYBOARD;
                input.ki.wVk = test_webbrowser.SendKeysWrap.wVk.VK_F;
                input.ki.dwFlags = SendKeysWrap.dwFlags.KEYEVENTF_KEYDOWN;
                input.ki.wScan = 0;
                input.ki.time = 0;
                input.ki.dwExtraInfo = SendKeysWrap.GetMessageExtraInfo();
                inputs.Add(input);

                //Control + F を送信
                SendKeysWrap.SendInput(inputs.ToArray());
            }
    }
    以下のクラスは他のサイトにあったものを使用してます。
    public class SendKeysWrap
        {
            /// <summary>
            /// SendInput Win32APIをラップしたメソッド
            /// </summary>
            /// <param name="inputs"></param>
            public static void SendInput(INPUT[] inputs)
            {
                for (Int32 i = 0; i < inputs.Length; i++)
                {
                    INPUT input = inputs[i];
                    if (input.type == type.INPUT_KEYBOARD)
                    {//キーボードの時は変換が必要らしい
                        input.ki.wScan = (Int16)(MapVirtualKey((Int32)input.ki.wVk, 0));
                        input.ki.time = 0;
                        input.ki.dwExtraInfo = GetMessageExtraInfo();
                        input.ki.dwFlags = ExtendedKeyFlagW(input.ki.wVk) | input.ki.dwFlags;
                    }
                }
                SendInput(inputs.Length, inputs, Marshal.SizeOf(inputs[0]));
            }
            public static dwFlags ExtendedKeyFlagW(wVk key)
            {
                dwFlags flag = 0;
                if (key == wVk.VK_CONTROL)
                {//とりあえずControlだけ
                    flag = dwFlags.KEYEVENTF_EXTENDEDKEY;
                }
                return flag;
            }
            //for KEYBDINPUT /MOUSEINPUT Structure
            public enum dwFlags
            {
                KEYEVENTF_KEYDOWN = 0,
                KEYEVENTF_EXTENDEDKEY = 0x1,
                KEYEVENTF_KEYUP = 0x2,
                KEYEVENTF_SCANCODE = 0x8,
                KEYEVENTF_UNICODE = 0x4,

                MOUSEEVENTF_MOVED = 0x0001,
                MOUSEEVENTF_LEFTDOWN = 0x0002,  // 左ボタン Down
                MOUSEEVENTF_LEFTUP = 0x0004,  // 左ボタン Up
                MOUSEEVENTF_RIGHTDOWN = 0x0008,  // 右ボタン Down
                MOUSEEVENTF_RIGHTUP = 0x0010,  // 右ボタン Up
                MOUSEEVENTF_MIDDLEDOWN = 0x0020,  // 中ボタン Down
                MOUSEEVENTF_MIDDLEUP = 0x0040,  // 中ボタン Up
                MOUSEEVENTF_WHEEL = 0x0080,
                MOUSEEVENTF_XDOWN = 0x0100,
                MOUSEEVENTF_XUP = 0x0200,
                MOUSEEVENTF_ABSOLUTE = 0x8000

            }
            //for INPUT Structure
            public enum type
            {
                INPUT_MOUSE = 0,
                INPUT_KEYBOARD = 1,
                INPUT_HARDWARE = 2
            }
            //SendInput Function
            //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/sendinput.asp
            [DllImport("user32.dll")]
            public extern static Int32 SendInput(Int32 nInputs, INPUT[] pInputs, Int32 cbSize);

            //GetMessageExtraInfo Function
            //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues/messagesandmessagequeuesreference/messagesandmessagequeuesfunctions/getmessageextrainfo.asp
            [DllImport("user32.dll")]
            public extern static IntPtr GetMessageExtraInfo();

            //MapVirtualKey Function
            //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/mapvirtualkey.asp
            [DllImport("user32.dll")]
            public extern static Int32 MapVirtualKey(Int32 uCode, Int32 uMapType);


            //INPUT struct
            //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputstructs/input.asp
            [StructLayout(LayoutKind.Explicit)]
            public struct INPUT
            {
                [FieldOffset(0)]
                public type type;

                [FieldOffset(4)]
                public MOUSEINPUT mi;

                [FieldOffset(4)]
                public KEYBDINPUT ki;

                [FieldOffset(4)]
                public HARDWAREINPUT hi;
            }
            //MOUSEINPUT struct
            //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputstructs/mouseinput.asp
            [StructLayout(LayoutKind.Explicit)]
            public struct MOUSEINPUT
            {
                [FieldOffset(0)]
                public Int32 dx;
                [FieldOffset(4)]
                public Int32 dy;
                [FieldOffset(8)]
                public Int32 mouseData;
                [FieldOffset(12)]
                public dwFlags dwFlags;
                [FieldOffset(16)]
                public Int32 time;
                [FieldOffset(20)]
                public IntPtr dwExtraInfo;
            }
            //KEYBDINPUT struct
            //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputstructs/keybdinput.asp
            [StructLayout(LayoutKind.Explicit)]
            public struct KEYBDINPUT
            {
                [FieldOffset(0)]
                public wVk wVk;
                [FieldOffset(2)]
                public Int16 wScan;
                [FieldOffset(4)]
                public dwFlags dwFlags;
                [FieldOffset(8)]
                public Int32 time;
                [FieldOffset(12)]
                public IntPtr dwExtraInfo;
            }
            //HARDWAREINPUT struct
            //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputstructs/hardwareinput.asp
            [StructLayout(LayoutKind.Explicit)]
            public struct HARDWAREINPUT
            {
                [FieldOffset(0)]
                public Int32 uMsg;
                [FieldOffset(4)]
                public Int16 wParamL;
                [FieldOffset(6)]
                public Int16 wParamH;
            }
            public enum wVk : short
            {
                VK_CONTROL = 0x11, //CTRL key
                VK_F = 0x46, //F key
            }
        }

    2011年3月10日 11:44