我有一个TextBox
不能用新类重新定义的,这样我就可以在WndProc
. 所以我必须使用win32函数来替换我自己SetWindowLong
的默认Window proc
值。所以我可以过滤其中的一些消息。我已经成功完成了替换。消息可以在我的. 然而,由于不一致的异常(这表示我的文本框是从创建它的线程之外的线程访问的),它并不完整。奇怪的是,异常突出显示了由设计器自动创建的表单的覆盖保护方法中的行。TextBox
Window Proc
Window proc
Window proc
InvalidOperationException
base.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
不能被继承或属于另一个应用程序的默认窗口 proc。但是上面的代码是用标准的 .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()