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.

时间: 2024-10-05 07:28:24

How to Send Information (String, Image, Record) Between Two Applications的相关文章

Method and apparatus for encoding data to be self-describing by storing tag records describing said data terminated by a self-referential record

A computer-implemented method and apparatus in a computer system of processing data generated by a first application program in a second application program during runtime. During runtime, the first application program generates a record including a

Record, Pause, and Stop Traces

Record, Pause, and Stop Traces 仪器在运行时收集有关应用程序的信息.本章介绍如何指导仪器收集信息.Instruments collects information about your app while it's running. This chapter describes how to direct instruments to collect information. 记录跟踪Record a Trace 当你准备好你的应用程序时,你开始录制.在记录时,跟踪

Snapchat- Group Record using Union-find

最近一直在做面筋,就没有在这边更新!但是最近!没有偷懒! // 题目是手机上的通讯录,每条记录只有(name, number)这种pair,有些记录名字重复,有些记录号码重复,让我返回一个list<list<Record>>,// 将所有记录按人分组.比较tricky的点在于(ABC,123), (ABC, 456), (BCD, 456)// 三条记录,第一条和第三条也属于同一个人.要求时间复杂度尽量小 uf算法我是明白的,但是我想的时候的困惑在于 1.ufMap里面存放什么,是

记录类型中String的释放

String能自动释放,在进行内存拷贝时需要进行手动释放.可以直接调用Finalize手工释放 如:TGraphicHideTab 记录中声明的Caption:string TGraphicHideTab = record Image:Integer; Data:Integer; Size:Integer; /// 绘制时使用的尺寸 Caption:string; /// <--- 记录中有String end; 直接内存处理的时候String不会自动处理计数,需要手工处理String. var

基于Tcp通讯的文件传输小例子 (wpf)

源码下载 示例基于wpf技术 是networkcomms2.3.1自带的示例 通讯框架 英国的networkcomms2.3.1C#通信框架 using System; using System.Collections.Generic; using System.Linq; using System.Text; using NetworkCommsDotNet; using System.ComponentModel; using System.IO; namespace ExamplesWPF

Awesome Machine Learning

Awesome Machine Learning  A curated list of awesome machine learning frameworks, libraries and software (by language). Inspired by awesome-php. If you want to contribute to this list (please do), send me a pull request or contact me @josephmisiti Als

kafka producer源码

producer接口: /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this

P6 Professional Installation and Configuration Guide (Microsoft SQL Server Database) 16 R1

P6 Professional Installation and Configuration Guide (Microsoft SQL Server Database) 16 R1       May 2016 Contents About This Guide...................................................................................... 11 Shared Topics in This Guide .

C++ Core Guidelines

C++ Core Guidelines September 9, 2015 Editors: Bjarne Stroustrup Herb Sutter This document is a very early draft. It is inkorrekt, incompleat, and pµøoorly formatted. Had it been an open source (code) project, this would have been release 0.6. Copy