【转】【C#】SendMessage
SendMessage是一个在user32.dll中声明的API函数,在C#中导入如下:
using System.Runtime.InteropServices;
[DllImport("user32.dll", EntryPoint="SendMessageA")]
public static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
本文描述其参数 lParam 的用法,主要是数据类型之间的转化。
● 一种最简单的处理方式是声明多个SendMessage函数(overload),用所需的数据类型直接替换IntPtr。
例如:
//声明: [DllImport("user32.dll", EntryPoint="SendMessageA")] private static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, string lParam); [DllImport("user32.dll", EntryPoint="SendMessageA")] private static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, ref Rectangle lParam);
//调用: string s = "hello, floodzhu"; SendMessage(this.textBox1.Handle, WM_SETTEXT, IntPtr.Zero, s); Rectangle rect = new Rectangle(); SendMessage(this.richTextBox1.Handle, EM_GETRECT, (IntPtr)0, ref rect);
● 对要求返回字符串的类型(out string)可以用 StringBuilder 代替,此时不需要 out/ref。
例如:
[DllImport("user32.dll", EntryPoint="SendMessageA")] private static extern int SendMessage (IntPtr hwnd, int wMsg, int wParam, StringBuilder lParam); private void button1_Click(object sender, System.EventArgs e) { const int buffer_size = 1024; StringBuilder buffer = new StringBuilder(buffer_size); SendMessage(this.textBox1.Handle, WM_GETTEXT, buffer_size, buffer); //MessageBox.Show(buffer.ToString()); }
● 如果想用 InPtr 类型统一处理的话,可以借助于 Marshal 或者 GCHandle 的相关方法。
例如:
[DllImport("user32.dll", EntryPoint="SendMessageA")] private static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam); private void button2_Click(object sender, System.EventArgs e) { Rectangle rect = new Rectangle(); IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Rectangle))); Marshal.StructureToPtr(rect, buffer ,true); SendMessage(this.richTextBox1.Handle, EM_GETRECT, (IntPtr)0, buffer); rect = (Rectangle)Marshal.PtrToStructure(buffer, typeof(Rectangle)); Marshal.FreeHGlobal(buffer); }
或者
private void button2_Click(object sender, System.EventArgs e) { Rectangle rect = new Rectangle(); GCHandle gch = GCHandle.Alloc(rect); SendMessage(this.richTextBox1.Handle, EM_GETRECT, (IntPtr)0, (IntPtr)gch); rect = (Rectangle)Marshal.PtrToStructure((IntPtr)gch, typeof(Rectangle)); gch.Free(); }
private const int WM_SETTEXT = 0x000C;
private const int WM_GETTEXT = 0x000D;
private const int EM_GETRECT = 0x00b2;
private const int EM_SETRECT = 0x00b3;
原文地址:http://www.cnblogs.com/me-sa/articles/669402.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义