zoukankan      html  css  js  c++  java
  • How to Send Information (String, Image, Record) Between Two Applications

    http://delphi.about.com/od/windowsshellapi/a/wm_copydata.htm

    here are many situation when you need to allow for two applications to communicate. If you do not want to mess with TCP and sockets communication (because both applications are running on the same machine), you can *simply* send (and properly receive) a special Windows message: WM_COPYDATA.

    Since handling Windows messages in Delphi is simple, issuing a SendMessage API call along with the WM_CopyData filled with the data to be sent is quite straight forward.

    WM_CopyData and TCopyDataStruct

    The WM_COPYDATA message enables you to send data from one application to another. The receiving application receives the data in a TCopyDataStruct record . 

    The TCopyDataStruct is defined in the Windows.pas unit and wraps the COPYDATASTRUCT structure that contains the data to be passed.

    Here's the declaration and the description of the TCopyDataStruct record:

    type
      TCopyDataStruct = packed record
        dwData : DWORD;
        // up to 32 bits of data to be passed to the receiving application
        cbData : DWORD;
        // the size, in bytes, of the data pointed to by the lpData member
        lpData : Pointer;
        // Points to data to be passed to the receiving application. This member can be nil.
      end;

    Send a String over WM_CopyData

    For a "Sender" application to send data to "Receiver" the CopyDataStruct must be filled and passed using the SendMessage function. Here's how to send a string value over WM_CopyData:

    procedure TSenderMainForm.SendString( );
    var
      stringToSend : string;
      copyDataStruct : TCopyDataStruct;
    begin
      stringToSend := 'About Delphi Programming';
      copyDataStruct.dwData := 0; // use it to identify the message contents
      copyDataStruct.cbData := 1 + Length( stringToSend );
      copyDataStruct.lpData := PChar( stringToSend );
      SendData( copyDataStruct );
    end;

    The SendData custom function locates the receiver using the FindWindow API call:

    procedure TSenderMainForm.SendData( const copyDataStruct : TCopyDataStruct );
    var
      receiverHandle : THandle;
      res : integer;
    begin
      receiverHandle := FindWindow( PChar( 'TReceiverMainForm' ),
        PChar( 'ReceiverMainForm' ) );
      if receiverHandle = 0 then
      begin
        ShowMessage( 'CopyData Receiver NOT found!' );
        Exit;
      end;
      res := SendMessage( receiverHandle, WM_COPYDATA, integer( Handle ),
        integer( @copyDataStruct ) );
    end;

    In the code above, the "Receiver" application was found using the FindWindow API call by passing the class name of the main form ("TReceiverMainForm") and the caption of the window ("ReceiverMainForm").

    Note: The SendMessage returns an integer value assigned by the code that handled the WM_CopyData message.

    Handling WM_CopyData - Receiving a String

    The "Receiver" application handles the WM_CopyData mesage as in:

    type
      TReceiverMainForm = class( TForm )
      private
        procedure WMCopyData( var Msg : TWMCopyData ); message WM_COPYDATA;
      end;
    
    type
      // The TWMCopyData record is declared as:
      TWMCopyData = packed record
        Msg : Cardinal;
        From : HWND; // Handle of the Window that passed the data
        CopyDataStruct : PCopyDataStruct; // data passed
        Result : Longint; // Use it to send a value back to the "Sender"
      end;
    
    implementation
    
    procedure TReceiverMainForm.WMCopyData( var Msg : TWMCopyData );
    var
      s : string;
    begin
      s := PChar( Msg.CopyDataStruct.lpData );
      // Send something back msg.Result := 2006;
    end;

    Sending String, Custom Record or an Image?

    The accompanying source code demonstrates how to send a string, record (complex data type) and even graphics (bitmap) to another application.

    If you cannot wait the download, here's how to send a TBitmap graphics:

    procedure TSenderMainForm.SendImage( );
    var
      ms : TMemoryStream;
      bmp : TBitmap;
      copyDataStruct : TCopyDataStruct;
    begin
      ms := TMemoryStream.Create;
      try
        bmp := self.GetFormImage;
        try
          bmp.SaveToStream( ms );
        finally
          bmp.Free;
        end;
    copyDataStruct.dwData :
    = Integer( cdtImage ); // identify the data copyDataStruct.cbData := ms.Size; copyDataStruct.lpData := ms.Memory; SendData( copyDataStruct );
    finally ms.Free; end; end; // And how to receive it: procedure TReceiverMainForm.HandleCopyDataImage( copyDataStruct : PCopyDataStruct ); var ms : TMemoryStream; begin ms := TMemoryStream.Create; try ms.Write( copyDataStruct.lpData^, copyDataStruct.cbData ); ms.Position := 0; receivedImage.Picture.Bitmap.LoadFromStream( ms ); finally ms.Free; end; end;

    Downloadwm_copydata source code example.

  • 相关阅读:
    .NET设计模式系列文章
    [转]给年轻工程师的十大忠告
    [你必须知道的.NET]第二十回:学习方法论
    写给开发者看的关系型数据库设计
    AjaxPro使用说明
    Spring.Net入门篇(一) [转]
    [从设计到架构] 必须知道的设计模式
    4月1日SharePoint Designer将开始免费
    12月累计更新的一个导出导入网站的问题在2月累计更新中修复了
    修复错误1093 “Unable to get the private bytes memory limit for the W3WP process”
  • 原文地址:https://www.cnblogs.com/shangdawei/p/4015316.html
Copyright © 2011-2022 走看看