5

ネイティブdllまたはexeが何らかのフックを使用してC#から実行しているWin32API呼び出しをインターセプトしています。この特定のケースでは、user32.dllのDrawText()に興味があります。Win32APIでは次のように宣言されています。

INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags)

LPRECT構造体には、次のシグネチャがあります(Win32 APIでも)。

typedef struct tagRECT { 
    LONG left;
    LONG top;
    LONG right;
    LONG bottom;
} RECT LPRECT;

LONGは、32ビットシステムでの32ビット整数のtypedefです(64ビットシステムについてはわかりません。私は32ビットWindowsを使用しているため、現時点では関係ありません)。この構造体のメンバーにアクセスできるようにするために、C#コードで宣言しました...

[StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct RECT
    {
        public Int32 left;
        public Int32 top;
        public Int32 right;
        public Int32 bottom;
    }

...そしてこのRECT構造体を使用してP/Invokeの署名を書きました:

[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
static extern IntPtr DrawText(IntPtr HDC, String str, Int32 count, ref RECT rect, UInt32 flags, IntPtr dtp);

構造体はC/C ++のような参照型ではなく、C#の値型であるため、ここではref修飾子が必要です。

ただし、rect.top rect.leftetcを使用すると、ほとんどの場合0が返されます。これが正しくないことはわかっています。しかし、数え切れないほどの時間をグーグルで調べて、さまざまなことを試した後、私はこの単純なものを機能させることができませんでした。

私が試したこと:

  • RECTメンバーにさまざまなプリミティブを使用する(int、long、short、UInt32 ...)。実際、これが型の問題ではないことは明らかです。いずれにせよ、0ではなく文字化けした数字が表示されるはずだからです。
  • ref修飾子を削除します。rect.leftは、その値ではなくrectへのポインターを正しく返すため、これも愚かです(絶望的な時間、絶望的な対策)。
  • unsafeコードブロックを試しました。動作しませんでしたが、実装を間違えた可能性があります(何をしたか覚えていません)。このアプローチは、一般的にCOMとWin32でのトリッキーなポインターの状況のた​​めに予約されていますが、とにかく私の場合はやり過ぎです。
  • [MarshallAs]RECTのメンバーの前に追加してみました。違いはありませんでした。
  • 値をいじってみましたPack。変わりはない。

私は非常に簡単で簡単なものを見逃しているとかなり確信していますが、それが何であるかわかりません...

どんな助けでも大歓迎です。ありがとうございました。

4

3 に答える 3

4

http://www.pinvoke.net/default.aspx/user32.DrawText

于 2008-10-14T23:40:07.087 に答える
2

あなたが試し[MarshallAs]たと言っているのに気づきましたが、試しました[MarshalAs(UnmanagedType.Struct)]か?

于 2008-10-14T23:43:34.257 に答える
1

問題の一部は、StringBuilder を使用する必要がある場所での String の使用です。

この署名を試してください ( PInvoke Interop Assistantで生成)


[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct tagRECT {

    /// LONG->int
    public int left;

    /// LONG->int
    public int top;

    /// LONG->int
    public int right;

    /// LONG->int
    public int bottom;
}

public partial class NativeMethods {

    /// Return Type: int
    ///hdc: HDC->HDC__*
    ///lpchText: LPCWSTR->WCHAR*
    ///cchText: int
    ///lprc: LPRECT->tagRECT*
    ///format: UINT->unsigned int
    [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint="DrawTextW")]
public static extern  int DrawTextW([System.Runtime.InteropServices.InAttribute()] System.IntPtr hdc, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] System.Text.StringBuilder lpchText, int cchText, ref tagRECT lprc, uint format) ;

}
于 2008-10-15T08:16:43.533 に答える