1. Home
  2. Computing & Technology
  3. Delphi Programming

{Article: Listening the Clipboard
Extending the clipboard's flexibility and functionality from Delphi.
Taking control over the Clipboard with custom formats. Coding Delphi
to receive clipboard change notifications.

Note: Add Memo1 to the Form1
}

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TMember = record
    Name : string;
    eMail : string;
    Posts : Cardinal;
  end;


type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    procedure WMDrawClipboard(var Msg: TMessage); message WM_DRAWCLIPBOARD;
    procedure WMChangeCBChain(var Msg: TMessage); message WM_CHANGECBCHAIN;
  public
  end;

var
  Form1        : TForm1;
  NextInChain  : THandle;
  DelphiGuide  : TMember;
  OurFormat    : Integer;
  MemberHandle : THandle;
implementation

{$R *.DFM}
uses ClipBrd;

procedure TForm1.WMDrawClipboard(var Msg:TMessage);
var MemberPointer : ^TMember;
    MemberInClip  : THandle;
    AMember       : TMember;
begin
 if Clipboard.HasFormat(cf_text) then begin
  Memo1.Lines.Clear;
  Memo1.PasteFromClipboard;
 end else
  if Clipboard.HasFormat(OurFormat) then begin
   if OpenClipboard(Handle) then begin
     MemberInClip:=GetClipboardData(OurFormat);
     MemberPointer := GlobalLock(MemberInClip);
     with AMember do begin
       Name  := MemberPointer^.Name;
       eMail := MemberPointer^.eMail;
       Posts := MemberPointer^.Posts;
     end;
     GlobalUnLock(MemberInClip);
     CloseClipboard();
     with Memo1.Lines do begin
      Clear;
      Add('Clipboard has TMember data:');
      Add(AMember.Name);
      Add(AMember.email);
      Add(IntToStr(AMember.Posts));
     end;
   end;
   end;

 if NextInChain <> 0 then
  SendMessage(NextInChain, WM_DrawClipboard, 0, 0)
end;

procedure TForm1.WMChangeCBChain(var Msg: TMessage);
var
  Remove, Next: THandle;
begin
  Remove := Msg.WParam;
  Next := Msg.LParam;
 with Msg do
  if NextInChain = Remove then
   NextInChain := Next
  else if NextInChain <> 0 then
   SendMessage(NextInChain, WM_ChangeCBChain, Remove, Next)
end;

procedure TForm1.FormCreate(Sender: TObject);
var MemberPointer  : ^TMember;
begin
 NextInChain:=SetClipboardViewer(Handle);

 DelphiGuide.Name  := 'Zarko Gajic';
 DelphiGuide.eMail := 'delphi.guide@about.com';
 DelphiGuide.Posts := 15;

 OurFormat:=RegisterClipboardFormat('CF_TMember');

 if OpenClipboard(Handle) then begin
   EmptyClipboard;
   MemberHandle := GlobalAlloc(GMEM_DDESHARE or GMEM_MOVEABLE, SizeOf(TMember));
   MemberPointer := GlobalLock(MemberHandle);

   MemberPointer^.Name  := DelphiGuide.Name;
   MemberPointer^.eMail := DelphiGuide.eMail;
   MemberPointer^.Posts := DelphiGuide.Posts;

   GlobalUnLock(MemberHandle);
   SetClipboardData(OurFormat,MemberHandle);
	 CloseClipboard();
 end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  GlobalFree(MemberHandle);
  ChangeClipboardChain(Handle, NextInChain);
end;

end.

{
********************************************
Zarko Gajic
About.com Guide to Delphi Programming
http://delphi.about.com
email: delphi.guide@about.com
free newsletter: http://delphi.about.com/library/blnewsletter.htm
forum: http://forums.about.com/ab-delphi/start/
********************************************
}
Explore Delphi Programming
About.com Special Features

Stay connected and entertained with reviews on tips on the latest HDTVs, cellphones and more. More >

Easy ways to connect two computers for networking purposes. More >

  1. Home
  2. Computing & Technology
  3. Delphi Programming

©2009 About.com, a part of The New York Times Company.

All rights reserved.