home *** CD-ROM | disk | FTP | other *** search
/ Delphi Anthology / aDELPHI.iso / Runimage / Delphi50 / Source / Vcl / clipbrd.pas < prev    next >
Pascal/Delphi Source File  |  1999-08-11  |  12KB  |  484 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Borland Delphi Visual Component Library         }
  5. {                                                       }
  6. {       Copyright (c) 1995,99 Inprise Corporation       }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. unit Clipbrd;
  11.  
  12. {$R-,T-,H+,X+}
  13.  
  14. interface
  15.  
  16. uses Windows, Messages, Classes, Graphics;
  17.  
  18. var
  19.   CF_PICTURE: Word;
  20.   CF_COMPONENT: Word;
  21.  
  22. { TClipboard }
  23.  
  24. { The clipboard object encapsulates the Windows clipboard.
  25.  
  26.   Assign - Assigns the given object to the clipboard.  If the object is
  27.     a TPicture or TGraphic desendent it will be placed on the clipboard
  28.     in the corresponding format (e.g. TBitmap will be placed on the
  29.     clipboard as a CF_BITMAP). Picture.Assign(Clipboard) and
  30.     Bitmap.Assign(Clipboard) are also supported to retrieve the contents
  31.     of the clipboard.
  32.   Clear - Clears the contents of the clipboard.  This is done automatically
  33.     when the clipboard object adds data to the clipboard.
  34.   Close - Closes the clipboard if it is open.  Open and close maintain a
  35.     count of the number of times the clipboard has been opened.  It will
  36.     not actually close the clipboard until it has been closed the same
  37.     number of times it has been opened.
  38.   Open - Open the clipboard and prevents all other applications from changeing
  39.     the clipboard.  This is call is not necessary if you are adding just one
  40.     item to the clipboard.  If you need to add more than one format to
  41.     the clipboard, call Open.  After all the formats have been added. Call
  42.     close.
  43.   HasFormat - Returns true if the given format is available on the clipboard.
  44.   GetAsHandle - Returns the data from the clipboard in a raw Windows handled
  45.     for the specified format.  The handle is not owned by the application and
  46.     the data should be copied.
  47.   SetAsHandle - Places the handle on the clipboard in the given format.  Once
  48.     a handle has been given to the clipboard it should *not* be deleted.  It
  49.     will be deleted by the clipboard.
  50.   GetTextBuf - Retrieves
  51.   AsText - Allows placing and retrieving text from the clipboard.  This property
  52.     is valid to retrieve if the CF_TEXT format is available.
  53.   FormatCount - The number of formats in the Formats array.
  54.   Formats - A list of all the formats available on the clipboard. }
  55.  
  56. type
  57.   TClipboard = class(TPersistent)
  58.   private
  59.     FOpenRefCount: Integer;
  60.     FClipboardWindow: HWND;
  61.     FAllocated: Boolean;
  62.     FEmptied: Boolean;
  63.     procedure Adding;
  64.     procedure AssignGraphic(Source: TGraphic);
  65.     procedure AssignPicture(Source: TPicture);
  66.     procedure AssignToBitmap(Dest: TBitmap);
  67.     procedure AssignToMetafile(Dest: TMetafile);
  68.     procedure AssignToPicture(Dest: TPicture);
  69.     function GetAsText: string;
  70.     function GetFormatCount: Integer;
  71.     function GetFormats(Index: Integer): Word;
  72.     procedure SetAsText(const Value: string);
  73.     procedure SetBuffer(Format: Word; var Buffer; Size: Integer);
  74.     procedure WndProc(var Message: TMessage);
  75.   protected
  76.     procedure AssignTo(Dest: TPersistent); override;
  77.   public
  78.     procedure Assign(Source: TPersistent); override;
  79.     procedure Clear;
  80.     procedure Close;
  81.     function GetComponent(Owner, Parent: TComponent): TComponent;
  82.     function GetAsHandle(Format: Word): THandle;
  83.     function GetTextBuf(Buffer: PChar; BufSize: Integer): Integer;
  84.     function HasFormat(Format: Word): Boolean;
  85.     procedure Open;
  86.     procedure SetComponent(Component: TComponent);
  87.     procedure SetAsHandle(Format: Word; Value: THandle);
  88.     procedure SetTextBuf(Buffer: PChar);
  89.     property AsText: string read GetAsText write SetAsText;
  90.     property FormatCount: Integer read GetFormatCount;
  91.     property Formats[Index: Integer]: Word read GetFormats;
  92.   end;
  93.  
  94. function Clipboard: TClipboard;
  95. function SetClipboard(NewClipboard: TClipboard): TClipboard;
  96.  
  97. implementation
  98.  
  99. uses SysUtils, Forms, Consts;
  100.  
  101. procedure TClipboard.Clear;
  102. begin
  103.   Open;
  104.   try
  105.     EmptyClipboard;
  106.   finally
  107.     Close;
  108.   end;
  109. end;
  110.  
  111. procedure TClipboard.Adding;
  112. begin
  113.   if (FOpenRefCount <> 0) and not FEmptied then
  114.   begin
  115.     Clear;
  116.     FEmptied := True;
  117.   end;
  118. end;
  119.  
  120. procedure TClipboard.Close;
  121. begin
  122.   if FOpenRefCount = 0 then Exit;
  123.   Dec(FOpenRefCount);
  124.   if FOpenRefCount = 0 then
  125.   begin
  126.     CloseClipboard;
  127.     if FAllocated then DeallocateHWnd(FClipboardWindow);
  128.     FClipboardWindow := 0;
  129.   end;
  130. end;
  131.  
  132. procedure TClipboard.Open;
  133. begin
  134.   if FOpenRefCount = 0 then
  135.   begin
  136.     FClipboardWindow := Application.Handle;
  137.     if FClipboardWindow = 0 then
  138.     begin
  139.       FClipboardWindow := AllocateHWnd(WndProc);
  140.       FAllocated := True;
  141.     end;
  142.     if not OpenClipboard(FClipboardWindow) then
  143.       raise Exception.CreateRes(@SCannotOpenClipboard);
  144.     FEmptied := False;
  145.   end;
  146.   Inc(FOpenRefCount);
  147. end;
  148.  
  149. procedure TClipboard.WndProc(var Message: TMessage);
  150. begin
  151.   with Message do
  152.     Result := DefWindowProc(FClipboardWindow, Msg, wParam, lParam);
  153. end;
  154.  
  155. function TClipboard.GetComponent(Owner, Parent: TComponent): TComponent;
  156. var
  157.   Data: THandle;
  158.   DataPtr: Pointer;
  159.   MemStream: TMemoryStream;
  160.   Reader: TReader;
  161. begin
  162.   Result := nil;
  163.   Open;
  164.   try
  165.     Data := GetClipboardData(CF_COMPONENT);
  166.     if Data = 0 then Exit;
  167.     DataPtr := GlobalLock(Data);
  168.     if DataPtr = nil then Exit;
  169.     try
  170.       MemStream := TMemoryStream.Create;
  171.       try
  172.         MemStream.WriteBuffer(DataPtr^, GlobalSize(Data));
  173.         MemStream.Position := 0;
  174.         Reader := TReader.Create(MemStream, 256);
  175.         try
  176.           Reader.Parent := Parent;
  177.           Result := Reader.ReadRootComponent(nil);
  178.           try
  179.             Owner.InsertComponent(Result);
  180.           except
  181.             Result.Free;
  182.             raise;
  183.           end;
  184.         finally
  185.           Reader.Free;
  186.         end;
  187.       finally
  188.         MemStream.Free;
  189.       end;
  190.     finally
  191.       GlobalUnlock(Data);
  192.     end;
  193.   finally
  194.     Close;
  195.   end;
  196. end;
  197.  
  198. procedure TClipboard.SetBuffer(Format: Word; var Buffer; Size: Integer);
  199. var
  200.   Data: THandle;
  201.   DataPtr: Pointer;
  202. begin
  203.   Open;
  204.   try
  205.     Data := GlobalAlloc(GMEM_MOVEABLE+GMEM_DDESHARE, Size);
  206.     try
  207.       DataPtr := GlobalLock(Data);
  208.       try
  209.         Move(Buffer, DataPtr^, Size);
  210.         Adding;
  211.         SetClipboardData(Format, Data);
  212.       finally
  213.         GlobalUnlock(Data);
  214.       end;
  215.     except
  216.       GlobalFree(Data);
  217.       raise;
  218.     end;
  219.   finally
  220.     Close;
  221.   end;
  222. end;
  223.  
  224. procedure TClipboard.SetComponent(Component: TComponent);
  225. var
  226.   MemStream: TMemoryStream;
  227. begin
  228.   MemStream := TMemoryStream.Create;
  229.   try
  230.     MemStream.WriteComponent(Component);
  231.     SetBuffer(CF_COMPONENT, MemStream.Memory^, MemStream.Size);
  232.   finally
  233.     MemStream.Free;
  234.   end;
  235. end;
  236.  
  237. function TClipboard.GetTextBuf(Buffer: PChar; BufSize: Integer): Integer;
  238. var
  239.   Data: THandle;
  240. begin
  241.   Open;
  242.   Data := GetClipboardData(CF_TEXT);
  243.   if Data = 0 then Result := 0 else
  244.   begin
  245.     Result := StrLen(StrLCopy(Buffer, GlobalLock(Data), BufSize - 1));
  246.     GlobalUnlock(Data);
  247.   end;
  248.   Close;
  249. end;
  250.  
  251. procedure TClipboard.SetTextBuf(Buffer: PChar);
  252. begin
  253.   SetBuffer(CF_TEXT, Buffer^, StrLen(Buffer) + 1);
  254. end;
  255.  
  256. function TClipboard.GetAsText: string;
  257. var
  258.   Data: THandle;
  259. begin
  260.   Open;
  261.   Data := GetClipboardData(CF_TEXT);
  262.   try
  263.     if Data <> 0 then
  264.       Result := PChar(GlobalLock(Data)) else
  265.       Result := '';
  266.   finally
  267.     if Data <> 0 then GlobalUnlock(Data);
  268.     Close;
  269.   end;
  270. end;
  271.  
  272. procedure TClipboard.SetAsText(const Value: string);
  273. begin
  274.   SetBuffer(CF_TEXT, PChar(Value)^, Length(Value) + 1);
  275. end;
  276.  
  277. procedure TClipboard.AssignToPicture(Dest: TPicture);
  278. var
  279.   Data: THandle;
  280.   Format: Word;
  281.   Palette: HPALETTE;
  282. begin
  283.   Open;
  284.   try
  285.     Format := EnumClipboardFormats(0);
  286.     while Format <> 0 do
  287.     begin
  288.       if TPicture.SupportsClipboardFormat(Format) then
  289.       begin
  290.         Data := GetClipboardData(Format);
  291.         Palette := GetClipboardData(CF_PALETTE);
  292.         Dest.LoadFromClipboardFormat(Format, Data, Palette);
  293.         Exit;
  294.       end;
  295.       Format := EnumClipboardFormats(Format);
  296.     end;
  297.     raise Exception.CreateRes(@SInvalidClipFmt);
  298.   finally
  299.     Close;
  300.   end;
  301. end;
  302.  
  303. procedure TClipboard.AssignToBitmap(Dest: TBitmap);
  304. var
  305.   Data: THandle;
  306.   Palette: HPALETTE;
  307. begin
  308.   Open;
  309.   try
  310.     Data := GetClipboardData(CF_BITMAP);
  311.     Palette := GetClipboardData(CF_PALETTE);
  312.     Dest.LoadFromClipboardFormat(CF_BITMAP, Data, Palette);
  313.   finally
  314.     Close;
  315.   end;
  316. end;
  317.  
  318. procedure TClipboard.AssignToMetafile(Dest: TMetafile);
  319. var
  320.   Data: THandle;
  321.   Palette: HPALETTE;
  322. begin
  323.   Open;
  324.   try
  325.     Data := GetClipboardData(CF_METAFILEPICT);
  326.     Palette := GetClipboardData(CF_PALETTE);
  327.     Dest.LoadFromClipboardFormat(CF_METAFILEPICT, Data, Palette);
  328.   finally
  329.     Close;
  330.   end;
  331. end;
  332.  
  333. procedure TClipboard.AssignTo(Dest: TPersistent);
  334. begin
  335.   if Dest is TPicture then
  336.     AssignToPicture(TPicture(Dest))
  337.   else if Dest is TBitmap then
  338.     AssignToBitmap(TBitmap(Dest))
  339.   else if Dest is TMetafile then
  340.     AssignToMetafile(TMetafile(Dest))
  341.   else inherited AssignTo(Dest);
  342. end;
  343.  
  344. procedure TClipboard.AssignPicture(Source: TPicture);
  345. var
  346.   Data: THandle;
  347.   Format: Word;
  348.   Palette: HPALETTE;
  349. begin
  350.   Open;
  351.   try
  352.     Adding;
  353.     Palette := 0;
  354.     Source.SaveToClipboardFormat(Format, Data, Palette);
  355.     SetClipboardData(Format, Data);
  356.     if Palette <> 0 then SetClipboardData(CF_PALETTE, Palette);
  357.   finally
  358.     Close;
  359.   end;
  360. end;
  361.  
  362. procedure TClipboard.AssignGraphic(Source: TGraphic);
  363. var
  364.   Data: THandle;
  365.   Format: Word;
  366.   Palette: HPALETTE;
  367. begin
  368.   Open;
  369.   try
  370.     Adding;
  371.     Palette := 0;
  372.     Source.SaveToClipboardFormat(Format, Data, Palette);
  373.     SetClipboardData(Format, Data);
  374.     if Palette <> 0 then SetClipboardData(CF_PALETTE, Palette);
  375.   finally
  376.     Close;
  377.   end;
  378. end;
  379.  
  380. procedure TClipboard.Assign(Source: TPersistent);
  381. begin
  382.   if Source is TPicture then
  383.     AssignPicture(TPicture(Source))
  384.   else if Source is TGraphic then
  385.     AssignGraphic(TGraphic(Source))
  386.   else inherited Assign(Source);
  387. end;
  388.  
  389. function TClipboard.GetAsHandle(Format: Word): THandle;
  390. begin
  391.   Open;
  392.   try
  393.     Result := GetClipboardData(Format);
  394.   finally
  395.     Close;
  396.   end;
  397. end;
  398.  
  399. procedure TClipboard.SetAsHandle(Format: Word; Value: THandle);
  400. begin
  401.   Open;
  402.   try
  403.     Adding;
  404.     SetClipboardData(Format, Value);
  405.   finally
  406.     Close;
  407.   end;
  408. end;
  409.  
  410. function TClipboard.GetFormatCount: Integer;
  411. begin
  412.   Result := CountClipboardFormats;
  413. end;
  414.  
  415. function TClipboard.GetFormats(Index: Integer): Word;
  416. begin
  417.   Open;
  418.   try
  419.     Result := EnumClipboardFormats(0);
  420.     while Index > 0 do
  421.     begin
  422.       Dec(Index);
  423.       Result := EnumClipboardFormats(Result);
  424.     end;
  425.   finally
  426.     Close;
  427.   end;
  428. end;
  429.  
  430. function TClipboard.HasFormat(Format: Word): Boolean;
  431.  
  432.   function HasAPicture: Boolean;
  433.   var
  434.     Format: Word;
  435.   begin
  436.     Open;
  437.     try
  438.       Result := False;
  439.       Format := EnumClipboardFormats(0);
  440.       while Format <> 0 do
  441.         if TPicture.SupportsClipboardFormat(Format) then
  442.         begin
  443.           Result := True;
  444.           Break;
  445.         end
  446.         else Format := EnumClipboardFormats(Format);
  447.     finally
  448.       Close;
  449.     end;
  450.   end;
  451.  
  452. begin
  453.   Result := IsClipboardFormatAvailable(Format) or ((Format = CF_PICTURE) and
  454.     HasAPicture);
  455. end;
  456.  
  457.  
  458. var
  459.   FClipboard: TClipboard;
  460.  
  461. function Clipboard: TClipboard;
  462. begin
  463.   if FClipboard = nil then
  464.     FClipboard := TClipboard.Create;
  465.   Result := FClipboard;
  466. end;
  467.  
  468. function SetClipboard(NewClipboard: TClipboard): TClipboard;
  469. begin
  470.   Result := FClipboard;
  471.   FClipboard := NewClipboard;
  472. end;
  473.  
  474. initialization
  475.   { The following strings should not be localized }
  476.   CF_PICTURE := RegisterClipboardFormat('Delphi Picture');
  477.   CF_COMPONENT := RegisterClipboardFormat('Delphi Component');
  478.   FClipboard := nil;
  479. finalization
  480.   FClipboard.Free;
  481. end.
  482.  
  483.  
  484.