0

TextBoxいくつかのメッセージをフィルタリングできるように、新しいクラスで再定義できない がありますWndProc。そのため、 win32 関数を使用して、デフォルトの を独自のSetWindowLongに置き換える必要があります。そのため、その中でいくつかのメッセージをフィルタリングできます。無事に交換完了です。メッセージは my でフィルタリングできます。ただし、一貫性のない例外(テキストボックスが作成されたスレッド以外のスレッドからアクセスされているという) のため、完全ではありません。奇妙なことに、例外は、デザイナーによって自動的に作成されたフォームのオーバーライドされた保護されたメソッドの行を強調表示することです。Window procTextBoxWindow ProcWindow procWindow procInvalidOperationExceptionbase.Dispose(disposing);Dispose()

デフォルトのウィンドウ プロシージャに置き換えるコードは次のとおりです。

[DllImport("user32")]
private static extern IntPtr SetWindowLong(IntPtr hwnd, int nIndex, IntPtr proc);
[DllImport("user32")]
private static extern int CallWindowProc(IntPtr proc, IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
private delegate int MyWndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
public int MyWndProcFunc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam)
{
   //Call the default window proc to test
   //However even this can cause the exception after some keystrokes or mouse selection.
   return CallWindowProc(defProc, hwnd, msg, wParam, lParam);
}
IntPtr defProc;
public Form1(){
  InitializeComponent();
  Load += (s,e) => {
     defProc = SetWindowLong(myTextBox.Handle, -4, Marshal.GetFunctionPointerForDelegate(new MyWndProc(MyWndProcFunc)));//GWL_WNDPROC = -4
  };
}

フォームは正常に開始されました。いくつかの文字を にTextBox入力できますが、入力を続けるか、マウスを使用してテキストを選択してみてください...上記の例外が発生する可能性があります。この問題について話しているドキュメントは見つかりません。場合は自分でInvoke呼び出すためにも使用してみましたが、違いはありませんでした。CallWindowProc(...)MyWndProcFunc(...)myTextBox.InvokeRequired = true;

私を助けるためにこの問題を掘り下げてもらえますか?問題は、私が投稿したコードで簡単に再現できます。ありがとう!

アップデート

私の目的は、TextBox継承できない、または別のアプリケーションに属するデフォルトのウィンドウ プロシージャを置き換えることです。ただし、上記のコードは標準の .NET でテストされていますTextBox。これは、プロジェクトに適用する前にテストする最初のステップです。スタックトレースは次のとおりです。

  at System.Windows.Forms.Control.get_Handle()
  at System.Windows.Forms.TextBox.ResetAutoComplete(Boolean force)
  at System.Windows.Forms.TextBox.Dispose(Boolean disposing)
  at System.ComponentModel.Component.Dispose()
  at System.Windows.Forms.Control.Dispose(Boolean disposing)
  at System.Windows.Forms.ContainerControl.Dispose(Boolean disposing)
  at System.Windows.Forms.Form.Dispose(Boolean disposing)
  at WindowsFormsApplication1.Form1.Dispose(Boolean disposing) in C:\Users\iec\AppData\Local\Temporary Projects\WindowsFormsApplication1\Form1.Designer.cs:line 20
  at System.ComponentModel.Component.Dispose()
  at System.Windows.Forms.ApplicationContext.Dispose(Boolean disposing)
  at System.Windows.Forms.Application.ThreadContext.DisposeThreadWindows()
4

2 に答える 2