home *** CD-ROM | disk | FTP | other *** search
/ PC World 1999 February / PCWorld_1999-02_cd.bin / temacd / HotKeys / hkClpbrd.pas < prev    next >
Pascal/Delphi Source File  |  1998-10-27  |  5KB  |  238 lines

  1. unit hkClpbrd;
  2.  
  3. interface
  4.  
  5. uses Classes, SysUtils, Windows, WComp;
  6.  
  7. type
  8.   EClipboardError = class(Exception);
  9.  
  10.   TClipboards = class;
  11.  
  12.   TClipboardData = class(TObject)
  13.     Format: UInt;
  14.     Size  : DWord;
  15.     Data  : THandle;
  16.   public
  17.     destructor DestroyMem; virtual;
  18.   end;
  19.  
  20.   TClipboardHistory = class(TObject)
  21.   private
  22.     FFormats: TList;
  23.     function CopyClipboardData(Format: UINT): TClipboardData;
  24.   public
  25.     constructor Create; virtual;
  26.     destructor Destroy; override;
  27.  
  28.     procedure Clear(FreeMemory: Boolean);
  29.  
  30.     procedure ReadClipboard;
  31.     procedure WriteClipboard;
  32.  
  33.     property Formats: TList read FFormats;
  34.   end;
  35.  
  36.   TClipboards = class(TObject)
  37.   private
  38.     FClipboards: TList;
  39.     FActive: Integer;
  40.     procedure SetActive(Value: Integer);
  41.     function GetSize: Integer;
  42.     procedure SetSize(Value: Integer);
  43.   protected
  44.     procedure Clear;
  45.     procedure MakeClipboards(NumClips: Integer);
  46.   public
  47.     constructor Create; virtual;
  48.     destructor Destroy; override;
  49.  
  50.     procedure SwitchToClipboard(Clipboard: Integer; ReportError: Boolean);
  51.     function  DataOnClipboard: Boolean;
  52.  
  53.     property NumClipboards: Integer read GetSize write SetSize default 5;
  54.     property ActiveClipboard: Integer read FActive write SetActive;
  55.   end;
  56.  
  57. implementation
  58.  
  59. { TClipboards }
  60. constructor TClipboards.Create;
  61. begin
  62.   inherited;
  63.   FClipboards := TList.Create;
  64.   FActive := 0;
  65.   MakeClipboards(5);
  66. end;
  67.  
  68. destructor TClipboards.Destroy;
  69. begin
  70.   Clear;
  71.   FClipboards.Free;
  72. end;
  73.  
  74. procedure TClipboards.Clear;
  75. begin
  76.   FActive := -1;
  77.   MakeClipboards(0);
  78. end;
  79.  
  80. procedure TClipboards.MakeClipboards(NumClips: Integer);
  81. begin
  82.   while FClipboards.Count>NumClips do
  83.    begin
  84.      TClipboardHistory(FClipboards[FClipboards.Count-1]).Free;
  85.      FClipboards.Delete(FClipboards.Count-1);
  86.    end;
  87.   while FClipboards.Count<NumClips do FClipboards.Add(TClipboardHistory.Create);
  88.   if FActive>FClipboards.Count-1 then SwitchToClipboard(FClipboards.Count-1, True);
  89. end;
  90.  
  91. procedure TClipboards.SwitchToClipboard(Clipboard: Integer; ReportError: Boolean);
  92. begin
  93.   if (FActive<>Clipboard) then
  94.    begin
  95.      if (Clipboard<0) or (Clipboard>=FClipboards.Count) then
  96.       begin
  97.         if ReportError then
  98.          raise EClipboardError.Create(IntToStr(Clipboard)+' is not a valid clipboard')
  99.         else
  100.          Clipboard := 0;
  101.       end;
  102.      if FActive<FClipboards.Count then TClipboardHistory(FClipboards[FActive]).ReadClipboard;
  103.      FActive := Clipboard;
  104.      TClipboardHistory(FClipboards[FActive]).WriteClipboard;
  105.    end;
  106. end;
  107.  
  108. function TClipboards.GetSize: Integer;
  109. begin
  110.   Result := FClipboards.Count;
  111. end;
  112.  
  113. procedure TClipboards.SetSize(Value: Integer);
  114. begin
  115.   if (Value<>FClipboards.Count) then
  116.    begin
  117.      if (Value>=1) and (Value<=100) then
  118.       MakeClipboards(Value)
  119.      else
  120.       raise EClipboardError.Create('Number of clipboards must be between 1 and 100');
  121.    end;
  122. end;
  123.  
  124. procedure TClipboards.SetActive(Value: Integer);
  125. begin
  126.   SwitchToClipboard(Value, True);
  127. end;
  128.  
  129. function TClipboards.DataOnClipboard: Boolean;
  130. begin
  131.   OpenClipboard(0);
  132.   try
  133.     Result := EnumClipboardFormats(0)<>0;
  134.   finally
  135.     CloseClipboard();
  136.   end;
  137. end;
  138.  
  139. { TClipboardHistory }
  140.  
  141. constructor TClipboardHistory.Create;
  142. begin
  143.   inherited Create;
  144.   FFormats := TList.Create;
  145. end;
  146.  
  147. destructor TClipboardHistory.Destroy;
  148. begin
  149.   Clear(True);
  150.   FFormats.Free;
  151. end;
  152.  
  153. procedure TClipboardHistory.Clear(FreeMemory: Boolean);
  154. var
  155.   i : integer;
  156. begin
  157.   for i:=0 to FFormats.Count-1 do
  158.    if FreeMemory then
  159.     TClipboardData(FFormats[i]).DestroyMem
  160.    else
  161.     TClipboardData(FFormats[i]).Destroy;
  162.   FFormats.Clear;
  163. end;
  164.  
  165. function TClipboardHistory.CopyClipboardData(Format: UINT): TClipboardData;
  166. var
  167.   ClipHandle : THandle;
  168.   pClipHandle,
  169.   pCopyHandle: Pointer;
  170. begin
  171.   ClipHandle := GetClipboardData(Format);
  172.   if ClipHandle<>0 then
  173.    begin
  174.      Result := TClipboardData.Create;
  175.      Result.Format := Format;
  176.      Result.Size := GlobalSize(ClipHandle);
  177.      Result.Data := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE or GMEM_ZEROINIT, Result.Size);
  178.      pClipHandle := GlobalLock(ClipHandle);
  179.      try
  180.        pCopyHandle := GlobalLock(Result.Data);
  181.        try
  182.          CopyMemory(pCopyHandle, pClipHandle, Result.Size);
  183.        finally
  184.          GlobalUnlock(Result.Data);
  185.        end;
  186.      finally
  187.        GlobalUnlock(ClipHandle);
  188.      end;
  189.    end
  190.   else
  191.    Result := nil;
  192. end;
  193.  
  194. procedure TClipboardHistory.ReadClipboard;
  195. var
  196.   Format: UINT;
  197.   Data  : TClipboardData;
  198. begin
  199.   Clear(True);
  200.   OpenClipboard(0);
  201.   try
  202.     Format := EnumClipboardFormats(0);
  203.     while Format<>0 do
  204.      begin
  205.        Data := CopyClipboardData(Format);
  206.        if Data<>nil then FFormats.Add(Data);
  207.        Format := EnumClipboardFormats(Format);
  208.      end;
  209.   finally
  210.     CloseClipboard();
  211.   end;
  212. end;
  213.  
  214. procedure TClipboardHistory.WriteClipboard;
  215. var
  216.   i : integer;
  217. begin
  218.   OpenClipboard(0);
  219.   try
  220.     EmptyClipboard;
  221.     for i:=0 to FFormats.Count-1 do
  222.      with TClipboardData(FFormats[i]) do SetClipboardData(Format, Data);
  223.     Clear(False);
  224.   finally
  225.     CloseClipboard();
  226.   end;
  227. end;
  228.  
  229. { TClipboardData }
  230.  
  231. destructor TClipboardData.DestroyMem;
  232. begin
  233.   if (Data<>0) then GlobalFree(Data);
  234.   inherited Destroy;
  235. end;
  236.  
  237. end.
  238.