Hardware Delphi

Title: Monitoring the Clipboard
Question: In this article I intend explain how to enable your application to join the chain of clipboard viewers, thus receiving an appropiate messages whenever the contents of the clipboard change.
Answer:
Monitoring the Clipboard

Introduction
In this article I intend explain how to enable your application to join the chain of clipboard viewers, thus receiving an appropiate messages whenever the contents of the clipboard change. There are several uses to this facilities, the main two being:
A clipboard monitor - This is an application that continually watches the clipboard, and stores any information passed to it
Enabling and Disabling of menu items - This is used in conjunction with the paste menu item (and toolbar buttons) to enable it whenever the clipboard contains a format that your application can paste.
I am sure that there are other uses for this facility but off hand I can not think of any.
Steps Involved
There are four main steps involved in using the clipboard chain, these are:
1. Joining the clipboard chain
2. Responding to and passing on messages when the clipboard contents change
3. Responding to messages when other members are added to or removed from the chain
4. Removing your application from the chain when it closes.
I will explain how to implement each of these stages in the following code section.
Writing the Code
The code can be crisply divided into the four steps previously mentioned, the extra declarations that needed are:
procedure WMDRAWCLIPBOARD(var Message: TMessage); message WM_DRAWCLIPBOARD;
procedure WMCHANGECBCHAIN(var Message: TMessage); message WM_CHANGECBCHAIN;
These are the messages that we will receive and respond too when the clipboard or clipboard chain is modified.
We also need to store the handle of the next window in the chain (the reasons for this will be explained later):
NextHandle: THandle;
We will now fill in the code to handle these messages, and also the code for joining and leaving the chain.
Joining the Clipboard Chain
This is normally done in the onCreate procedure of the main form in the application. All we need to do here is add the following code:
NextHandle := SetClipboardViewer(handle);
What we are doing here is adding our handle to the clipboard chain, the returned handle is the handle of the next viewer in the chain which we will need to use later.
Responding when the Clipboards Contents Change
Whenever the contents of the clipboard changes we now receive a WM_DRAWCLIPBOARD message. In the procedure which we previously declared we can now respond to clipboard changes. We also must pass on the message that we received to the next handle in the chain, as illustrated by the following code:
procedure TForm1.WMDRAWCLIPBOARD(var Message: TMessage);
begin
{ Add code here to respond to the change }
sendmessage(NextHandle,WM_DRAWCLIPBOARD,0,0);
end;
Responding when the Chain Changes
We also receive a message whenever a handle is removed from the chain. The message we receive provides us with the handle being removed and also with the handle that imediatly follows the one being removed. In response to this we must modify our next handle property (if its being removed) and pass the message along to the next handle in the chain. This is accomplished by the following code:
procedure TForm1.WMCHANGECBCHAIN(var Message: TMessage);
begin
if Message.WParam = NextHandle then
begin
NextHandle := Message.LParam;
end
else
begin
sendmessage(NextHandle,
WM_CHANGECBCHAIN,
Message.WParam, // handle of window to remove
Message.LParam); // handle of next window
end;
end;
Leaving the Clipboard Chain
This is normally done in the on Destroy procedure of the main form in the application. All we are doing here is removing the application from the chain. It is done by the following code:
procedure TForm1.FormDestroy(Sender: TObject);
begin
ChangeClipboardChain(Handle, // our handle to remove
NextHandle ); // handle of next window in the chain
end;