SendMessage与WndProc

Pom*_*oma 6 c# pinvoke winforms

我正在尝试扩展TextBox控件以添加水印功能.我在CodeProject上找到的例子是使用导入的SendMessage函数.

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);

void SetWatermark()
{
    SendMessage(this.Handle, 0x1501, 0, "Sample");
}
Run Code Online (Sandbox Code Playgroud)

我想知道为什么不使用受保护的WndProc

void SetWatermark()
{
    var m =new Message() { HWnd = this.Handle, Msg = 0x1501, WParam = (IntPtr)0, LParam = Marshal.StringToHGlobalUni("Sample") };
    WndProc(ref m);
}
Run Code Online (Sandbox Code Playgroud)

两者似乎都很好.我在互联网上看到的几乎所有例子都使用了SendMessage功能.这是为什么?是不是WndProc取代了功能SendMessage

PS我不知道对不对转换stringIntPtr,发现Marshal.StringToHGlobalUni工作正常.这样做是否正确?

Jef*_*tes 12

WndProc不替换SendMessage,它是.NET的等价物WindowProc.WndProc由您的应用程序的消息泵(接收由SendMessage或发送或发布的消息)调用PostMessage以处理它们.通过WndProc直接调用,您可以绕过Windows执行的特殊消息处理,例如捆绑WM_PAINT消息,并且可能会导致一些令人讨厌的问题,即消息出现在应用程序中的窗口所期望的顺序之外.

MSDN中所述,

在通过PreProcessMessage方法进行过滤后,所有消息都将发送到WndProc方法.

WndProc方法完全对应于Windows WindowProc函数.有关处理Windows消息的详细信息,请参阅MSDN库中的WindowProc函数文档,网址http://msdn.microsoft.com/library.

通过直接调用它,您将剥夺系统执行预处理或对该消息进行任何其他处理的机会..NET框架在Windows之上运行而不发送或发布消息,底层系统无法对该消息执行任何操作,因此您将失去底层系统可能为您执行的任何操作.