我有一个TREEVIEW控件,由于上面加载了图片,所以很大,
远远超出了屏幕的范围.
请问怎样才能把整个TREEVIEW载入下来保存到BMP或JPG文件中?

解决方案 »

  1.   

    获取控件句柄,通过API中的屏幕抓取函数,根据控件的坐标来抓取
      

  2.   

    用Canvas去做,给你一段代码,还有一个旋转的功能,一起看看吧。procedure PaneltoPic(pan: Tpanel; Pic: string; bprint:boolean=false);
    var
      bmp , bmp1: TBitmap;
      jpg : TJPEGImage;
      i, x, y, w, h : Integer;
      p : TPoint;
      image1: Timage;
    begin
      bmp := TBitmap.Create;//首先创建一个BMP图像,准备把VG图形画到此BMP上
      bmp1 := TBitmap.Create;
      jpg := TJPEGImage.Create; //首先创建一个JPG图像,准备把BMP转化为JPG格式
      image1:= Timage.Create(nil);
      {x := round( pan.Left);
      y := round( pan.Top);
      w := round( pan.Width );
      h := round( pan.Height );
      bmp.Width := w ;//+1;
      bmp.Height := h ; //得到BMP的大小,好让所有VG图形都能画到BMP上去  }
      x := round( pan.Left+1 );
      y := round( pan.Top+1 );
      w := round( pan.Width-3 );
      h := round( pan.Height-3 );
      bmp.Width := w+1 ;//+1;
      bmp.Height := h + 1; //得到BMP的大小,好让所有VG图形都能画到BMP上去
      bmp.Canvas.Lock;
      bmp1.Height := w+1 ;//+1;
      bmp1.Width := h + 1; //得到BMP的大小,好让所有VG图形都能画到BMP上去  SetViewportOrgEx( bmp.Canvas.Handle, round( pan.Left ) - x, round( pan.Top ) - y, @p ); //设置BMP画布的原点,
      //SetViewportOrgEx( bmp.Canvas.Handle, 0, 0, @p ); //设置BMP画布的原点,
      pan.PaintTo(  bmp.Canvas,0,0 );//利用PaintTo把VG的所有图形一个个地画到BMP的画布里。  SetViewportOrgEx( bmp.Canvas.Handle, p.x, p.y, nil );  bmp.Canvas.Unlock;
      RotateBitmap(bmp, bmp1,90);  bmp1.SaveToFile(Pic);  jpg.Free;  bmp.Free;
      bmp1.Free;
      image1.Free;end;procedure   RotateBitmap(ASrcBmp,   ADestBmp:   TBitmap;   AAngle:   double);
    var
        cosTheta:   double;
        i:   integer;
        iOriginal:   integer;
        iPrime:   integer;
        j:   integer;
        jOriginal:   integer;
        jPrime:   integer;
        RowOriginal:   pRGBArray;
        RowRotated:   pRGBArray;
        sinTheta:   double;
        OldPixelFormat:   TPixelFormat;
        NewCX,   NewCY:   integer;
        OldCX,   OldCY:   integer;
        TranspColor:   TRGBTriple;
    begin
        OldPixelFormat   :=   ASrcBmp.PixelFormat;
        ASrcBmp.PixelFormat   :=   pf24bit;
        sinTheta   :=   Sin(-AAngle   *   pi   /   180);
        cosTheta   :=   Cos(-AAngle   *   pi   /   180);
        ADestBmp.Width     :=   abs(round(ASrcBmp.Height   *   sinTheta))   +   abs(round(ASrcBmp.Width   *   cosTheta));
        ADestBmp.Height   :=   abs(round(ASrcBmp.Width   *   sinTheta))   +   abs(round(ASrcBmp.Height   *   cosTheta));
        ADestBmp.PixelFormat   :=   pf24bit;
        if   ASrcBmp.Transparent   then
        begin
            TranspColor.rgbtBlue   :=   (ASrcBmp.TransparentColor   and   $FF0000)   shr   16;
            TranspColor.rgbtGreen   :=   (ASrcBmp.TransparentColor   and   $00FF00)   shr   8;
            TranspColor.rgbtRed   :=   (ASrcBmp.TransparentColor   and   $0000FF);
        end   else
        begin
            TranspColor.rgbtBlue   :=   255;
            TranspColor.rgbtRed   :=   0;
            TranspColor.rgbtGreen   :=   0;
        end;
        OldCX   :=   ASrcBmp.Width   div   2;
        OldCY   :=   ASrcBmp.Height   div   2;
        NewCX   :=   ADestBmp.Width   div   2;
        NewCY   :=   ADestBmp.Height   div   2;
        for   j   :=   ADestBmp.Height   -   1   downto   0   do
        begin
            RowRotated     :=   ADestBmp.Scanline[j];
            jPrime   :=   (j   -   NewCY);
            for   i   :=   ADestBmp.Width   -   1   downto   0   do
            begin
                iPrime   :=   (i   -   NewCX);
                iOriginal   :=   Round(iPrime   *   CosTheta   -   jPrime   *   sinTheta)   +   OldCX;
                jOriginal   :=   Round(iPrime   *   sinTheta   +   jPrime   *   cosTheta)   +   OldCY;
                if   (iOriginal   >=   0)   and   (iOriginal   <=   ASrcBmp.Width   -   1)   and
                    (jOriginal   >=   0)   and   (jOriginal   <=   ASrcBmp.Height   -   1)   then
                begin
                    RowOriginal   :=   ASrcBmp.Scanline[jOriginal];
                    RowRotated[i]     :=   RowOriginal[iOriginal]
                end   else
                begin
                    RowRotated[i]   :=   TranspColor;
                end;
            end;
        end;
        ASrcBmp.PixelFormat   :=   OldPixelFormat;
    end;
      

  3.   

    二楼的朋友,你好.
    你的代码只能截取一部份.
    不能截全部.
    因为我的TREE控件内容很多,屏幕并不能显示全部,已经出现了滚动条,我是想把滚动条下面的也截下来.
    如果可以的话.
      

  4.   

    如果超出外面的话,控件也不绘制的,你是截图不了的;除非是一些像Timage之类的内部存在picture 才可以的吧;
    这是我的想法;就像你截图Form的界面也是一样的,在屏幕外面的就截图不了了;
      

  5.   

    PrintWindow 只能截取一部分吧?
      

  6.   


    这样可不可以?把 TreeView 放到 Form2 中,再放大到屏幕以外,最大 32767x32767-----
      TForm1 = class(TForm)
        tv1: TTreeView;
        btn1: TButton;
        btn2: TButton;
        procedure btn1Click(Sender: TObject);
        procedure btn2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    -----
      TForm2 = class(TForm)
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    -----{ 自定义函数,放大窗体 }
    procedure BigFormSize(Form: TForm; Width, Height: Cardinal);
    begin
      SetWindowLong(Form.Handle, GWL_STYLE, not(WS_THICKFRAME) and
        GetWindowLong(Form.Handle, GWL_STYLE) or Integer(WS_POPUP));
      SetWindowPos(Form.Handle, 0, 0, 0, Width, Height, SWP_NOZORDER or SWP_NOMOVE);
    end;{ 全局变量,保存 TreeView 原始位置和大小 }
    var
      P: TPoint;
      W, H: Integer;{ 放大 }
    procedure TForm1.btn1Click(Sender: TObject);
    begin
      P.X := tv1.Left;
      P.Y :=  tv1.Top;
      W := tv1.Width;
      H := tv1.Height;  tv1.Parent := Form2;
      tv1.Align := alCLient;
      BigFormSize(Form2, 32767, 32767);
      Form2.Show;
    end;{ 还原 }
    procedure TForm1.btn2Click(Sender: TObject);
    begin
      tv1.Align := alCustom;
      tv1.Left := P.X;
      tv1.Top :=  P.Y;
      tv1.Width := W;
      tv1.Height := H;
      tv1.Parent := Form1;
      Form2.Close;
    end;
      

  7.   

    PrintWindow 在屏幕外的也能截,先把控件放大到没有滚动条再用PrintWindow