2005. július 9., szombat

Print a TListView


Problem/Question/Abstract:

I have a TListView component on my form. When I call listview1.paintto(printer.handle,30,30), where listview1 is of type TListView, the content of the grid is printed like expected, but the column headings are not printed. Is this a (windows?) bug or is it just me using the PaintTo the wrong way?

Answer:

It is no bug, just a problem caused by the way PaintTo works. Basically it sends a WM_PAINT message to a control with a canvas handle in wparam. This tells the control to paint its client area to the canvas. The problem in your case is that the listview header is not part of the listviews client area, it is an embedded header control. So you need to send that one a paint message as well. Unfortunately it has no VCL wrapper control, so PaintTo cannot be used. There is a little-known Windows message that can be used as alternative to WM_PAINT. The problem is that not all controls seem to implement it. But TListview does:

procedure TForm1.Button1Click(Sender: TObject);
var
  bmp: TBitmap;
begin
  bmp := Tbitmap.Create;
  try
    bmp.width := listview1.width;
    bmp.height := listview1.height;
    with bmp.canvas do
    begin
      Lock;
      try
        listview1.perform(WM_PRINT, handle, PRF_CHILDREN or PRF_CLIENT or
          PRF_NONCLIENT or PRF_ERASEBKGND);
      finally
        Unlock
      end;
      image1.picture.bitmap := bmp;
    end;
  finally
    bmp.free
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése