1

メインプログラムでウィンドウハンドルを見つける方法のジャンプ...

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が何も設定されません。スパイ++は、子供のキャプションには価値があると私に言いました.

4

2 に答える 2

4

GetWindowText 関数のドキュメントには、「GetWindowText は、別のアプリケーションでコントロールのテキストを取得できません。別のプロセスでコントロールのテキストを取得するには、GetWindowText を呼び出す代わりに、WM_GETTEXT メッセージを直接送信してください」と明確に記載されています。

次のコードを使用して、コントロールのテキストを取得できます。

[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();
于 2011-01-05T13:29:58.133 に答える
3

これを行う「最も正しい」方法は次のとおりです。

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 メソッドを外部の世界 (パブリックではない) に公開してはならないことに注意してください。

于 2011-01-05T15:53:51.367 に答える