Win9x下程式間的資料傳遞 |
|
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
此為轉貼資料 Win9x下程式間的資料傳遞 大家知道在Window 9x中一個應用程式不能直接訪問另一個程式的記憶體位址,因?WIN9x?每個運行中的進程提供了自己的虛擬空間,這起到了很好的保護作用,然而,它也使得兩個程式間不能輕易的交換資料,但是這並不是說程式間就一定不能進行資料傳送了,Win9x?我們提供了幾個特殊的方法來實現這個目的,如通過Windows消息WM_CopyData 和存儲影響文件等方法。
使用消息WM_CopyData傳送需要傳遞的資料緩衝區的記憶體位址,前面講過,我們不能從一個應用程式向另一個程式發送記憶體塊的位址,因?一個虛擬存儲空間中的位址在另一個位址空間中沒有意義。但是WM_CopyData消息回在後臺執行一些特殊操作之後在傳遞資料,因此我們能夠在接受方得到正確的地址。該消息使用時需要傳遞正在發送消息的視窗的控制碼,及一個指TCopyDataStruct結構的指標。該結構如下:
tagCOPYDATASTRUCT = packed record
dwData: DWORD;
//這是一個附加的32位參數;
cbData: DWORD;
//我們將要傳遞的資料緩衝區的大小;
lpData: Pointer;
//指向資料緩衝區的指標。
end;
TCopyDataStruct=tag COPYDATASTRUCT;
一個例子,SendData套裝程式含一個文本框,在它的OnChange事件中將文本框中的內容發送到GetData程式重並顯示出來。
在SendCopyData程式裏,文本框OnChange事件的處理函數如下:
procedure TForm1.InputEditChange(Sender: TObject);
var
cds: TCopyDataStruct;
ss: PChar;
targetHandle: THandle;
begin
cds.cbData:=Length(InputEdit.Text)+1;
GetMem(ss,cds.cbData); //申請cbData大小的緩衝區,並把指標賦給ss;
strCopy(ss,Pchar(InputEdit.text));
cds.lpData:=ss; //設置緩衝區指標
targetHandle:=FindWindow(′TForm1′,′GetCopyData′); //用API函數獲取〃GetCopyData〃視窗控制碼
if targetHandle=0 then
begin
ShowMessage(′Don′'t find target window′);
exit;
end;
SendMessage(targetHandle,WM_COPYDATA,Handle,Integer((@cds)));//將cds結構指標發送個目標視窗;
//targetHandle使目標視窗控制碼;
//Handle 發送消息的視窗控制碼;
FreeMem(ss);
end;
在GetCopyData程式中,通過一個定制的消息處理程式接受wm_CopyData消息:
public
procedure GetCopyData(var msg: TWMCopyData); message WM_COPYDATA;
procedure TForm1.GetCopyData(var msg: TWMCopyData);
begin
with msg.CopyDataStruct^ do
begin
Form1.Edit1.Text:=PChar(lpdata);
end;
end;
其中TWMCopyData結構定義如下:
TWMCopyData = record
Msg: Cardinal;
From: HWND; //發送該消息的視窗的控制碼
CopyDataStruct: PCopyDataStruct; //即SendCopyData程式中cds結構的指標
Result: Longint;
end;
除了用wm_CopyData消息傳遞資料外,Windows還提供了File_Mapping記憶體共用技術用於實現程式間資料共用。使用與上例視窗相似的兩個程式來說明
在MapWrite程式中:
Private
HMapFile: Thanale;
MapFilePointer: Pointer;
procedure TForm1.FormCreate(Sender: TObject);
begin
//使用API函數來建立映象文件
hMapFile:=CreateFileMapping(
$FFFFFFFF, //指定共用記憶體
nil,
Page_ReadWrite, //共用方式
0,
1000, //共用記憶體大小
′MyMappedFile′); //映象文件的名字
if hMapFile<>0 then //如果映象文件建立成功
//MapViewOfFile函數返回一個指向共用記憶體塊的在該程式記憶體空間中有效的指標
MapFilePointer:=MapView OfFile(hMapFile,File-Map-All-Access,0,0,0)
else
ShowMessage(′Can′'t Create MapFile′);
if MapFilePointer=nil then
ShowMessage(′MapFilePointer=nil′);
end;
procedure TForm1.Edit1Change(Sender: TObject);
begin
StrCopy(PChar(MapFilePointer),PChar(Edit1.Text));//將文本框中的字串copy到共用記憶體中
end;
在MapRead程式中使用API函數OpenFileMapping打開MapWrite程式中已建立的映象文件
procedure TForm1.FormCreate(Sender: TObject);
begin
hMapFile:=OpenFileMapping(FILE_MAP_READ,true,′MyMappedFile′); //取得′MyMappedFile′映象文件的控制碼
if hMapFile<>0 then
MapFilePointer:=MapViewOfFile(hMapFile,File_Map_All_Access,0,0,0)
else
begin
ShowMessage(′Can not open Mapp File′);
Timer1.Enabled:=false;
end;
end;
//定時從共用記憶體中讀取資料並顯示出來
procedure TForm1.Timer1Timer(Sender: TObject);
var
ss: String;
begin
ss:=PChar(MapFilePointer);
Edit1.Text:=ss;
end;
當然最後我們要釋放共用記憶體控制碼
UnMapViewOfFile(MapFilePointer);
CloseHandle(hMapFile);
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |