备注:主要描述在调用API函数SendMessage时数据类型的转换。
--------------------------------------------------------------------------------
SendMessage是一个在user32.dll中声明的API函数,在C#中导入如下:
本文描述其参数 lParam 的用法,主要是数据类型之间的转化。
● 一种最简单的处理方式是声明多个SendMessage函数(overload),用所需的数据类型直接替换IntPtr。例如:
--------------------------------------------------------------------------------
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);
[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, 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);
[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 的相关方法。例如:
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());
}
[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 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();
}
{
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();
}