0

アプリケーションには次の C# コードがあります。

private IntPtr _DefaultWndProc = IntPtr.Zero;

[DllImport("user32")]
private static extern IntPtr SetWindowLongPtr(IntPtr hwnd, int index, 
                                              WndProcPointer wndProcPointer);

[DllImport("user32")]
private static extern IntPtr SetWindowLongPtr(IntPtr hwnd, int index, 
                                              IntPtr wndProc);

[DllImport("user32")]
private static extern IntPtr GetWindowLongPtr(IntPtr hwnd, int index);

[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern int CallWindowProc(IntPtr wndProc, IntPtr hwnd, int msg, 
                                         IntPtr wparam, IntPtr lparam);

private const int GWL_WNDPROC = (-4);
private const int WM_NCDESTROY = 0x0082;
private delegate int WndProcPointer(IntPtr hwnd, nt msg, 
                                    IntPtr wparam, IntPtr lparam);

protected virtual int WndProc(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam)
{ 
  return CallWindowProc(_DefaultWndProc, hwnd, msg, wparam, lparam);
}

_DefaultWndProc次のように設定されています。

_DefaultWndProc = SetWindowLongPtr(control.Handle, GWL_WNDPROC, _MyWndProc);

このプログラムを 32 ビット構成用にコンパイルして実行すると、すべて正常に動作します。

ただし、構成を 64 ビットに設定すると、CallWindowProc(_DefaultWndProc, hwnd, msg, wparam, lparam)上記のメソッド呼び出しで次の例外がスローされます。

System.OverflowException - {"Arithmetic operation resulted in an overflow."}

これは、マウス カーソルを の特定の列に移動した場合にのみ発生しますListView

何か案が ?

4

2 に答える 2

1
 private delegate int WndProcPointer(IntPtr hwnd, nt msg, 
                                     IntPtr wparam, IntPtr lparam);

宣言が間違っています。戻り値は int ではなく IntPtr です。メッセージのタイプがタイプミスだったと思います。はい、これは 64 ビット モードで問題を引き起こす可能性があります。

これを行うには、より良い方法があります。

  1. ListView から独自のクラスを派生させ、その WndProc() メソッドをオーバーライドします

  2. NativeWindow から独自のクラスを派生させ、その WndProc() メソッドをオーバーライドします。this.DefWndProc() を呼び出してメッセージを渡します。有効なウィンドウ ハンドルを取得したら、Attach() メソッドを使用します。WM_NCDESTROY を取得したら、WndProc() オーバーライド内で Detach() を呼び出します。

于 2013-07-17T13:19:49.290 に答える