在c#中采用的是事件驅動方式,但在我們使用的過程中,有時候通過調用系統原有的消息,處理起來會比較簡單一些,特別是在處理與dll文件的交互時,的確是非常的方便。
在c#中使用自定義消息
在c#中使用自定義消息非常簡單,只需要下面幾個簡單的步驟就可以了:
1、 定義消息
定義消息的方法和vc中定義消息有一點點不同
比如在vc中申明一個自定義消息:
#define wm_test wm_user + 101
而在c#中消息需要定義成windows系統中的原始的16進制數字,比如自定義消息
public const int user = 0x0400;
那么我們在vc中申明的自定義消息,在c#中就可以做對應的聲明:
public const int wm_test = user+101;
2、 發送消息
消息發送是通過windows提供的api函數sendmessage來實現的,它的原型定義: [dllimport("user32.dll",entrypoint="sendmessage")]
private static extern int sendmessage(
intptr hwnd, // handle to destination window
uint msg, // message
uint wparam, // first message parameter
uint lparam // second message parameter
);
3、 消息接收
消息發出之后,在form中如何接收呢?我們可以重載defwinproc函數來接收消息。
protected override void defwndproc ( ref system.windows.forms.message m )
{
switch(m.msg)
{
case message.wm_test: //處理消息
break;
default:
base.defwndproc(ref m);//調用基類函數處理非自定義消息。
break;
}
}
在c#中使用系統消息
我們以wm_paint消息的處理為例,在c#中處理消息與mfc的消息處理是類似的,但更為簡單。mfc中需要使用declare_message_map來定義消息映射,在c#就不需要了。比如wm_paint消息,我們只要重載父類中的onpaint虛擬方法即可,方法如下:
在菜單view->other windows->object browser打開對象瀏覽窗口(或用ctrl+alt+j打開),在我們的工程名下找到form并選中,這時在右邊的窗口列出所有form類的成員函數,如圖所示:
我們選中onpaint(system.winforms.painteventargs)此時在下面會顯示完整的onpaint函數protected void onpaint ( system.winforms.painteventargs e )我們將這一行字符串copy下來。打開form1.cs進行代碼編輯,我們把剛才拷貝下來的函數定義復制到form1類里面,并加上override關鍵字,此時我們便可以在里面添加我們的消息處理代碼了,請參考如下代碼段:
protected override void onpaint (system.windows.forms.painteventargs e )
{
font font = new font("黑體",28);///定義字體:黑體,大?。?8
solidbrush bluepen = new solidbrush(color.blue);///創建藍色畫筆
solidbrush blackpen = new solidbrush(color.fromargb(0xa0,0xa0,0xb0));///創建黑色畫筆
e.graphics.drawstring("vc知識庫",font,blackpen,65,25);///寫字符串
e.graphics.drawstring("vc知識庫",font,bluepen,61,21);///偏移4個象素用不同的顏色再寫一次,達到立體效果
}
示例應用
1、 定義消息
我們在工程中添加一個message類用來定義消息。然后添加了三個成員變量,其中user為自定義消息的初始值,相當與mfc中的wm_user。wm_test為自定義的用來響應應用程序的消息,wm_msg為自定義的用來響應dll傳遞過來的消息。如何在dll定義消息請參考文章:vc.net從dll傳遞消息到dll。
public class message
{
public const int user = 0x0400;
//as mfc define wm_test wm_user + 101
public const int wm_test = user+101;
public const int wm_msg = user+102;
}
2、 聲明引用函數
在使用消息的地方,申明引用的函數,我們這里在msgform.cs文件中申明:
//申明發送消息函數
[dllimport("user32.dll",entrypoint="sendmessage")]
private static extern int sendmessage(
intptr hwnd, // handle to destination window
uint msg, // message
uint wparam, // first message parameter
uint lparam // second message parameter
);
//申明dll中啟動消息函數
[dllimport("messagedll.dll",entrypoint="startsendmessage")]
private extern static void startsendmessage(intptr hwnd);
3、 處理系統消息
protected override void onpaint ( system.windows.forms.painteventargs e )
{
///定義字體:黑體,大?。?8
font font = new font("黑體",28);
///創建藍色畫筆
solidbrush bluepen = new solidbrush(color.blue);
///創建黑色畫筆
solidbrush blackpen = new solidbrush(color.fromargb(0xa0,0xa0,0xb0));
///寫字符串
e.graphics.drawstring("vc知識庫",font,blackpen,65,25);
///偏移4個象素用不同的顏色再寫一次,達到立體效果
e.graphics.drawstring("vc知識庫",font,bluepen,61,21);
}
4、 觸發自定義消息
//測試應用程序消息
private void testappbutton_click(object sender, system.eventargs e)
{
sendmessage(this.handle,message.wm_test,100,200);
}
//測試dll消息
private void testdllbutton_click(object sender, system.eventargs e)
{
startsendmessage(this.handle);
}
5、 響應和處理自定義消息
protected override void defwndproc ( ref system.windows.forms.message m )
{
string message;
switch(m.msg)
{
case message.wm_test://處理消息
message = string.format("收到從應用程序發出的消息!參數為:{0},{1}",m.wparam,m.lparam);
messagebox.show(message);///顯示一個消息框
break;
case message.wm_msg:
message = string.format("收到從dll發出的消息!參數
為:{0},{1}",m.wparam,m.lparam);
messagebox.show(message);///顯示一個消息框
break;
default:
base.defwndproc(ref m);//調用基類函數處理非自定義消息。
break;
}
}
程序運行結果:
當我們點擊測試dll消息時,彈出消息框顯示收到消息的參數,窗口也會調用wm_pain函數對窗口進行重新繪制。