摘自:
在c#中,程式採用了的驅動採用了事件驅動而不是原來的訊息驅動,雖然.net框架提供的事件已經十分豐富,但是在以前的系統中定義了豐富的訊息對系統的程式設計提供了方便的實現方法,因此在c#中使用訊息有時候還是大大提高程式設計的效率的。
定義訊息
在c#中訊息需要定義成windows系統中的原始的6進製數字,比如
const int wm_lbutton = 0x0; //定義了滑鼠的左鍵點選訊息
public const int user = 0x000 // 是windows系統定義的使用者訊息
訊息傳送
訊息傳送是通過windows提供的api函式sendmessage來實現的它的原型定義為
[dllimport("user.dll",entrypoint="sendmessage")]
private static extern int sendmessage(
int hwnd, // handle to destination window
int msg, // message
int wparam, // first message parameter
int lparam // second message parameter
); 訊息的接受
在c#中,任何乙個視窗都有也訊息的接收處理函式,就是defproc函式
你可以在form中過載該函式來處理訊息
protected override void defwndproc ( ref system.winforms.message m )
,{}",m.wparam,m.lparam);
messagebox.show(message);///顯示乙個訊息框
break;
default:
base.defwndproc(ref m);///呼叫基類函式處理非自定義訊息。
break;
} }
其實,c#中的事件也是通過封裝系統訊息來實現的,如果你在defwndproc函式中不處理該
那麼,他會交給系統來處理該訊息,系統便會通過**來實現滑鼠單擊的處理函式,因此你可以通過
defproc函式來攔截訊息,比如你想攔截某個按鈕的單擊訊息
c#中其他的訊息處理方法
在c#中有的時候需要對控制項的訊息進行預處理,比如你用owc的spreedsheet控制項來處理excel檔案,你不想讓使用者可以隨便選中
資料進行編輯,你就可以遮蔽掉滑鼠事件,這個時候就必須攔截系統預先定義好的事件(這在mfc中稱為子類化),你可以通過c#提供的乙個介面
imessagefilter來實現訊息的過濾
public class form: system.windows.forms.form,imessagefilter
return false; } }
備註:主要描述在呼叫api函式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 intsendmessage(intptr hwnd, int wmsg, intptr wparam,stringlparam);
[dllimport("user32.dll", entrypoint="sendmessagea")]
private static extern intsendmessage(intptr hwnd, int wmsg, intptr wparam, refrectanglelparam);//呼叫:
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,stringbuilderlparam);
private void button1_click(object sender, system.eventargs e)
[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)
或者private void button2_click(object sender, system.eventargs e)
sendmessage-------postmessage
1、首先是返回值意義的區別,我們先看一下 msdn 裡的宣告:
lresult sendmessage(
hwnd hwnd,
uint msg,
wparam wparam,
lparam lparam
);bool postmessage(
hwnd hwnd,
uint msg,
wparam wparam,
lparam lparam
);其中 4 個引數的意義是一樣的,返回值型別不同(其實從資料上看他們一樣是乙個 32 位的數,只是意義不一樣),lresult 表示的是訊息被處理後的返回值,bool 表示的是訊息是不是 post 成功。
2、postmessage 是非同步的,sendmessage 是同步的。
postmessage 只把訊息放入佇列,不管訊息是否被處理就返回,訊息可能不被處理;而 sendmessage 等待訊息被處理完了之後才返回,如果訊息不被處理,傳送訊息的執行緒將一直被阻塞。
3、如果在同乙個執行緒內,sendmessage 傳送訊息時,由 user32.dll
模組呼叫目標視窗的訊息處理程式,並將結果返回。sendmessage 在同一執行緒中傳送訊息並不入執行緒訊息佇列。postmessage
傳送訊息時,訊息要先放入執行緒的訊息佇列,然後通過訊息迴圈分派到目標視窗(dispatchmessage)。
如果在不同執行緒內,sendmessage 傳送訊息到目標視窗所屬執行緒的訊息佇列,然後傳送訊息的執行緒在 user32.dll
模組內監視和等待訊息處理,直到目標視窗處理完返回。sendmessage 在返回前還做了很多任務作,比如,響應別的執行緒向它
sendmessage。post 到別的執行緒時,最好用 postthreadmessage 代替
postmessage,postmessage 的 hwnd 引數可以是 null,等效於 postthreadmessage +
getcurrentthreadid。post wm_quit 時,應使用 postquitmessage 代替。
4、系統只整編(marshal)系統訊息(0 到 wm_user 之間的訊息),傳送使用者訊息(wm_user 以上)到別的程序時,需要自己做整編。
用 postmessage、sendnotifymessage、sendmessagecallback 等非同步函式傳送系統訊息時,引數裡不可以使用指標,因為傳送者並不等待訊息的處理就返回,接受者還沒處理指標就已經被釋放了。
5、在 windows 2000/xp 裡,每個訊息佇列最多只能存放 10,000 個 post
的訊息,超過的還沒被處理的將不會被處理,直接丟掉。這個值可以改得更大:[hkey_local_machine\software\
microsoft\windows nt\currentversion\windows] userpostmessagelimit,最小可以是
4000。
postmessage只負責將訊息放到訊息佇列中,不確定何時及是否處理
sendmessage要等到受到訊息處理的返回碼(dword型別)後才繼續
postmessage執行後馬上返回
sendmessage必須等到訊息被處理後才會返回。
#程式物件使用
在C 中使用訊息佇列RabbitMQ
1 什麼是rabbitmq。詳見 作用就是提高系統的併發性,將一些不需要及時響應客戶端且占用較多資源的操作,放入佇列,再由另外乙個執行緒,去非同步處理這些佇列,可極大的提高系統的併發能力。2 安裝 a.如果沒有erlang執行環境,在安裝過程中會提醒先安裝erlang環境。注意安裝完成後必須配置環境...
在C 中使用訊息佇列RabbitMQ
參考文章 開發環境 工具 vs2017 rabbitmq erlang執行環境 先安裝erlang執行環境然後再安裝rabbitmq 安裝和配置就不說了 預設安裝路徑 c program files rabbitmq server,在rabbitmq server 3.6.11 sbin資料夾下有b...
Django中使用訊息提示
來自 先簡單說一下這裡的訊息提示是什麼意思,以及其被需求的程度。比如你上乙個任何乙個 當你進行某項操作 例如提交表單或者刪除乙個好友等 可能會彈出乙個訊息框,告訴你你完成了某項操作 相反的,當你進行某項非法操作時,比如你在 號碼的輸入框裡輸入了你的郵箱,人性化的 也許會友好地彈出個框告訴你,你的操作...