在C#中也可以使用Windows 消息,包括系統消息和自定義消息。
對於自定義消息中,對於LParam可以在發中或者接收過程中使用自定義結構來傳遞數據
如:
public struct MyStruct
{
public int i;
public string str;
}
發送消息可以調用WindowsAPI,SendMessage:
MyStruct myst = new MyStruct();
SendMessage(hWnd, WM_USER, 0,ref myst);
接收消息可通過重寫DefWndProc來實現:
protected override void DefWndProc(ref System.Windows.Forms.Message m)
{
switch(m.Msg)
{
case WM_USER: // 任何消息
int iWPara = (int)m.WParam;
MyStruct myStr = new MyStruct();
Type myType=myType.GetType();
myType = (MyStruct)m.GetLParam(myType);
break;
default:
base.DefWndProc(ref m);//調用基類函數處理非自定義消息。
break;
}
}
但是對於一些非自定義的消息, 如WM_SETTEXT,或者一些第三方應用所發出的消息,其中的LParam中可能包含的是一個指向字符串的指針,如char *,那么這時候如何取得LParam中的實際數據呢?
以一自定義消息為例,通過該消息的m.LParam.ToString()得知存儲的數據類型為"String",
但是使用GetLParam(str.GetType())獲取會出現錯誤,因為GetLParam只接受結構類型。那怎么辦呢?
在網上查找了很久這方面的資料,發現問問題的很多,但是卻沒有找到直接的答案,能找到的都是通過自定義結構進行傳遞的例子,但這卻並不能解決很多我們無法決定消息如何發送的情況,包括在MSDN中,也沒有找到有關於此的直接介紹,后來無意想器,既然LParam是IntPtr的指針類型,那么,不調用GetLParam,而直接獲取該指針指向的內存不就可以么?經過實踐,一次成功:
那就是使用Marshal.Copy,將數據從非托管內存指針復制到托管 8 位無符號整數數組.
如下:
byte[] ch = new byte[256];
System.Runtime.InteropServices.Marshal.Copy(m.LParam,ch,0,255);
string str = System.Text.Encoding.Default.GetString(ch);//轉換為字符串
這樣,就成功獲得了m.LParam所包含的字符數據。
利用Marshal.Copy,可以解決很多類似的情況,這樣,無論LParam傳遞過來的是什么類型,也不能擔心了,所有的消息,你可以盡情的來使用了~~哈哈
出處:https://blog.csdn.net/ck0074451665/article/details/5922073