home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 April / Chip_1997-04_cd.bin / prezent / cb / data.z / CLIPBRD.PAS < prev    next >
Pascal/Delphi Source File  |  1997-01-16  |  12KB  |  481 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Delphi Visual Component Library                 }
  5. {                                                       }
  6. {       Copyright (c) 1995,96 Borland International     }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. unit Clipbrd;
  11.  
  12. {$R-}
  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.     OpenClipboard(FClipboardWindow);
  143.     FEmptied := False;
  144.   end;
  145.   Inc(FOpenRefCount);
  146. end;
  147.  
  148. procedure TClipboard.WndProc(var Message: TMessage);
  149. begin
  150.   with Message do
  151.     Result := DefWindowProc(FClipboardWindow, Msg, wParam, lParam);
  152. end;
  153.  
  154. function TClipboard.GetComponent(Owner, Parent: TComponent): TComponent;
  155. var
  156.   Data: THandle;
  157.   DataPtr: Pointer;
  158.   MemStream: TMemoryStream;
  159.   Reader: TReader;
  160. begin
  161.   Result := nil;
  162.   Open;
  163.   try
  164.     Data := GetClipboardData(CF_COMPONENT);
  165.     if Data = 0 then Exit;
  166.     DataPtr := GlobalLock(Data);
  167.     if DataPtr = nil then Exit;
  168.     try
  169.       MemStream := TMemoryStream.Create;
  170.       try
  171.         MemStream.WriteBuffer(DataPtr^, GlobalSize(Data));
  172.         MemStream.Position := 0;
  173.         Reader := TReader.Create(MemStream, 256);
  174.         try
  175.           Reader.Parent := Parent;
  176.           Result := Reader.ReadRootComponent(nil);
  177.           try
  178.             Owner.InsertComponent(Result);
  179.           except
  180.             Result.Free;
  181.             raise;
  182.           end;
  183.         finally
  184.           Reader.Free;
  185.         end;
  186.       finally
  187.         MemStream.Free;
  188.       end;
  189.     finally
  190.       GlobalUnlock(Data);
  191.     end;
  192.   finally
  193.     Close;
  194.   end;
  195. end;
  196.  
  197. procedure TClipboard.SetBuffer(Format: Word; var Buffer; Size: Integer);
  198. var
  199.   Data: THandle;
  200.   DataPtr: Pointer;
  201. begin
  202.   Open;
  203.   try
  204.     Data := GlobalAlloc(GMEM_MOVEABLE, Size);
  205.     try
  206.       DataPtr := GlobalLock(Data);
  207.       try
  208.         Move(Buffer, DataPtr^, Size);
  209.         Adding;
  210.         SetClipboardData(Format, Data);
  211.       finally
  212.         GlobalUnlock(Data);
  213.       end;
  214.     except
  215.       GlobalFree(Data);
  216.       raise;
  217.     end;
  218.   finally
  219.     Close;
  220.   end;
  221. end;
  222.  
  223. procedure TClipboard.SetComponent(Component: TComponent);
  224. var
  225.   MemStream: TMemoryStream;
  226. begin
  227.   MemStream := TMemoryStream.Create;
  228.   try
  229.     MemStream.WriteComponent(Component);
  230.     SetBuffer(CF_COMPONENT, MemStream.Memory^, MemStream.Size);
  231.   finally
  232.     MemStream.Free;
  233.   end;
  234. end;
  235.  
  236. function TClipboard.GetTextBuf(Buffer: PChar; BufSize: Integer): Integer;
  237. var
  238.   Data: THandle;
  239. begin
  240.   Open;
  241.   Data := GetClipboardData(CF_TEXT);
  242.   if Data = 0 then Result := 0 else
  243.   begin
  244.     Result := StrLen(StrLCopy(Buffer, GlobalLock(Data), BufSize - 1));
  245.     GlobalUnlock(Data);
  246.   end;
  247.   Close;
  248. end;
  249.  
  250. procedure TClipboard.SetTextBuf(Buffer: PChar);
  251. begin
  252.   SetBuffer(CF_TEXT, Buffer^, StrLen(Buffer) + 1);
  253. end;
  254.  
  255. function TClipboard.GetAsText: string;
  256. var
  257.   Data: THandle;
  258. begin
  259.   Open;
  260.   Data := GetClipboardData(CF_TEXT);
  261.   try
  262.     if Data <> 0 then
  263.       Result := PChar(GlobalLock(Data)) else
  264.       Result := '';
  265.   finally
  266.     if Data <> 0 then GlobalUnlock(Data);
  267.     Close;
  268.   end;
  269. end;
  270.  
  271. procedure TClipboard.SetAsText(const Value: string);
  272. begin
  273.   SetBuffer(CF_TEXT, PChar(Value)^, Length(Value) + 1);
  274. end;
  275.  
  276. procedure TClipboard.AssignToPicture(Dest: TPicture);
  277. var
  278.   Data: THandle;
  279.   Format: Word;
  280.   Palette: HPALETTE;
  281. begin
  282.   Open;
  283.   try
  284.     Format := EnumClipboardFormats(0);
  285.     while Format <> 0 do
  286.     begin
  287.       if TPicture.SupportsClipboardFormat(Format) then
  288.       begin
  289.         Data := GetClipboardData(Format);
  290.         Palette := GetClipboardData(CF_PALETTE);
  291.         Dest.LoadFromClipboardFormat(Format, Data, Palette);
  292.         Exit;
  293.       end;
  294.       Format := EnumClipboardFormats(Format);
  295.     end;
  296.     raise Exception.CreateRes(SInvalidClipFmt);
  297.   finally
  298.     Close;
  299.   end;
  300. end;
  301.  
  302. procedure TClipboard.AssignToBitmap(Dest: TBitmap);
  303. var
  304.   Data: THandle;
  305.   Palette: HPALETTE;
  306. begin
  307.   Open;
  308.   try
  309.     Data := GetClipboardData(CF_BITMAP);
  310.     Palette := GetClipboardData(CF_PALETTE);
  311.     Dest.LoadFromClipboardFormat(CF_BITMAP, Data, Palette);
  312.   finally
  313.     Close;
  314.   end;
  315. end;
  316.  
  317. procedure TClipboard.AssignToMetafile(Dest: TMetafile);
  318. var
  319.   Data: THandle;
  320.   Palette: HPALETTE;
  321. begin
  322.   Open;
  323.   try
  324.     Data := GetClipboardData(CF_METAFILEPICT);
  325.     Palette := GetClipboardData(CF_PALETTE);
  326.     Dest.LoadFromClipboardFormat(CF_METAFILEPICT, Data, Palette);
  327.   finally
  328.     Close;
  329.   end;
  330. end;
  331.  
  332. procedure TClipboard.AssignTo(Dest: TPersistent);
  333. begin
  334.   if Dest is TPicture then
  335.     AssignToPicture(TPicture(Dest))
  336.   else if Dest is TBitmap then
  337.     AssignToBitmap(TBitmap(Dest))
  338.   else if Dest is TMetafile then
  339.     AssignToMetafile(TMetafile(Dest))
  340.   else inherited AssignTo(Dest);
  341. end;
  342.  
  343. procedure TClipboard.AssignPicture(Source: TPicture);
  344. var
  345.   Data: THandle;
  346.   Format: Word;
  347.   Palette: HPALETTE;
  348. begin
  349.   Open;
  350.   try
  351.     Adding;
  352.     Palette := 0;
  353.     Source.SaveToClipboardFormat(Format, Data, Palette);
  354.     SetClipboardData(Format, Data);
  355.     if Palette <> 0 then SetClipboardData(CF_PALETTE, Palette);
  356.   finally
  357.     Close;
  358.   end;
  359. end;
  360.  
  361. procedure TClipboard.AssignGraphic(Source: TGraphic);
  362. var
  363.   Data: THandle;
  364.   Format: Word;
  365.   Palette: HPALETTE;
  366. begin
  367.   Open;
  368.   try
  369.     Adding;
  370.     Palette := 0;
  371.     Source.SaveToClipboardFormat(Format, Data, Palette);
  372.     SetClipboardData(Format, Data);
  373.     if Palette <> 0 then SetClipboardData(CF_PALETTE, Palette);
  374.   finally
  375.     Close;
  376.   end;
  377. end;
  378.  
  379. procedure TClipboard.Assign(Source: TPersistent);
  380. begin
  381.   if Source is TPicture then
  382.     AssignPicture(TPicture(Source))
  383.   else if Source is TGraphic then
  384.     AssignGraphic(TGraphic(Source))
  385.   else inherited Assign(Source);
  386. end;
  387.  
  388. function TClipboard.GetAsHandle(Format: Word): THandle;
  389. begin
  390.   Open;
  391.   try
  392.     Result := GetClipboardData(Format);
  393.   finally
  394.     Close;
  395.   end;
  396. end;
  397.  
  398. procedure TClipboard.SetAsHandle(Format: Word; Value: THandle);
  399. begin
  400.   Open;
  401.   try
  402.     Adding;
  403.     SetClipboardData(Format, Value);
  404.   finally
  405.     Close;
  406.   end;
  407. end;
  408.  
  409. function TClipboard.GetFormatCount: Integer;
  410. begin
  411.   Result := CountClipboardFormats;
  412. end;
  413.  
  414. function TClipboard.GetFormats(Index: Integer): Word;
  415. begin
  416.   Open;
  417.   try
  418.     Result := EnumClipboardFormats(0);
  419.     while Index > 0 do
  420.     begin
  421.       Dec(Index);
  422.       Result := EnumClipboardFormats(Result);
  423.     end;
  424.   finally
  425.     Close;
  426.   end;
  427. end;
  428.  
  429. function TClipboard.HasFormat(Format: Word): Boolean;
  430.  
  431.   function HasAPicture: Boolean;
  432.   var
  433.     Format: Word;
  434.   begin
  435.     Open;
  436.     try
  437.       Result := False;
  438.       Format := EnumClipboardFormats(0);
  439.       while Format <> 0 do
  440.         if TPicture.SupportsClipboardFormat(Format) then
  441.         begin
  442.           Result := True;
  443.           Break;
  444.         end
  445.         else Format := EnumClipboardFormats(Format);
  446.     finally
  447.       Close;
  448.     end;
  449.   end;
  450.  
  451. begin
  452.   Result := IsClipboardFormatAvailable(Format) or ((Format = CF_PICTURE) and
  453.     HasAPicture);
  454. end;
  455.  
  456. var
  457.   FClipboard: TClipboard;
  458.  
  459. function Clipboard: TClipboard;
  460. begin
  461.   if FClipboard = nil then
  462.     FClipboard := TClipboard.Create;
  463.   Result := FClipboard;
  464. end;
  465.  
  466. function SetClipboard(NewClipboard: TClipboard): TClipboard;
  467. begin
  468.   Result := FClipboard;
  469.   FClipboard := NewClipboard;
  470. end;
  471.  
  472. initialization
  473.   { The following strings should not be localized }
  474.   CF_PICTURE := RegisterClipboardFormat('Delphi Picture');
  475.   CF_COMPONENT := RegisterClipboardFormat('Delphi Component');
  476.   FClipboard := nil;
  477. finalization
  478.   FClipboard.Free;
  479. end.
  480.  
  481.