Recent

Author Topic: Problems with TClipboard  (Read 9269 times)

simone

  • Hero Member
  • *****
  • Posts: 573
Problems with TClipboard
« on: December 21, 2017, 05:07:05 pm »
Dear all,

I'd like to allow copy/paste from graphs drawn with my application, based on
EvsSimpleGraph package, towards externals applications.

May be I'm missing something, but with the following demo code,
after execution, if I paste on Windows Paint, I have the wrong result showed
in the second screenshot...

Does anyone have any suggestions? Thanks in advance.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2. {$mode objfpc}{$H+}
  3.  
  4. interface
  5.  
  6. uses
  7.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Clipbrd, USimpleGraph;
  8.  
  9. type
  10.   TForm1 = class(TForm)
  11.     Graph : TEvsSimpleGraph;
  12.     procedure FormShow(Sender: TObject);
  13.   private
  14.     procedure CopyToClipBoard(aGraph : TEvsSimpleGraph; SrcRect : TRect);
  15.   public
  16.    
  17.   end;
  18.  
  19. var
  20.   Form1: TForm1;
  21.  
  22. implementation
  23. {$R *.lfm}
  24.  
  25. procedure TForm1.FormShow(Sender: TObject);
  26. begin
  27.   Graph:=TEvsSimpleGraph.Create(Self);
  28.   Graph.Align:=alClient;
  29.   Graph.Parent:=Self;
  30.   Graph.InsertNode(Rect(50,50,100,100));
  31.   CopyToClipBoard(Graph,Rect(0,0,110,110));
  32. end;
  33.  
  34. procedure TForm1.CopyToClipBoard(aGraph : TEvsSimpleGraph; SrcRect : TRect);
  35. var
  36.   BmpSrc,BmpDst : TBitmap;
  37.   DstRect : TRect;
  38. begin
  39.   BmpSrc:=TBitmap.Create;
  40.   BmpDst:=TBitmap.Create;
  41.   aGraph.CopyToGraphic(BmpSrc);
  42.   DstRect:=Rect(0,0,SrcRect.Width,SrcRect.Height);
  43.   BmpDst.Width:=DstRect.Width;
  44.   BmpDst.Height:=DstRect.Height;
  45.   BmpDst.Canvas.CopyRect(DstRect,BmpSrc.Canvas,SrcRect);
  46.   Clipboard.Assign(BmpDst);
  47.   BmpSrc.Free;
  48.   BmpDst.Free;
  49. end;
  50.  
  51. end.
« Last Edit: December 21, 2017, 06:40:21 pm by simone »
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Problems with TClipboard
« Reply #1 on: December 21, 2017, 06:48:13 pm »
simple graph already supports clipboard in multiple formats, to copy everything you simple call aGraph.CopytoClipboard(false). To copy only the selection you call aGraph.CopytoClipboard(True). As long as you have the cfBitmap in the Clipboardformats property it should copy a bitmap in the clipboard (last time I checked that is).

Just a heads up, FormShow is called every time your form regain focus (eg alt+Tab outside your application then back in and the onshow event will be fired) use the OnCreate event for initialization. The code posted hints that the graph is already placed on the form at design time there is no need to create it at run time just set its properties. To add Bitmap support in the copytoclipboard you do something along the lines of
Code: Pascal  [Select][+][-]
  1. Graph.ClipBoardFormats := Graph.ClipBoardFormats+[cfBitmap];
  2.  
The selectedobjects property holds the current selected objects.
« Last Edit: December 21, 2017, 07:10:24 pm by taazz »
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

simone

  • Hero Member
  • *****
  • Posts: 573
Re: Problems with TClipboard
« Reply #2 on: December 21, 2017, 07:04:39 pm »
Thanks Taazz. You are right, but if possible, I'd like to copy a specified rectangular (TRect) area of graph, that could contain partial objects...  For this reason I'm trying a different approach.
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Problems with TClipboard
« Reply #3 on: December 21, 2017, 07:12:47 pm »
Thanks Taazz. You are right, but if possible, I'd like to copy a specified rectangular (TRect) area of graph, that could contain partial objects...  For this reason I'm trying a different approach.
the default background in lazarus is black not white. after you set the destination bitmap width and height draw a filled rectangle in white (or what ever color the graph is set to) then copy the rect from the source. Keep in mind that big graphs might raise an out of memory exception when creating the bitmap. make sure that copyrect does not re samples the original size to one line and one column less (common problem in windows).
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

simone

  • Hero Member
  • *****
  • Posts: 573
Re: Problems with TClipboard
« Reply #4 on: December 22, 2017, 12:23:37 am »
It seems to me that CopyToClipboard method does not work properly with a scrolled graph. If it is necessary I can provide an example where the problem arises. Thanks again.

Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: Problems with TClipboard
« Reply #5 on: December 22, 2017, 12:36:27 am »
It may work better if you do SomeForm.GetFormImage for example.

From there, you copy from the bitmap not the surface canvas..

Something to try anyways..
The only true wisdom is knowing you know nothing

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Problems with TClipboard
« Reply #6 on: December 22, 2017, 03:38:50 am »
It seems to me that CopyToClipboard method does not work properly with a scrolled graph. If it is necessary I can provide an example where the problem arises. Thanks again.
Well yeah makes sense. Bmp canvas did not get the proper treatment. I'm assuming there is a selection involved. I'll have to take a closer look. Thanks for reporting.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

