2

ワードパッドの実行中のインスタンスからテキスト範囲を取得するのに問題があります。次のWindowsメッセージがワードパッドで問題なく機能するようになりました:WM_GETTEXT、WM_GETTEXTLENGTH、EM_REPLACESEL、EM_GETSEL、およびEM_SETSEL。しかし、EM_GETTEXTRANGEメッセージには運がありません。

私のC#テストアプリには、起動時に実行されるワードパッドの実行中のインスタンスを検索し、その子ウィンドウでクラス名RICHEDIT50Wのウィンドウを検索するコードがあります。これは私がメッセージを送信するウィンドウです。繰り返しますが、EM_GETTEXTRANGEを除いて、このウィンドウに送信したすべてのメッセージは正常に機能します。EM_GETTEXTRANGEを送信した後、Marshal.GetLastWin32Errorは5を返します。これは、MSDNによるとERROR_ACCESS_DENIEDです。以下は私の相互運用コードの一部です。誰かが私が問題を解決するのを手伝ってくれますか?ありがとう!

const uint WM_USER = 0x0400; const uint EM_GETTEXTRANGE = WM_USER + 75;

[StructLayout(LayoutKind.Sequential)]
struct CharRange
{
  public int min;
  public int max;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct TextRange
{
  public CharRange charRange;
  [MarshalAs(UnmanagedType.LPWStr)]
  public string text;
}

[DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
extern static int SendMessage(IntPtr hWnd, uint Msg, int wParam, ref TextRange lParam);

public static string GetTextRange(IntPtr wnd, int min, int max)
{
  TextRange textRange = new TextRange();
  textRange.charRange.min = min;
  textRange.charRange.max = max;
  textRange.text = new string('\0', max - min);

  int length = SendMessage(wnd, EM_GETTEXTRANGE, 0, ref textRange);
  int error = Marshal.GetLastWin32Error();

  return error == 0 ? textRange.text : string.Empty;
}

4

1 に答える 1

2

私は自分の問題に対する答えを見つけました。別のプロセスのウィンドウをターゲットにしてSendMessageを呼び出す場合、パラメータは、WM_USER以上のすべてのメッセージのターゲットプロセスメモリに割り当てる必要があります。必要なことはすべて、関数VirtualAllocEx、VirtualFreeEx、ReadProcessMemory、およびWriteProcessMemoryをピンボークすることで実行できます。WriteProcessMemoryとReadProcessMemoryでEM_GETTEXTRANGEを使用する方法について別の質問で取り上げられましたが、問題を完全に理解していなかったため、当初はこれが自分の行っていることに当てはまるとは思いませんでした。

于 2011-02-24T16:59:12.377 に答える