SetClipboardViewer( WindowHandle ); 함수를 이용해서 Clipboard 감시 윈도우를
설정합니다.
procedure TForm1.FormCreate(Sender: TObject);
begin
NextWindow := SetClipboardViewer(Handle);
end;
반환값인 NextWindow는 감시 윈도를 해제하거나 메시지를 호출할때 사용합니다.
procedure TForm1.FormDestroy(Sender: TObject);
begin
ChangeClipboardChain(Handle, NextWindow);
end;
감시 윈도를 설정하면 그 윈도는 두개의 메시지를 받을 수 있게 됩니다.
WM_CHANGECBCHAIN -> 감시윈도를 해제했을 때 메시지를 전달받습니다.
WM_DRAWCLIPBOARD -> 클립보드가 변경되었을 때 메시지를 전달받습니다.
이 팁의 전체 예제는 아래와 같습니다.
----------------------------------------------------------------------------------------
unit DynaClip;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TForm1 = class( TForm )
btnUpdate: TButton;
lbFormats: TListBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnUpdateClick(Sender: TObject);
private
{ Private declarations }
NextWindow: HWND;
procedure WMChangeCBChain(var Message: TWMChangeCBChain); message
WM_CHANGECBCHAIN;
procedure WMDrawClipboard(var Message: TWMDrawClipboard); message
WM_DRAWCLIPBOARD;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
NextWindow := SetClipboardViewer(Handle);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
ChangeClipboardChain(Handle, NextWindow);
end;
procedure TForm1.WMChangeCBChain(var Message: TWMChangeCBChain);
begin
with Message do begin
if (Remove = NextWindow) then begin
NextWindow := Next;
end
else begin
SendMessage(NextWindow, WM_CHANGECBCHAIN, Remove, Next);
end;
end;
end;
procedure TForm1.WMDrawClipboard(var Message: TWMDrawClipboard);
begin
btnUpdate.Click;
SendMessage(NextWindow, WM_DRAWCLIPBOARD, 0, 0);
end;
procedure TForm1.btnUpdateClick(Sender: TObject);
const
PreDefinedFormats : array[ 1..16 ] of String =
( 'CF_TEXT',
'CF_BITMAP',
'CF_METAFILEPICT',
'CF_SYLK',
'CF_DIF',
'CF_TIFF',
'CF_OEMTEXT',
'CF_DIB',
'CF_PALETTE',
'CF_PENDATA',
'CF_RIFF',
'CF_WAVE',
'CF_UNICODETEXT',
'CF_ENHMETAFILE',
'CF_HDROP',
'CF_LOCALE' );
var
ClipFormat: TClipFormat;
szBuffer : array[0..511] of Char;
FormatID : String;
begin
if not OpenClipboard(Handle) then Exit;
try
lbFormats.Items.BeginUpdate;
try
lbFormats.Items.Clear;
ClipFormat := EnumClipboardFormats(0);
while ( ClipFormat <> 0 ) do
begin
if ( ClipFormat in [1..16] ) then
begin
FormatID := PreDefinedFormats[ClipFormat];
end
else
begin
GetClipboardFormatName(ClipFormat, szBuffer, SizeOf(szBuffer));
FormatID := String(szBuffer);
end;
lbFormats.Items.Add(Format('%s [%d]', [FormatID, ClipFormat]));
ClipFormat := EnumClipboardFormats(ClipFormat);
end;
finally
lbFormats.Items.EndUpdate;
end;
finally
CloseClipboard;
end;
end;
end.
|