Virtual-TreeView icon indicating copy to clipboard operation
Virtual-TreeView copied to clipboard

Paint into device context via PrintTo or WM_PRINT

Open Deeem2031 opened this issue 8 years ago • 5 comments

Hello, i'm trying to use the virtual-treeview and paint a copy of it (and other controls) into a panel. To accomplish this i used the TWinControl.PaintTo-routine which works well with other controls but the virtual-treeview is missing the header when using PaintTo. I did some research but couldn't figure out why it is missing. Besides that I tried using WM_PRINT, which seems to work better as it does paint the header but kinda messes with the border. So both ways aren't perfect. I uploaded a delphi 10.1 project to demonstrate the problem on my personal webspace (as github seems to refuse it for no apparent reason...): VirtualTreeCopy.zip

Deeem2031 avatar Jul 12 '16 09:07 Deeem2031

as github seems to refuse it for no apparent reason...

Strange, it worked for me. Demo project: #632.zip

joachimmarder avatar Jul 12 '16 20:07 joachimmarder

i'm trying to use the virtual-treeview and paint a copy of it (and other controls) into a panel.

May I ask why you want to do that?

I did some research but couldn't figure out why it is missing

This must be related to the fact that TBaseVirtualTree.WMPaint() paints the header using GetDCEx(), and TBaseVirtualTree.Paint() uses Canvas. There is already an if-condition in WMPaint() that checks for csPaintCopy, which is set in case CopyTo()was used. I have no ideas why this was made that way in the past.

joachimmarder avatar Jul 12 '16 20:07 joachimmarder

May I ask why you want to do that?

The goal is to fade out the content of a form so the user is aware that he can't use the form right now. To achieve this the content of the form is drawn into a bitmap (with PaintTo) and this image (once mixed with a bit gray) is painted over the form.

This must be related to the fact that TBaseVirtualTree.WMPaint() paints the header using GetDCEx(), and TBaseVirtualTree.Paint() uses Canvas. There is already an if-condition in WMPaint() that checks for csPaintCopy, which is set in case CopyTo() was used.

Yes, if i change the GetDCEx() to something like

if csPaintCopy in ControlState then
  DC := Message.DC
else
  DC := GetDCEx(Handle, 0, DCX_CACHE or DCX_CLIPSIBLINGS or DCX_WINDOW or DCX_VALIDATE);

the Header is being drawn but over the first node/child. Easily reproducible by adding FVT.AddChild(nil); in FormCreate(). So it's not as easy as that because the PaintTree() already messes up the vertical position of all nodes in case you use PaintTo(). This also explains the black bar at the bottom of the PaintTo-Copy. virtualtree_ 632

Deeem2031 avatar Jul 14 '16 15:07 Deeem2031

This also explains the black bar at the bottom of the PaintTo-Copy.

I also noticed that, I guess the viewport is shifted here, or the client area is defined differently.

joachimmarder avatar Jul 14 '16 19:07 joachimmarder

I have the same problem as originally reported by Deeem2031. It is apparent any time a VST is PaintTo a bitmap canvas or even if it is on a form and you use GetFormImage to get the form's image onto a canvas. I have an idea that the problem is caused by the fact that the VST ClientRect does not include the vst.Header area.

gthorn avatar Sep 02 '18 14:09 gthorn