我需要两个程序之间传递字符串,用消息可以做到吗?
我看了很多关于消息的帖子,都是传一个消息类型,不附带数据,消息不能附带数据吗?不想用TCP或UDP

解决方案 »

  1.   

    是不是网络上用的?如果是的话,那你要考虑使用WINSOCK了?
    如果不是,接着向下看:两个程序之间用消息传递数据。
    问题:我想用SendMessage和自定义消息在两个程序之间传递一个字符串,问题是如果这个字符串是一个常量,SendMessage(h,CM_MYMESSAGE,0,integer(pchar('abcdef')));另外一个程序对CM_MYMESSAGE进行处理可以收到'abcdef',然而,把abcdef变成一个pchar或者string进行传递,就无法正常使用了!如何解决呢?解答:可以利用WM_COPYDATA来做。
    下面代码仅仅演示,细节错误不予考虑procedure Init;
    var
      s                 : pchar;
      h                 : hwnd;
      buf:tagCOPYDATASTRUCT;
    begin
      h := FindWindow('TForm1', 'Form1');
      if h <> 0 then
      begin
        GetMem(s,100);
        buf.lpData :=s;
        buf.cbData:=100;
        buf.dwData :=100;
        strpcopy(s, ParamStr(0));
        SendMessage(h, WM_COPYDATA, 0, integer(@buf));
      end;
    end;procedure TForm1.WM_COPYDATA(var msg: TMessage);
    var
      P:^tagCOPYDATASTRUCT;
    begin
      p:=Pointer(Msg.lParam);
      ShowMessage(strpas(p.lpData));
    end;
    ***********************************************************************************

      The WM_COPYDATA messages makes it possible to transfer information 
      between processes. It does this by passing the data through the kernel. 
      Space is allocated in the receiving process to hold the information that is copied, 
      by the kernel, from the source process to the target process. 
      The sender passes a pointer to a COPYDATASTRUCT, which is defined as a structure 
      of the following: 

    type 
      TCopyDataStruct = packed record 
        dwData: DWORD; // anwendungsspezifischer Wert 
        cbData: DWORD; // Byte-L&auml;nge der zu übertragenden Daten 
        lpData: Pointer; // Adresse der Daten 
      end; 
    { Sender Application } 
    unit SenderApp; interface uses 
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
      StdCtrls, ExtCtrls; type 
      TForm1 = class(TForm) 
        Button1: TButton; 
        Edit1: TEdit; 
        Button2: TButton; 
        Image1: TImage; 
        procedure Button1Click(Sender: TObject); 
        procedure Button2Click(Sender: TObject); 
      private 
        procedure SendCopyData(hTargetWnd: HWND; ACopyDataStruct:TCopyDataStruct); 
      public 
      end; var 
      Form1: TForm1; implementation {$R *.DFM} // Sender: Send data 
    // Sender: Daten schicken 
    procedure TForm1.SendCopyData(hTargetWnd: HWND; ACopyDataStruct:TCopyDataStruct); 
    begin 
      if hTargetWnd <> 0 then 
        SendMessage(hTargetWnd, WM_COPYDATA, Longint(Handle), Longint(@ACopyDataStruct)) 
      else 
        ShowMessage('No Recipient found!'); 
    end; // Send Text from Edit1 to other app 
    // Text von Edit1 an andere Anwendung schicken 
    procedure TForm1.Button1Click(Sender: TObject); 
    var 
      MyCopyDataStruct: TCopyDataStruct; 
      hTargetWnd: HWND; 
    begin 
      // Set up a COPYDATASTRUCT structure for use with WM_COPYDATA 
      // TCopyDataStruct mit den Sende-Daten Infos ausfüllen 
      with MyCopyDataStruct do 
      begin 
        dwData := 0; // may use a value do identify content of message 
        cbData := StrLen(PChar(Edit1.Text)) + 1;  //Need to transfer terminating #0 as well 
        lpData := PChar(Edit1.Text) 
      end; 
      // Find the destination window for the WM_COPYDATA message 
      // Empf&auml;nger Fenster anhand des Titelzeilentextes suchen 
      hTargetWnd := FindWindow(nil,PChar('Message Receiver')); 
      // send the structure to the receiver 
      // Die Struktur an den Empf&auml;nger schicken 
      SendCopyData(hTargetWnd, MyCopyDataStruct); 
    end; // Send Image1 to other app 
    // Image1 an andere Anwendung schicken 
    procedure TForm1.Button2Click(Sender: TObject); 
    var 
      ms: TMemoryStream; 
      MyCopyDataStruct: TCopyDataStruct; 
      hTargetWnd: HWND; 
    begin 
      ms := TMemoryStream.Create; 
      try 
        image1.Picture.Bitmap.SaveToStream(ms); 
        with MyCopyDataStruct do 
        begin 
          dwData := 1; 
          cbData := ms.Size; 
          lpData := ms.Memory; 
        end; 
        // Search window by the window title 
        // Empf&auml;nger Fenster anhand des Titelzeilentextes suchen 
        hTargetWnd := FindWindow(nil,PChar('Message Receiver')); 
        // Send the Data 
        // Daten Senden 
        SendCopyData(hTargetWnd,MyCopyDataStruct); 
      finally 
        ms.Free; 
      end; 
    end; end. {*********************************************************************} { Receiver Application } 
    unit ReceiverApp; interface uses 
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
      ExtCtrls, StdCtrls; type 
      TForm1 = class(TForm) 
        Image1: TImage; 
        Label1: TLabel; 
      private 
        procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA; 
        { Private-Deklarationen } 
      public 
        { Public-Deklarationen } 
      end; var 
      Form1: TForm1; implementation {$R *.DFM} procedure TForm1.WMCopyData(var Msg: TWMCopyData); 
    var 
      sText: array[0..99] of Char; 
      ms: TMemoryStream; 
    begin 
      case Msg.CopyDataStruct.dwData of 
        0: { Receive Text, Text empfangen} 
          begin 
            StrLCopy(sText, Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData); 
            label1.Caption := sText; 
          end; 
        1: { Receive Image, Bild empfangen} 
          begin 
            ms := TMemoryStream.Create; 
            try 
              with Msg.CopyDataStruct^ do 
               ms.Write(lpdata^, cbdata); 
               ms.Position := 0; 
              image1.Picture.Bitmap.LoadFromStream(ms); 
            finally 
              ms.Free; 
            end; 
          end; 
      end; 
    end; end. 
      

  2.   

    //给你个类。封装wm_copydata的。
    ///////////////////////////////
    //CopyRight Stanely 2002-9-21//
    //[email protected]////////
    ///////////////////////////////
    unit CopyData_San;interface
    uses
    windows,messages,sysutils;type
      TCopyData_San=class
      private
        CD:TcopyDataStruct;
        procedure SetData(p:pointer;len:integer;dwData:cardinal);
      public
        function Send(AHandle:Cardinal;AStr:string;wParam:integer=0;dwData:cardinal=0):integer;overload;
        function Send(AHandle:Cardinal;P:pointer;Len:integer;wParam:integer=0;dwData:cardinal=0):integer;overload;  end;
    ///////////////////////
    function GetCopyData(AMsg:TWMCopyData):string;overload;
    procedure GetCopyData(AMsg:TWMCopyData;var P:pointer;var len:integer);overload;implementation
    procedure GetCopyData(AMsg:TWMCopyData;var P:pointer;var len:integer);
    begin
      p:=amsg.CopyDataStruct.lpData;
      len:=amsg.CopyDataStruct.cbData;
    end;
    function GetCopyData(AMsg:TWMCopyData):string;
    var
    i,len:integer;
    type
    pstr=array of char;
    begin
      result:='';
      len:=amsg.CopyDataStruct.cbData;
      if len<=0 then exit;
      setlength(result,len);
      for i:=1 to len do
      begin
        result[i]:=pstr(amsg.CopyDataStruct.lpData)[i-1];
      end;
    end;{ TCopyData_San }function TCopyData_San.Send(AHandle: Cardinal; AStr: string;wParam:integer=0;dwData:cardinal=0): integer;
    var
    p:array of char;
    i,len:integer;
    begin
      result:=-1;
      len:=length(astr);
      if len<=0 then exit;
      try
      getmem(p,len);
      for i:=1 to len do
      begin
        p[i-1]:=astr[i];
      end;
      result:=send(ahandle,p,len,wparam,dwdata);
      finally
      freemem(p);
      end;
    end;function TCopyData_San.Send(AHandle: Cardinal; P: pointer;
      Len: integer;wParam:integer=0;dwData:cardinal=0): integer;
    begin
      setdata(p,len,dwdata);
      result:=sendmessage(ahandle,wm_copydata,wparam,Cardinal(@cd));
    end;procedure TCopyData_San.SetData(p: pointer; len: integer;dwData:cardinal);
    begin
      cd.cbData:=len;
      cd.lpData:=p;
      cd.dwData:=dwData;
    end;end.
      

  3.   

    好类!不过倒数第二个函数:function TCopyData_San.Send(AHandle: Cardinal; P: pointer;
      Len: integer;wParam:integer=0;dwData:cardinal=0): integer;
    begin
      setdata(p,len,dwdata);
      result:=sendmessage(ahandle,wm_copydata,wparam,Cardinal(@cd));//此句有错:'.' expected but ',' found
    end;很奇怪啊,邢她汉子
      

  4.   

    我用delphi6+win2000没问题。你说是哪行?
      

  5.   

    我也是Delphi6+Win2000,就是我注释的那行。在wparam前。编译器说wparam前面应该是'.' 不是','
      

  6.   

    那没办法了。
    这明显不可能的阿!sendmessage要几个参数?不是4个?
    如果delphi6希望是'.'那么不是变成3个参数了?
    并且wparam是integer类型的,怎么可能后面跟'.'??
      

  7.   

    并且wm_copydata是cardinal类型的,也不会需要'.'雅
      

  8.   

    呵呵,
    顶吧,
    也不能再说什么了,
    大量的数据用WM_COPYDATA,
    少量数据用自定义消息,wParam,lParam来传送数据
      

  9.   

    我的错,找到了,不小心把Unit存成了WM_COPYDATA,重名了。真丢人。
    谢谢汉子,给你40分。