simone

  • Hero Member
  • *****
  • Posts: 573
Re: Problems with TClipboard
« Reply #7 on: December 22, 2017, 08:29:33 am »
Yes, I have the problem with a selection of objects, after scrolling. Let me know if you need a case test to reproduce the issue. Thanks again!
 
« Last Edit: December 22, 2017, 08:51:49 am by simone »
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Problems with TClipboard
« Reply #8 on: December 22, 2017, 08:43:05 am »
Yes, I have the problem with a selection of Object, after scrolling. Let me know if you need a case test to reproduce the issue. Thanks again!
the problem has been identified. The solution touches different parts of the library and is not confined in the bitmap and its canvas. It will take me some time to collect and test all the cases(all is a strong word here). I'll try to post a solution when the most used cases are solved.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

simone

  • Hero Member
  • *****
  • Posts: 573
Re: Problems with TClipboard
« Reply #9 on: December 24, 2017, 11:55:36 am »
Meanwhile I'm trying to work without original CopyToClipboard of TEvsSimpleGraph, but I don't understand why in the following code, the red square drawn in FormCreate is not captured by system clipboard with the call to my method SendToClipboard... Thanks for suggestions!

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2. {$mode objfpc}{$H+}
  3.  
  4. interface
  5.  
  6. uses
  7.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Clipbrd, USimpleGraph;
  8.  
  9. type
  10.  
  11.   { TForm1 }
  12.  
  13.   TForm1 = class(TForm)
  14.     Graph : TEvsSimpleGraph;
  15.     procedure FormCreate(Sender: TObject);
  16.  
  17.   private
  18.     procedure SendToClipBoard(aGraph : TEvsSimpleGraph; SrcRect : TRect);
  19.  
  20.   public
  21. end;
  22.  
  23. var
  24.   Form1: TForm1;
  25.  
  26. implementation
  27. {$R *.lfm}
  28.  
  29. procedure TForm1.FormCreate(Sender: TObject);
  30. begin
  31.   Graph:=TEvsSimpleGraph.Create(Self);
  32.   Graph.Align:=alClient;
  33.   Graph.Parent:=Self;
  34.   Graph.InsertNode(Rect(50,50,100,100)).Pen.Color:=clRed;
  35.   SendToClipBoard(Graph,Rect(49,49,111,111));
  36. end;
  37.  
  38. procedure TForm1.SendToClipBoard(aGraph : TEvsSimpleGraph; SrcRect : TRect);
  39. var
  40.   BmpSrc,BmpDst : TBitmap;
  41.   DstRect : TRect;
  42. begin
  43.   BmpSrc:=TBitmap.Create;
  44.   BmpDst:=TBitmap.Create;
  45.   aGraph.CopyToGraphic(BmpSrc);
  46.   DstRect:=Rect(0,0,SrcRect.Width,SrcRect.Height);
  47.   BmpDst.Width:=DstRect.Width;
  48.   BmpDst.Height:=DstRect.Height;
  49.   BmpDst.Canvas.CopyRect(DstRect,BmpSrc.Canvas,SrcRect);
  50.   Clipboard.Assign(BmpDst);
  51.   BmpSrc.Free;
  52.   BmpDst.Free;
  53. end;
  54.  
  55. end.  
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Problems with TClipboard
« Reply #10 on: December 24, 2017, 12:09:59 pm »
The draw method calls owner.gptocp which uses the scrollbar's position to determine if the graph is visible or not, which comes in direct conflict with the code of the bitmap canvas which is already shifted to the correct position. I need to attach a TEvsGraphCanvas to the bitmap and use the canvas to answer the visibility question. Sorry I did not had time to spend on the problem yet, holidays and all that.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

simone

  • Hero Member
  • *****
  • Posts: 573
Re: Problems with TClipboard
« Reply #11 on: December 24, 2017, 12:20:47 pm »
Thanks Taazz for explanations! I thought that in this case the problem was in my code, not in the external component.
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Problems with TClipboard
« Reply #12 on: December 24, 2017, 12:38:13 pm »
you can test your code by saving the BmpSrc (before calling copyrect) and BmpDst(after copyrect is called) on disk and check the differences. If there are differences then the most suspect portion would be the pixelformat of the BmpSrc try after calling CopyToGraphic to set the pixel format to pf24bit.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

simone

  • Hero Member
  • *****
  • Posts: 573
Re: Problems with TClipboard
« Reply #13 on: December 24, 2017, 05:23:26 pm »
It seems that something  goes wrong with Canvas.CopyRect... See attached images...
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: Problems with TClipboard
« Reply #14 on: December 24, 2017, 11:24:36 pm »
I assume you want to be able to send a complete canvas of your work elsewhere and
are trying to get it from the GUI surface? If that being the case, you maybe in a
world of hurt if the canvas requires a scrollbar to see all of it..

 The best solution I have come up with via and app I am currently working on is
to make a master procedure or some procedures that accept a Canvas as a
parameter on the input.

 From there,  you can select a Bitmap as a canvas, a printer.canvas etc.
 
P.S.

 there are some strange effects with Tbitmaps with the initial setup..

 Create the Bitmap, Set the Pixel format, Width and height then finally

 MyNewBitMap.Canvas.Changed;

 this creates a proper GDI mapped bitmap...
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018