0

I use Delphi 6.0, and I have TPanel, that contains TVirtualStringTree, that contains many nodes (more, than 1 screen).

I need to save this panel (with all nodes) to the BMP as a picture.

I use this method to save panel:

procedure TfrmDidTreeTime.cmSaveGantClick(Sender: TObject);
var
        bmp : tBitmap;
        cnt : Integer;
        Dc  : HDC;
        R   : TRect;
begin
        inherited;

        DC := GetDC ( pnlChart.handle);

        R := pnlChart.boundsRect;
        bmp := tBitmap.create;
        bmp.width := R.Right-R.Left;
        bmp.Height := R.Bottom - R.Top;
        Bitblt(bmp.canvas.handle,0,0,bmp.Width,bmp.height,dc,r.left,r.top,srccopy);

        spdSaveGraph.DefaultExt := 'bmp';
        spdSaveGraph.FileName := 'Gant.bmp';
        spdSaveGraph.Filter := 'Bitmap Picture|*.bmp';

        if spdSaveGraph.Execute then
                bmp.saveToFile (spdSaveGraph.FileName);

        bmp.free;
end;

But this method saves only nodes that shows on the screen, but I need to save all of nodes.

Vadim Kiselev
  • 1,030
  • 1
  • 8
  • 16
  • You won't be able to use Bitblt to save nterie contents of TVirualStringTree into a bitmap. The main reson for this is that TVirtualStringTree only renders part of its contents onto its Windows. It does this so that there is no performance impact when you have large amount of strings in it. – SilverWarior Sep 13 '19 at 08:05
  • 1
    Maybe you could override TVirtualStringTree default Paint method to force it to draw its entire contents into your BMP. I have never treid this myself – SilverWarior Sep 13 '19 at 08:07

1 Answers1

0
procedure TfrmDidTreeTime.cmSaveDidTreeTimeClick(Sender: TObject);
var
        bmp_total: tBitmap;
        bmp_current : tBitmap;

        r: TRect;
        dc: HDC;

        date_start: TDateTime;
        h: integer;

        bmp_current_position: integer;
        scroll_position_current: integer;
        scroll_position_total: integer;
        screen_count: integer;
begin
        inherited;

        date_start := dtpDateStart.Value;

        dc := GetDC (tvDidTimeTree.handle);
        r := tvDidTimeTree.boundsRect;

        bmp_total := tBitmap.create;
        bmp_total.width := r.Right - r.Left - sbxVertical.Width - 3;
        h := r.Bottom - r.Top - tvDidTimeTree.Header.Height;
        if h < 0 then
                h := 0;

        SendMessage(tvDidTimeTree.Handle, WM_VSCROLL, SB_BOTTOM, 0);

        scroll_position_total := GetScrollPos(tvDidTimeTree.Handle, sb_Vert);
        screen_count := round(scroll_position_total / h);

        bmp_total.Height := h * (screen_count + 1);
        bmp_current_position := 0;

        SendMessage(tvDidTimeTree.Handle, WM_VSCROLL, SB_TOP, 0);

        tvDidTimeTree.Repaint;

        while (scroll_position_current < scroll_position_total) do
        begin
                r := tvDidTimeTree.boundsRect;
                dc := GetDC (tvDidTimeTree.handle);

                bmp_current := tBitmap.create;
                bmp_current.width := r.Right - r.Left - sbxVertical.Width - 3;
                bmp_current.Height := h - 5;

                Bitblt(bmp_total.canvas.handle, 0, bmp_current_position, bmp_current.Width, bmp_current.height, dc, r.left, r.top, srccopy);
                scroll_position_current := GetScrollPos(tvDidTimeTree.Handle, sb_Vert);

                SendMessage(tvDidTimeTree.Handle, WM_VSCROLL, SB_PAGEDOWN, 0);

                tvDidTimeTree.Repaint;

                bmp_current_position := bmp_current_position + bmp_current.Height;
        end;

        spdSaveGraph.DefaultExt := 'bmp';
        spdSaveGraph.FileName := DateToStr(date_start) + '—' + DateToStr(IncMonth(date_start, 1)) + '.bmp';
        spdSaveGraph.Filter := 'Bitmap Picture|*.bmp';

        if spdSaveGraph.Execute then
                bmp_total.saveToFile (spdSaveGraph.FileName);

        bmp_total.free;
end;
Vadim Kiselev
  • 1,030
  • 1
  • 8
  • 16