unit ClipboardViewer; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs; type TForm1 = class(TForm)procedure FormCreate(Sender: TObject);procedure FormDestroy(Sender: TObject);privateFNextViewerHandle : THandle;procedure WMDrawClipboard (var message : TMessage);message WM_DRAWCLIPBOARD;procedure WMChangeCBCHain (var message : TMessage);message WM_CHANGECBCHAIN;publicend; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin // Проверяем работоспособность функции.// При невозможности просмотра буфера обмена// функция возвратит значение Nil.FNextViewerHandle := SetClipboardViewer(Handle);end; procedure TForm1.FormDestroy(Sender: TObject); begin // Восстанавливаем цепочки.ChangeClipboardChain(Handle, FNextViewerHandle);end; procedure TForm1.WMDrawClipboard (var message : TMessage); begin // Вызывается при любом изменении содержимого буфера обмена message.Result := SendMessage(WM_DRAWCLIPBOARD, FNextViewerHandle, 0, 0);end; procedure TForm1.WMChangeCBCHain (var message : TMessage); begin // Вызывается при любом изменении цепочек буфера обмена.if message.wParam = FNextViewerHandle then begin// Удаляем следующую цепочку просмотра. Корректируем внутреннюю переменную.FNextViewerHandle := message.lParam;// Возвращаем 0 чтобы указать, что сообщение было обработаноmessage.Result := 0;end else begin// Передаем сообщение следующему окну в цепочке.message.Result := SendMessage(FNextViewerHandle, WM_CHANGECBCHAIN,message.wParam, message.lParam); end;end; end. |
...private{ Private declarations }PrevHwnd : Hwnd;procedure WMChangeCBChain(VAR Msg: TWMChangeCBChain);message WM_CHANGECBCHAIN;procedure WMDrawClipboard(VAR Msg: TWMDrawClipboard);message WM_DRAWCLIPBOARD;...procedure TForm1.WMChangeCBChain(VAR Msg: TWMChangeCBChain); begin IF PrevHWnd = Msg.Remove THENPrevHWnd := Msg.Next;IF Msg.Remove <> Handle THENSendMessage(PrevHWnd, WM_CHANGECBCHAIN, Msg.Remove, Msg.Next);end; procedure TForm1.WMDrawClipboard(VAR Msg: TWMDrawClipboard); VAR P : PChar;H : THandle;begin SendMessage(PrevHWnd, WM_DRAWCLIPBOARD, 0, 0);IF Clipboard.HasFormat(CF_TEXT) THENBEGINH := Clipboard.GetAsHandle(CF_TEXT);Len := GlobalSize(H)+1;P := GlobalLock(H);Memo1.SetTextBuf(P);GlobalUnlock(H);END;Msg.Result := 0;end; procedure TForm1.FormCreate(Sender: TObject); begin PrevHwnd := SetClipboardViewer(Handle);end; procedure TForm1.FormDestroy(Sender: TObject); begin ChangeClipboardChain(Handle, PrevHwnd);end; |
Обращаю ваше внимание на то, что у меня не было никакой конкретной идеи прежде, чем я это сделал; я просто внимательно прочел файлы помощи по SetClipboardViewer и во всех связанных темах.
- Neil [000523]