程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Win9x下程序間的數據傳遞

Win9x下程序間的數據傳遞

編輯:Delphi
大家知道在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);
  
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved