clipmon.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:4k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 1996 AO ROSNO                   }
  6. {         Copyright (c) 1998 Master-Bank                }
  7. {                                                       }
  8. {*******************************************************}
  9. unit ClipMon;
  10. interface
  11. {$I RX.INC}
  12. uses Messages, {$IFDEF WIN32} Windows, {$ELSE} WinTypes, WinProcs, {$ENDIF}
  13.   SysUtils, Classes;
  14. type
  15.   TClipboardMonitor = class(TComponent)
  16.   private
  17.     FWindowHandle: HWnd;
  18.     FNextWindow: HWnd;
  19.     FEnabled: Boolean;
  20.     FOnChange: TNotifyEvent;
  21.     procedure ForwardMessage(var Msg: TMessage);
  22.     procedure SetEnabled(Value: Boolean);
  23.     procedure WndProc(var AMsg: TMessage);
  24.     procedure ClipboardChanged;
  25.   protected
  26.     procedure Change; dynamic;
  27.   public
  28.     constructor Create(AOwner: TComponent); override;
  29.     destructor Destroy; override;
  30.   published
  31.     property Enabled: Boolean read FEnabled write SetEnabled default True;
  32.     property OnChange: TNotifyEvent read FOnChange write FOnChange;
  33.   end;
  34. procedure SaveClipboardToStream(Format: Word; Stream: TStream);
  35. procedure LoadClipboardFromStream(Format: Word; Stream: TStream; Size: Longint);
  36. implementation
  37. uses Forms, Clipbrd;
  38. { Stream routines }
  39. procedure SaveClipboardToStream(Format: Word; Stream: TStream);
  40. var
  41.   Buffer: Pointer;
  42.   Data: THandle;
  43. begin
  44.   Clipboard.Open;
  45.   try
  46.     Data := GetClipboardData(Format);
  47.     if Data = 0 then Exit;
  48.     Buffer := GlobalLock(Data);
  49.     try
  50.       Stream.Write(Buffer^, GlobalSize(Data));
  51.     finally
  52.       GlobalUnlock(Data);
  53.     end;
  54.   finally
  55.     Clipboard.Close;
  56.   end;
  57. end;
  58. procedure LoadClipboardFromStream(Format: Word; Stream: TStream; Size: Longint);
  59. var
  60.   Len: Longint;
  61.   Buffer: Pointer;
  62.   Data: THandle;
  63. begin
  64.   Clipboard.Open;
  65.   try
  66.     Len := Stream.Size - Stream.Position;
  67.     if Len > Size then Len := Size;
  68.     Data := GlobalAlloc(HeapAllocFlags, Len);
  69.     try
  70.       if Data <> 0 then begin
  71.         Buffer := GlobalLock(Data);
  72.         try
  73.           Stream.Read(Buffer^, Len);
  74.           SetClipboardData(Format, Data);
  75.         finally
  76.           GlobalUnlock(Data);
  77.         end;
  78.       end;
  79.     except
  80.       GlobalFree(Data);
  81.       raise;
  82.     end;
  83.   finally
  84.     Clipboard.Close;
  85.   end;
  86. end;
  87. { TClipboardMonitor }
  88. constructor TClipboardMonitor.Create(AOwner: TComponent);
  89. begin
  90.   inherited Create(AOwner);
  91.   FWindowHandle := AllocateHWnd(WndProc);
  92.   SetEnabled(True);
  93. end;
  94. destructor TClipboardMonitor.Destroy;
  95. begin
  96.   FOnChange := nil;
  97.   SetEnabled(False);
  98.   DeallocateHWnd(FWindowHandle);
  99.   inherited Destroy;
  100. end;
  101. procedure TClipboardMonitor.ForwardMessage(var Msg: TMessage);
  102. begin
  103.   if FNextWindow <> 0 then
  104.     with Msg do SendMessage(FNextWindow, Msg, WParam, LParam);
  105. end;
  106. procedure TClipboardMonitor.WndProc(var AMsg: TMessage);
  107. begin
  108.   with AMsg do begin
  109.     Result := 0;
  110.     case Msg of
  111.       WM_DESTROYCLIPBOARD:
  112.         ClipboardChanged;
  113.       WM_CHANGECBCHAIN:
  114.         if HWnd(WParam) = FNextWindow then FNextWindow := HWnd(LParam)
  115.         else ForwardMessage(AMsg);
  116.       WM_DRAWCLIPBOARD:
  117.         begin
  118.           ForwardMessage(AMsg);
  119.           ClipboardChanged;
  120.         end;
  121.       WM_DESTROY:
  122.         SetEnabled(False);
  123.       else Result := DefWindowProc(FWindowHandle, Msg, WParam, LParam);
  124.     end;
  125.   end;
  126. end;
  127. procedure TClipboardMonitor.SetEnabled(Value: Boolean);
  128. begin
  129.   if FEnabled <> Value then begin
  130.     if Value then begin
  131.       FNextWindow := SetClipboardViewer(FWindowHandle);
  132.       FEnabled := True;
  133.     end
  134.     else begin
  135.       ChangeClipboardChain(FWindowHandle, FNextWindow);
  136.       FEnabled := False;
  137.       FNextWindow := 0;
  138.     end;
  139.   end;
  140. end;
  141. procedure TClipboardMonitor.ClipboardChanged;
  142. begin
  143.   try
  144.     Change;
  145.   except
  146.     Application.HandleException(Self);
  147.   end;
  148. end;
  149. procedure TClipboardMonitor.Change;
  150. begin
  151.   if Assigned(FOnChange) then FOnChange(Self);
  152. end;
  153. end.