gpt4 book ai didi

c# - 如何获取超时窗口的文本?

转载 作者:太空宇宙 更新时间:2023-11-04 11:53:24 35 4
gpt4 key购买 nike

我目前正在将 C++ 应用程序移植到 C#,但在转换此特定功能时遇到了问题。此函数获取给定窗口句柄的文本/标题。

我发现重要的部分是对 SendMessageTimeoutW 的 2 次调用,它们获取了我假设的窗口的文本,但我无法弄清楚其余部分。

我也找不到 UTF-16 函数 SendMessageTimeoutW 的任何 P/Invoke 签名,那么对 SendMessageTimeout 的调用是否等效,如 this post 所示?

public static unsafe string GetWindowText(IntPtr hWnd)
{

// THIS PART MAY NOT BE NEEDED
string str2 = null;
WinHookEx* exPtr3;
WinHookEx* exPtr = @new(4);
try
{
exPtr3 = (exPtr == null) ? null : WinHookEx.{ctor}(exPtr);
}
fault
{
delete((void*) exPtr);
}
WinHookEx* exPtr2 = exPtr3;
*((int*) exPtr2) = hWnd.ToPointer();
HWND__* hwnd__Ptr = (HWND__*) hWnd.ToPointer();
uint modopt(IsLong) num = 0;
delete((void*) exPtr2);


// 1st call to SendMessageTimeoutW
if (SendMessageTimeoutW(hwnd__Ptr, 14, 0, 0, 2, 0x3e8, &num) == 0)
{
return null;
}

// whats happening here?
num++;
uint modopt(IsLong) num2 = num;
char* chPtr = @new((num2 > 0x7fffffff) ? uint.MaxValue : ((uint) (num2 * 2)));
chPtr[0] = '\0';

// 2nd call to SendMessageTimeoutW
if (SendMessageTimeoutW(hwnd__Ptr, 13, num, (int modopt(IsLong)) chPtr, 2, 0x3e8, &num) == 0)
{
return null;
}
str2 = new string(chPtr);
delete((void*) chPtr);
return str2;
}

我已暂时将此函数移植到 C#,但它总是返回一个空字符串。我什至尝试使用 new StringBuilder(256) 初始化字符串生成器,但它仍然不起作用。

我做错了什么?

public static unsafe string GetWindowText(IntPtr hWnd){

// send WM_GETTEXTLENGTH
if (SendMessageTimeout(hWnd, 14, 0, 0, 2, 0x3e8, IntPtr.Zero) == 0){
return null;
}

// send WM_GETTEXT
StringBuilder sb = new StringBuilder();
if (SendMessageTimeout(hWnd, 13, 0, sb, 2, 0x3e8, IntPtr.Zero) == 0){
return null;
}

return sb.ToString();
}

最佳答案

对于 WM_GETTEXT , wParam(SendMessageTimeout 的第三个参数)是

The maximum number of characters to be copied, including the terminating null character.

你超过了零。

此外,您正在调用 WM_GETTEXTLENGTH但不使用返回值:

The return value is the length of the text in characters, not including the terminating null character.

用它来指定 StringBuilder 的初始大小.我刚刚确认这有效:

    static void Main(string[] args) {
var p = Process.GetProcessById(3484);
var h = p.MainWindowHandle;

string s = GetWindowTextTimeout(h, 100 /*msec*/);

}


[DllImport("User32.dll", SetLastError = true)]
public unsafe static extern int SendMessageTimeout(
IntPtr hWnd,
uint uMsg,
uint wParam,
StringBuilder lParam,
uint fuFlags,
uint uTimeout,
void* lpdwResult);

const int WM_GETTEXT = 0x000D;
const int WM_GETTEXTLENGTH = 0x000E;

public static unsafe string GetWindowTextTimeout(IntPtr hWnd, uint timeout)
{
int length;
if (SendMessageTimeout(hWnd, WM_GETTEXTLENGTH, 0, null, 2, timeout, &length) == 0) {
return null;
}
if (length == 0) {
return null;
}

StringBuilder sb = new StringBuilder(length + 1); // leave room for null-terminator
if (SendMessageTimeout(hWnd, WM_GETTEXT, (uint)sb.Capacity, sb, 2, timeout, null) == 0) {
return null;
}

return sb.ToString();
}

关于c# - 如何获取超时窗口的文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17143880/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com