Ver Mensaje Individual
  #2  
Antiguo 12-07-2011
x_aguilarf x_aguilarf is offline
Miembro
 
Registrado: abr 2006
Posts: 22
Reputación: 0
x_aguilarf Va por buen camino
A la primera pregunta, un solución seria modificar la función PaintTo del TWinControl para que al dibujar no limite al tamaño del control y utilizar esta función para dibujar en un TBitmap y finalmente imprimirlo.

Esto seria un ejemplo:

Código Delphi [-]

...

implementation

uses
  Math;

type
  TWC = class(TWinControl) end;

function GetPaintAllBmp(AControl: TWinControl): TBitmap;

  procedure PaintAllTo(AControl: TWinControl; DC: HDC; X, Y: Integer);

    procedure DrawThemeEdge(DC: HDC; var DrawRect: TRect);
    var
      Details: TThemedElementDetails;
      Save: Integer;
    begin
      Save := SaveDC(DC);
      try
        with DrawRect do
          ExcludeClipRect(DC, Left + 2, Top + 2, Right - 2, Bottom - 2);
        Details := ThemeServices.GetElementDetails(teEditTextNormal);
        ThemeServices.DrawElement(DC, Details, DrawRect);
      finally
        RestoreDC(DC, Save);
      end;
      InflateRect(DrawRect, -2, -2);
    end;

  var
    w, h: Integer;
    I, EdgeFlags, BorderFlags, SaveIndex: Integer;
    R: TRect;
  begin

    w := AControl.ClientWidth;
    h := AControl.ClientHeight;

    for I := 0 to AControl.ControlCount - 1 do
    begin
      w := Max(w, AControl.Controls[i].Left + AControl.Controls[i].Width);
      h := Max(h, AControl.Controls[i].Top + AControl.Controls[i].Height);
    end;

    SaveIndex := SaveDC(DC);
    try
      MoveWindowOrg(DC, X, Y);
      IntersectClipRect(DC, 0, 0, w, h);
      BorderFlags := 0;
      EdgeFlags := 0;
      if GetWindowLong(AControl.Handle, GWL_EXSTYLE) and WS_EX_CLIENTEDGE <> 0 then
      begin
        EdgeFlags := EDGE_SUNKEN;
        BorderFlags := BF_RECT or BF_ADJUST
      end else
      if GetWindowLong(AControl.Handle, GWL_STYLE) and WS_BORDER <> 0 then
      begin
        EdgeFlags := BDR_OUTER;
        BorderFlags := BF_RECT or BF_ADJUST or BF_MONO;
      end;
      if (EdgeFlags = EDGE_SUNKEN) and ThemeServices.ThemesEnabled and
        not ((csDesigning in AControl.ComponentState) and UnthemedDesigner(AControl)) then
      begin
        SetRect(R, 0, 0, w, h);
        if csNeedsBorderPaint in AControl.ControlStyle then
          DrawThemeEdge(DC, R)
        else
        begin
          AControl.ControlStyle := AControl.ControlStyle + [csNeedsBorderPaint];
          AControl.ControlStyle := AControl.ControlStyle - [csNeedsBorderPaint];
        end;
        MoveWindowOrg(DC, R.Left, R.Top);
        IntersectClipRect(DC, 0, 0, R.Right - R.Left, R.Bottom - R.Top);
      end
      else if BorderFlags <> 0 then
      begin
        SetRect(R, 0, 0, w, h);
        MoveWindowOrg(DC, R.Left, R.Top);
        IntersectClipRect(DC, 0, 0, R.Right - R.Left, R.Bottom - R.Top);
      end;

      AControl.Perform(WM_PAINT, DC, 0);
      for I := 0 to AControl.ControlCount - 1 do
        if AControl.Controls[i] is TWinControl then
          with AControl.Controls[i] do
            if Visible then
              PaintAllTo(AControl.Controls[i] as TWinControl, DC, Left, Top);
    finally
      RestoreDC(DC, SaveIndex);
    end;

  end;
var
  I: Integer;
  w,h: Integer;
begin

  w := AControl.ClientWidth;
  h := AControl.ClientHeight;

  for I := 0 to AControl.ControlCount - 1 do
  begin
    w := Max(w, AControl.Controls[i].Left + AControl.Controls[i].Width);
    h := Max(h, AControl.Controls[i].Top + AControl.Controls[i].Height);
  end;

  Result := TBitmap.Create;
  Result.Canvas.Brush.Color := TWC(AControl).Color;
  Result.SetSize(w, h);
  Result.Canvas.Lock;
  try
    PaintAllTo(AControl, Result.Canvas.Handle, 0, 0);
  finally
    Result.Canvas.Unlock;
  end;

end;

...

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Ejemplo de utilización. (En este caso no hace falta destruir el resultado ya que la propiedad Picture de la imagen ya se ocupará de eso.)
  Image1.Picture.Assign(GetPaintAllBmp(Self));
end;

La función GetPaintAllBmp devuelve un Bitmap con todos los controles dibujados sin importar el tamaño del control principal.


A la segunda pregunta, dibujar el componente DBGrid entero es un problema diferente, ya que este componente no contiene subcomponentes sino que las filas son dibujadas, y solo unas filas son visibles dependiendo de la posición del scroll. A falta de otra solución, yo haría lo que tu mismo has comentado, de manera manual, campo a campo.

Saludos
Responder Con Cita