【问题标题】:Reading text from an external applications textbox从外部应用程序文本框中读取文本
【发布时间】:2011-11-25 21:27:35
【问题描述】:

我正在尝试扩展无法使用插件或其他东西的外部程序的某些功能。所以我必须编写自己的应用程序,从这个外部应用程序的文本框中读取文本并触发一些自己的操作。

通过在 user32.dll 中使用 FindWindow API,我已经掌握了外部应用程序的句柄。但现在我有点卡住了。通过使用 Visual Studio Tools 中的 Spy++,我得到了我想从控件中读取的类名是“WindowsForms10.EDIT.app.0.218f99c”的信息,但其中有几个。此外,每次外部应用程序启动时,它都会为我要阅读的文本框创建一个新的控件 ID。

我怎样才能让它设法识别某个文本框并读取它的值?任何人都可以给我一个提示或建议吗?

【问题讨论】:

    标签: vb.net textbox external-application


    【解决方案1】:

    C# 中的代码

    public static class ModApi
    {
        [DllImport("user32.dll", EntryPoint = "FindWindowA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
    
        [DllImport("user32.dll", EntryPoint = "SendMessageTimeout", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern uint SendMessageTimeoutText(IntPtr hWnd, int Msg, int countOfChars, StringBuilder text, uint flags, uint uTImeoutj, uint result);
    
        [DllImport("user32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        static internal extern bool EnumChildWindows(IntPtr hWndParent, funcCallBackChild funcCallBack, IntPtr lParam);
    
        public delegate bool funcCallBackChild(IntPtr hWnd, IntPtr lParam);
    
    
        public static ArrayList TextBoxStrings = new ArrayList();
        public static void ParseWindowControls(string WindowTitle)
        {
            IntPtr hWnd = FindWindow(null, WindowTitle);
            TextBoxStrings.Clear();
    
    
            funcCallBackChild MyCallBack = EnumChildWindowsProc;
            EnumChildWindows(hWnd, MyCallBack, IntPtr.Zero);
        }
    
        private static bool EnumChildWindowsProc(IntPtr hWndParent, IntPtr lParam)
        {
            var buffer = new StringBuilder(256);
            long Retval = GetClassName(hWndParent, buffer, buffer.Capacity);
            if (buffer.ToString() == "Edit" || buffer.ToString() == "Static")
            {
                TextBoxStrings.Add(GetText(hWndParent));
            }
    
            return true;
        }
    
        private static string GetText(IntPtr hwnd)
        {
            var text = new StringBuilder(1024);
            if (SendMessageTimeoutText(hwnd, 0xd, 1024, text, 0x2, 1000, 0) != 0)
            {
                return text.ToString();
            }
    
            return "";
        }
    }
    

    【讨论】:

      【解决方案2】:

      在浏览了几页之后,我找到了如何从外部应用程序的文本框中检索内容的解决方案。我认为这段代码对其他人也可能有用,所以结果如下:

      Module modApi
      
          Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
          Private Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA" (ByVal hwnd As IntPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
          Private Declare Function SendMessageTimeoutString Lib "user32.dll" Alias "SendMessageTimeoutA" (ByVal hwnd As IntPtr, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As String, ByVal fuFlags As Long, ByVal uTimeout As Long, ByVal lpdwResult As Long) As Long
          Friend Declare Function EnumChildWindows Lib "user32.dll" (ByVal hWndParent As IntPtr, ByVal funcCallBack As funcCallBackChild, ByVal lParam As IntPtr) As Boolean
      
          Public Delegate Function funcCallBackChild(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
      
          Public TextBoxStrings As ArrayList = New ArrayList
      
          Public Sub ParseWindowControls(ByVal WindowTitle As String)
              Dim hWnd As IntPtr = FindWindow(vbNullString, WindowTitle)
              TextBoxStrings.Clear()
              If hWnd Then
                  Dim MyCallBack As New funcCallBackChild(AddressOf EnumChildWindowsProc)
                  EnumChildWindows(hWnd, MyCallBack, IntPtr.Zero)
              Else
                  MsgBox("Could not find window!", vbOKOnly + vbExclamation, "Error")
              End If
          End Sub
      
          Private Function EnumChildWindowsProc(ByVal hWndParent As IntPtr, ByVal lParam As IntPtr) As Boolean
              Dim Buffer As String = Space(256)
              Dim Retval As Long = GetClassName(hWndParent, Buffer, Len(Buffer))
              If Left(Buffer, Retval) = "WindowsForms10.EDIT.app.0.218f99c" Then
                  TextBoxStrings.Add(GetText(hWndParent))
              End If
              EnumChildWindowsProc = True
          End Function
      
          Private Function GetText(ByVal hwnd As IntPtr) As String
              Dim sText As String = Space(1024)
              If SendMessageTimeoutString(hwnd, &HD, 1024, sText, &H2, 1000, 0) <> 0 Then
                  GetText = Left(sText, InStr(sText, vbNullChar) - 1)
                  Exit Function
              End If
              GetText = ""
          End Function
      
      End Module
      

      您可以将窗口标题传递给子ParseWindowControls()。子试图找到请求的窗口。如果找到该窗口,它将开始收集在此应用程序中找到的所有控件。回调检查找到的控件是否符合我的规范(文本框)并将文本存储在数组列表中。稍后您只需要知道您的请求文本框的索引并将其从数组列表中取出。而已。希望这对其他人也有帮助。

      【讨论】:

        猜你喜欢
        • 2014-03-21
        • 2012-12-14
        • 2013-08-15
        • 1970-01-01
        • 2011-11-17
        • 1970-01-01
        • 2012-01-12
        • 2010-09-06
        • 2012-06-05
        相关资源
        最近更新 更多