Apr
04
2007
This time we want to retrieve the text from a given window, represented by a handle. Like last time, open an Internet Explorer instance. Now open Winspector and select the address field, ensure that it is the address field itself (class = Edit) and not the ComboBox that you select.
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Globalization; namespace Get_text_from_handle { class Program { // These are two Win32 constants that we'll need, they'll be explained later. const int WM_GETTEXT = 0x000D; const int WM_GETTEXTLENGTH = 0x000E; // The SendMessage function sends a Win32 message to the specified handle, it takes three // ints as parameters, the message to send, and to optional parameters (pass 0 if not required). [DllImport("User32.dll")] public static extern Int32 SendMessage(int hWnd, int Msg, int wParam, int lParam); // An overload of the SendMessage function, this time taking in a StringBuilder as the lParam. // Through the series we'll use a lot of different SendMessage overloads as SendMessage is one // of the most fundamental Win32 functions. [DllImport("User32.dll")] public static extern Int32 SendMessage(int hWnd, int Msg, int wParam, StringBuilder lParam); static void Main(string[] args) { // First, read the handle from the console, remember this has to be in HEX format! int handle = int.Parse(Console.ReadLine(), NumberStyles.HexNumber); // This is a bit tricky. To retrieve the text from a window, we have to know it's length beforehand. // This is because we have to send a StringBuilder of the correct length as a parameter. If it's too // small, it won't be able to contain the full text. If it's too large, it's inefficient. When using // the SendMessage function with the WM_GETTEXTLENGTH message, it returns the length of the // window text. int txtLength = SendMessage(handle, WM_GETTEXTLENGTH, 0, 0); // After having retrieved the length of the string, we create a StringBuilder to hold it. StringBuilder sb = new StringBuilder(txtLength + 1); // Sending the message WM_GETTEXT to the window, passing int he length of the text (the capacity // of the StringBuilder) as well as a reference to the StringBuilder will result in the // StringBuilder being filled up with the windows text. SendMessage(handle, WM_GETTEXT, sb.Capacity, sb); // Finally we'll write out the window text by ToString()'ing the StringBuilder. Console.Write(sb.ToString()); Console.Read(); } } }
And the result:
Mark S. Rasmussen
I'm the Technical Lead at iPaper where I cuddle with databases, mold code and maintain the overall technical responsibility. I'm an avid speaker at user groups & conferences. I love life, motorcycles, photography and all things technical. Say hi on Twitter, write me an email or look me up on LinkedIn.
Comments








