1。在應(yīng)用程序內(nèi)發(fā)送消息
調(diào)用perform(),sendmessage(),postmessage()函數(shù),使消息常量的值為
WM USER+100~$7FFF
2。在應(yīng)用程序之間發(fā)送消息
調(diào)用registerWindowMessage()函數(shù),這個函數(shù)能夠確保每個應(yīng)用程序使用一致的消息序號。RegisterWindowMessage()需要傳遞一個以null結(jié)束的字符串,并返回一個范圍從
$C000~$FFFFF的新的消息常量。在要發(fā)送消息的應(yīng)用程序之間,每個應(yīng)用程序都必須傳遞相同的字符串給RegisterWindowMessage(),而WINDOWS也會返回相同的消息常量,這可以確保給定的字符串返回整個系統(tǒng)中惟一的消息常量,這樣就可以放心地向所有窗口發(fā)送消息。
3。廣播消息
Twincontrol的派生對象可以調(diào)用broadcast()向它的子組件廣播一個消息,當(dāng)需要向一組組件發(fā)送相同的消息時,便可以使用這種技術(shù)。
還可以利用sendmessage,postmessage實現(xiàn)廣播消息,此時只需要將hwnd參數(shù)設(shè)為HWND BROADCAST,它代表向所有的窗口發(fā)送消息。
2007-3-2 12:04:19
發(fā)表評語»»»
2007-7-7 13:48:03 ding
2007-7-9 15:38:33 Perform()
V C L的P e r f o r m ( )方法適用于所有的T C o n t r o l派生對象。P e r f o r m ( )可以向任何一個窗體或控件發(fā)送
消息,只需要知道窗體或控件的實例。P e r f o r m ( )需要傳遞3個參數(shù):消息標(biāo)識符、w P a r a m和l P a r a m。
P e r f o r m ( )是這樣聲明的:
要給一個窗體或控件發(fā)送一個消息,可以參照下面的代碼:
調(diào)用了P e r f o n n ( )后,它要等消息得到處理后才返回。P e r f o r m ( )把3個參數(shù)組裝成T M e s s a g e記錄,
然后調(diào)用D i s p a t c h ( )方法把消息傳遞給Wi n d o w s的消息系統(tǒng)。
sendMessage()和PostMessage()
有的時候,可能需要向一個窗口發(fā)送一個消息,而又不知道這個窗口的實例。例如,可能要給一
個非D e l p h i的窗口發(fā)送一個消息,而只有這個窗口的句柄。幸運的是, Wi n d o w s有兩個A P I函數(shù)可以
實現(xiàn)這一點: S e n d M e s s a g e ( )和P o s t M e s s a g e ( )。這兩個函數(shù)幾乎是一樣的,它們的區(qū)別是: S e n d M e -
s s a g e ( )直接把一個消息發(fā)送給窗口過程,等消息被處理后才返回。P o s t M e s s a g e ( )只是把消息發(fā)送到消
息隊列,然后立即返回。
S e n d M e s s a g e ( )和P o s t M e s s a g e ( )是這樣聲明的:
hwnd是接收消息的窗口的句柄。
Msg是消息標(biāo)識符。
wParam是3 2位的特定附加信息。
lParam是3 2位的特定附加信息。
注意盡管S e n d M e s s a g e ( )和P o s t M e s s a g e ( )調(diào)用方式完全一樣,但它們的返回值不一樣。
S e n d M e s s a g e ( )返回此消息被處理的結(jié)果值,而P o s t M e s s a g e ( )返回一個布爾值,表示消息是否已被放到消息隊列中。
用戶自定義的消息
有些情況下,一個應(yīng)用程序可能需要向自己發(fā)送消息,或者在兩個應(yīng)用程序之間發(fā)送消息。這時
你會有這樣一個問題:“為什么要發(fā)送消息而不是直接調(diào)用一個過程”。這個問題問得好,有這樣幾個
答案。首先,消息可以讓你不需要知道接收者的確切類型。同時,消息可以有選擇地處理。如果接收
者對消息沒有做任何處理,不會造成任何后果。最后,消息可以廣播給多個接收者,而要同時調(diào)用幾
個過程則比較困難。
1. 在應(yīng)用程序內(nèi)發(fā)送消息
一個應(yīng)用程序要發(fā)送消息給自己是很容易的,只要調(diào)用P e r f o r m ( )、S e n d M e s s a g e ( )或P o s t M e s s a g e ( ),
并且使消息常量的值為WM_USER + 100到$ 7 F F F (這個范圍是Wi n d o w s為用戶自定義消息保留的)
const
SX_MYMESSAGE = WM_USER + 100;
BEGIN
SOMEFORM.PERFORM(SX_MYMESSAGE, 0, 0);
//OR
SENDMESSAGE(SOMEFORM.HANDLE, SX_MYMESSAGE, 0, 0);
//OR
POSTMESSAGE(SOMEFORM.HANDLE, SX_MYMESSAGE, 0, 0);
.
.
.
然后聲明和定義一個普通的消息處理過程來處理S X _ M Y M E S S A G E消息:
TFORM1=CLASS(TFORM)
.
.
.
PRIVATE
PROCEDURE SXMYMESSAGE(VAR MSG: TMESSAGE); MESSAGE SX_MYMESSAGE;
END;
PROCEDURE TFORM1.SXMYMESSAGE(VAR MSG: TMESSAGE);
BEGIN
SHOWMESSAGE(‘HELLO‘);
END;
正如你看到的那樣,處理用戶自定義的消息與處理標(biāo)準(zhǔn)的Wi n d o w s消息幾乎沒有什么不同。真正
的關(guān)鍵在于:必須聲明一個消息常量,它的值必須從WM_USER + 100開始。最好為自定義的消息起
一個表明它的用途的名字。
注意除非應(yīng)用程序已經(jīng)建立了相應(yīng)的消息處理過程,否則,不要發(fā)送自定義的消息。由于每
個窗口都可以獨立地定義消息常量的值,因此,發(fā)送自定義消息具有潛在的危險,除非在接受
處理時非常地小心。
2007-7-9 16:15:04 //在發(fā)送數(shù)據(jù)窗體中
var
ds: TCopyDataStruct;
hd: THandle;
begin
ds.cbData := Length(mmContent.Lines.Text) + 1;
GetMem(ds.lpData, ds.cbData); //為傳遞的數(shù)據(jù)區(qū)分配內(nèi)存
StrCopy(ds.lpData, PChar(mmContent.Lines.Text));
Hd := FindWindow(nil, ‘函數(shù)庫‘); // 獲得接受窗口的句柄
if Hd <> 0 then
SendMessage(Hd, WM_COPYDATA, Handle,
Cardinal(@ds)); // 發(fā)送WM_COPYDATA消息
FreeMem(ds.lpData); //釋放資源
end
2007-7-9 16:23:23 //截取最小(大)化消息
procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
procedure TForm1.WMSysCommand(var Msg: TWMSysCommand);
begin
if (Msg.CmdType = SC_MINIMIZE) or
(Msg.CmdType = SC_MAXIMIZE) then
MessageBeep(0);
DefaultHandler(Msg);
end;
2007-9-28 17:20:09 WIN32應(yīng)用程序進行交互的最簡單的方法WIN32應(yīng)用程序進行交互的最簡單的方法
WM_COPYDATA消息
TcopyDataStruct結(jié)構(gòu)類型指針
dwData 是一個32位的附加參數(shù)
cbData 表示要傳遞的數(shù)據(jù)區(qū)的大小
lpData 表示要傳遞的數(shù)據(jù)區(qū)的指針
SendData程序向GetData程序發(fā)送消息,并傳遞edit1中的字符串;GetData在收到消息后,把SendData發(fā)送的字符串接受下來,并顯示在相應(yīng)的edit1中
SendData程序:
……
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: Tobject);
var
ds: TCopyDataStruct;
hd: Thandle;
begin
ds.cbData := Length (Edit1.Text) + 1;
GetMem (ds.lpData, ds.cbData ); //為傳遞的數(shù)據(jù)區(qū)分配內(nèi)存
StrCopy (ds.lpData, Pchar (Edit1.Text));
Hd := FindWindow (nil, ‘Form2‘); // 獲得接受窗口的句柄
if Hd <> 0 then
SendMessage (Hd, WM_COPYDATA, Handle, Cardinal(@ds)) // 發(fā)送WM_COPYDATA消息
else
ShowMessage (‘目標(biāo)窗口沒找到!‘);
FreeMem (ds.lpData); //釋放資源
end;
StrCopy(Dest,Source :pChar):Pchar;
字符串拷貝。函數(shù)不進行長度檢查,且目的區(qū)域的大小不小于length(source)+1個字符。如果希望進行長度檢查,請使用strlcopy()函數(shù)。
GetData程序:
TForm2 = class(Tform)
Edit1: Tedit;
private
{ Private declarations }
public
{ Public declarations }
procedure Mymessage(var t:TWmCopyData);message WM_COPYDATA;
end;
var
Form2: TForm2;
implementation
procedure TForm2.Mymessage(var t:TWmCopyData);
begin
Edit1.text:=StrPas(t.CopyDataStruct^.lpData);//接受數(shù)據(jù)并顯示。
end;
StrPas(Str:Pchar):String;
將以0結(jié)束(null結(jié)束)的字符串str轉(zhuǎn)換成pascal格式的字符串。
2007-9-30 14:44:14 全局原子Win32系統(tǒng)中,為了實現(xiàn)信息共享,系統(tǒng)維護了一張全局原子表。每個原子中存放了一些共享數(shù)據(jù)。關(guān)于對原子的操作,有一組專門的API函數(shù)
GlobalAddAtom 在表中增加全局原子
GlobalDeleteAtom 在表中刪除全局原子
GlobalFindAtom 在表中搜索全局原子
GlobalGetAtomName 從表中獲取全局原子
program Pvdde;
uses
Forms,shellapi,Windows,dialogs,dde in ‘dde.pas‘ {Form1};
{$R *.RES}
begin
if GlobalFindAtom(Pchar(‘PDDE_IS_RUNNING‘)) = 0 then //避免二次啟動
begin
K:=GlobalAddAtom(Pchar(‘PDDE_IS_RUNNING‘));
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end
else
begin
//傳遞二次啟動時的參數(shù)到第一個實例
H := FindWindow(Pchar(‘TForm1‘), Pchar(‘資料保密 嚴禁外傳‘));
if ParamCount > 0 then
begin
L := GlobalAddAtom(Pchar(ParamStr(1)));
if H<>0 then
SendMessage(H, WM_MYMESSAGE, 0, L);
{ 傳遞原子句柄 }
GlobalDeleteAtom(L); { 使用后釋放 }
end;
Application.Terminate;
end;
end;
end.
在相應(yīng)的窗口單元dde.pas增加對自定義消息WM_MYMESSAGE的處理:
procedure TForm1.MyMessage(var T:Tmessage);
{對 WM_MYMESSAGE消息進行處理 }
var
P: Array [0..255] of char;
begin
GlobalGetAtomName(T.Lparam, P,255); { 接受數(shù)據(jù)到p數(shù)組中 }
...
end;
使用存儲映象文件
這種方法相對較復(fù)雜一些。
當(dāng)Win95與Winows Nt向內(nèi)存中裝載文件時,使用了特殊的全局內(nèi)存區(qū)。在該區(qū)域內(nèi),應(yīng)用程序的虛擬內(nèi)存地址和文件中的相應(yīng)位置一一對應(yīng)。由于所有進程共享了一個用于存儲映象文件的全局內(nèi)存區(qū)域,因而當(dāng)兩個進程裝載相同模塊(應(yīng)用程序或DLL文件)時,它們實際可以在內(nèi)存‘">發(fā)現(xiàn)違禁文字,本頁之后內(nèi)容忽