Jumping of how i will find windows handle in my main program...
in C#
I run notepad.exe then type something in it,then find the main window handle using SPY++ (0x111111) ,and
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int GetWindowText(IntPtr hWnd, [Out] StringBuilder lpString, int nMaxCount);
.
.
.
GetWindowText((IntPtr)(0x111111), str, 1024);
this code works fine and return me the caption of the main window.
: : but when i do the same to find caption of the child of notepad.exe it just set str to nothing. the spy++ told me that the child's caption has value.
The "most correct" way to do this would be:
public static string GetWindowText(IntPtr hwnd)
{
if (hwnd == IntPtr.Zero)
throw new ArgumentNullException("hwnd");
int length = SendMessageGetTextLength(hwnd, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
if (length > 0 && length < int.MaxValue)
{
length++; // room for EOS terminator
StringBuilder sb = new StringBuilder(length);
SendMessageGetText(hwnd, WM_GETTEXT, (IntPtr)sb.Capacity, sb);
return sb.ToString();
}
return String.Empty;
}
const int WM_GETTEXT = 0x000D;
const int WM_GETTEXTLENGTH = 0x000E;
[DllImport("User32.dll", EntryPoint = "SendMessage")]
extern static int SendMessageGetTextLength(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
extern static IntPtr SendMessageGetText(IntPtr hWnd, int msg, IntPtr wParam, [Out] StringBuilder lParam);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
extern static IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, [In] string lpClassName, [In] string lpWindowName);
Note the use of [In]
and [Out]
attributes to eliminate unnecessary copying during marshalling.
Also note that you should never expose p/invoke methods to the outside world (not public).
The GetWindowText function documentation clearly states that "GetWindowText cannot retrieve the text of a control in another application. ... To retrieve the text of a control in another process, send a WM_GETTEXT message directly instead of calling GetWindowText."
You can retrieve the control's text with the following code:
[DllImport("user32.dll", EntryPoint = "SendMessage")]
public static extern IntPtr SendMessageGetText(IntPtr hWnd, uint msg, UIntPtr wParam, StringBuilder lParam);
const uint WM_GETTEXT = 13;
const int bufferSize = 1000; // adjust as necessary
StringBuilder sb = new StringBuilder(bufferSize);
SendMessageGetText(hWnd, WM_GETTEXT, new UIntPtr(bufferSize), sb);
string controlText = sb.ToString();
来源:https://stackoverflow.com/questions/4604023/unable-to-read-another-applications-caption