无法读取其他应用程序的标题

发布于 2024-10-10 14:35:23 字数 462 浏览 10 评论 0原文

跳转我如何在主程序中找到窗口句柄...

在 C# 中,

我运行 notepad.exe 然后在其中输入一些内容,然后使用 SPY++ (0x111111) 找到主窗口句柄,

[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);

此代码工作正常并返回标题主窗口的。

: : 但是当我做同样的事情来查找 notepad.exe 子项的标题时,它只是将 str 设置为空。间谍++告诉我孩子的标题有价值。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柠檬 2024-10-17 14:35:23

GetWindowText 函数文档明确指出“GetWindowText 无法检索另一个应用程序中控件的文本。...要检索另一个进程中控件的文本,请直接发送 WM_GETTEXT 消息,而不是调用 GetWindowText。”

您可以使用以下代码检索控件的文本:

[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();

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();
左耳近心 2024-10-17 14:35:23

“最正确”的方法是:

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);

注意使用 [In][Out] 属性来消除编组期间不必要的复制。

另请注意,您永远不应该将 p/invoke 方法暴露给外界(非公开)。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文