{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/
********************************************
}