SendMessage与WndProc

我正在尝试扩展TextBox控件以添加水印function。 我在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"); } 

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

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

两者似乎都很好。 我在互联网上看到的几乎所有例子都使用SendMessage函数。 这是为什么? 是不是WndProcfunction旨在取代SendMessage

PS我不知道将string转换为IntPtr权利,并发现Marshal.StringToHGlobalUni正常工作。 这样做是否正确?

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

如MSDN中所述 ,

在通过PreProcessMessage方法过滤后,所有消息都被发送到WndProc方法。

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

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