在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);///定義字體:黑體,大小:28 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 ) { ///定義字體:黑體,大小:28 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函數對窗口進行重新繪制。
說明:本文是參考《C#開發WINDOWS應用程序時消息的處理》一文,整理而成 參考:http://www.51pub.net/class/project.asp?cat_id=12
|