Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 19-03-2013
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 227
Poder: 14
darkamerico Va por buen camino
Smile Rutina de Impresion TRichEdit

Saludos amigos, estoy intentando acoplar una rutina de impresion a los documentos de mi sistema de Control Documentario, al presionar el boton Imprimir aparece una ventana donde el usuario fija los margenes en cm y el numero de copias, luego finalmente un boton Listo con el siguiente codigo:

Código Delphi [-]
procedure TForm5.PrintRichEdit(Rich: TRxRichEdit; LMargin, RMargin, TMargin, BMargin: real;
  Copies: integer; JobTitle: string);
var
  Loff, TOff, ROff, BOff   : integer;
  XRes, YRes, XOffs, YOffs : integer;
  R: TRect;
begin
  // Set the margins
   { set your needed values in milimeters }
  LOff := Trunc(StrToFloat(txtMIzq.Text)*10);
  TOff := Trunc(StrToFloat(txtMSup.Text)*10);
  ROff := Trunc(StrToFloat(txtMDer.Text)*10);
  BOff := Trunc(StrToFloat(txtMInf.Text)*10);
  { Get printer data }
  XOffs := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX ); { minimum Left offset }
  YOffs := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY ); { minimum Top offset }
  XRes := GetDeviceCaps(Printer.Handle, LOGPIXELSX); { points per inch in X }
  YRes := GetDeviceCaps(Printer.Handle, LOGPIXELSY); { points per inch in Y }
  {Change Your values to printer Units }
  LOff := Round(LOff*XRes/25.4)-XOffs; { of course You can't set margins less than min offset !!! }
  TOff := Round(TOff*YRes/25.4)-YOffs; { of course You can't set margins less than min offset !!! }
  ROff := 2490-Round(ROff*XRes/25.4)-XOffs; { changing to width, not offset !!!}
  BOff := 3510-Round(BOff*YRes/25.4)-YOffs; { changing to height, not offset !!!}

  Rich.PageRect := Rect( LOff, TOff, ROff, BOff );
  // Print the desired number of copies
  while Copies > 0 do begin
    Application.ProcessMessages;
    Rich.Print(JobTitle);
    Dec(Copies);
  end;
end;

El evento click del boton que llama a la funcion anterior es:

Código Delphi [-]
procedure TForm5.Button1Click(Sender: TObject);
begin
  PrintRichEdit(form2.docView, StrToFloat(txtMIzq.Text), StrToFloat(txtMDer.Text), StrToFloat(txtMSup.Text), StrToFloat(txtMInf.Text), cboNumCopias.Value, form2.DBMemo1.Text);
end;


La idea es imprimir solo documentos de 1 pagina en formato A4, pero esta rutina me imprime pequeñas pociones del documento, y las saca en 4 paginas, al parecer los margenes no cuadran, requiero de su ayuda amigos para ver este caso.

Gracias

Americo
Responder Con Cita
  #2  
Antiguo 19-03-2013
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 227
Poder: 14
darkamerico Va por buen camino
Smile Amigos

Sin esta caracteristica ningun sistema que maneje documentos con componentes TRichEdit, TRxRichEdit, TcxRichEdit, estará completa, invito a quien haya resuelto este topico a compartir el codigo.

[-] Requerimiento: Una funcion que permita fijar los márgenes, el numero de copias y si fuera posible un Preview del documento.

Muchas Gracias
Responder Con Cita
  #3  
Antiguo 19-03-2013
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola darkamerico.

Sé que no es respuesta a tu pregunta pero, ¿ Has descartado por algo en especial el uso de un reporter ?

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #4  
Antiguo 19-03-2013
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 227
Poder: 14
darkamerico Va por buen camino
Wink Me parece estar cerca...

Encontre esta super funcion:

Código Delphi [-]
procedure TForm5.Button1Click(Sender: TObject);
var
  wPage, hPage, xPPI, yPPI, wTwips, hTwips: integer;
  pageRect, rendRect: TRect;
  po: TPageOffset;
  fr: TFormatRange;
  lastOffset, currPage, pageCount: integer;
  xOffset, yOffset: integer;
  FPageOffsets: array of TPageOffset;
  TextLenEx: TGetTextLengthEx;
  firstPage: boolean;
begin
  //First, get the size of a printed page in printer device units
  wPage := GetDeviceCaps(Printer.Handle, PHYSICALWIDTH);
  hPage := GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT);
  //Next, get the device units per inch for the printer
  xPPI := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
  yPPI := GetDeviceCaps(Printer.Handle, LOGPIXELSY);
  //Convert the page size from device units to twips
  wTwips := MulDiv(wPage, 1440, xPPI);
  hTwips := MulDiv(hPage, 1440, yPPI);
  //Save the page size in twips
  with pageRect do
  begin
    Left := 0;
    Top := 0;
    Right := wTwips;
    Bottom := hTwips
  end;
  //Next, calculate the size of the rendering rectangle in twips
  //Rememeber - two inch margins are hardcoded, so the below code
  //reduces the width of the output by four inches
  with rendRect do
  begin
    Left := 0;
    Top := 0;
    Right := pageRect.Right - (1440 * 4);
    Bottom := pageRect.Bottom - (1440 * 4)
  end;
  //Define a single page and set starting offset to zero
  po.mStart := 0;
  //Define and initialize a TFormatRange structure. This structure is passed
  //to the TRichEdit with a request to format as much text as will fit on a
  //page starting with the chrg.cpMin offset and ending with the chrg.cpMax.
  //Initially, we tell the RichEdit control to start at the beginning
  //(cpMin = 0) and print as much as possible (cpMax = -1). We also tell it
  //to render to the printer
  with fr do
  begin
    hdc := Printer.Handle;
    hdcTarget  := Printer.Handle;
    chrg.cpMin := po.mStart;
    chrg.cpMax := -1;
  end;
  //In order to recognize when the last page is rendered, we need to know how
  //much text is in the control.
  if RichEditVersion >= 2 then
  begin
    with TextLenEx do
    begin
      flags := GTL_DEFAULT;
      codepage := CP_ACP;
    end;
    lastOffset := SendMessage(form2.docView.Handle, EM_GETTEXTLENGTHEX, wParam(@TextLenEx), 0)
  end
  else
    lastOffset := SendMessage(form2.docView.Handle, WM_GETTEXTLENGTH, 0, 0);
  //As a precaution, clear the formatting buffer
  SendMessage(form2.docView.Handle, EM_FORMATRANGE, 0, 0);
  //Printers frequently cannot print at the absolute top-left position on the
  //page. In other words, there is usually a minimum margin on each edge of the
  //page. When rendering to the printer, RichEdit controls adjust the top-left
  //corner of the rendering rectangle for the amount of the page that is
  //unprintable. Since we are printing with two-inch margins, we are presumably
  //already within the printable portion of the physical page.
  SaveDC(fr.hdc);
  SetMapMode(fr.hdc, MM_TEXT);
  xOffset := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);
  yOffset := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY);
  xOffset := xOffset + MulDiv(1440 + 1440, xPPI, 1440);
  yOffset := yOffset + MulDiv(1440 + 1440, yPPI, 1440);
  SetViewportOrgEx(fr.hdc, xOffset, yOffset, nil);
  //Now we build a table of page entries, one entry for each page that would be
  //printed.
  while ((fr.chrg.cpMin <> -1) and (fr.chrg.cpMin < lastOffset)) do
  begin
    fr.rc := rendRect;
    fr.rcPage := pageRect;
    po.mStart := fr.chrg.cpMin;
    fr.chrg.cpMin := SendMessage(form2.docView.Handle, EM_FORMATRANGE, 0, Longint(@fr));
    po.mEnd := fr.chrg.cpMin - 1;
    po.rendRect := fr.rc;
    if High(FPageOffsets) = -1 then SetLength(FPageOffsets, 1)
    else
      SetLength(FPageOffsets, Length(FPageOffsets) + 1);
    FPageOffsets[High(FPageOffsets)] := po
  end;
  pageCount := Length(FPageOffsets);
  ShowMessage(Format('Han sido enviadas %d paginas', [pageCount]));
  SendMessage(form2.docView.Handle, EM_FORMATRANGE, 0, 0);
  RestoreDC(fr.hdc, - 1);
  //Now, we are almost ready to actually print.
  Printer.BeginDoc;
  fr.hdc := Printer.Handle;
  fr.hdcTarget := Printer.Handle;
  SaveDC(fr.hdc);
  SetViewportOrgEx(fr.hdc, xOffset, yOffset, nil);
  //Ok, here we go to print
  firstPage := True;
  //At this point you can select from page and to page
  currPage := 0;  //Print from the first page
  pageCount := 1;  //Only One page for testing
  while (currPage < pageCount) do
  begin
    if firstPage then firstPage := False
    else
      Printer.NewPage;
    SetViewportOrgEx(fr.hdc, xOffset, yOffset, nil);
    fr.rc := FPageOffsets[currPage].rendRect;
    fr.rcPage := pageRect;
    fr.chrg.cpMin := FPageOffsets[currPage].mStart;
    fr.chrg.cpMax := FPageOffsets[currPage].mEnd;
    fr.chrg.cpMin := SendMessage(form2.docView.Handle, EM_FORMATRANGE, 1, Longint(@fr));
    Inc(currPage);
  end;
  //At this point, we have finished rendering the contents of the RichEdit
  //control. Now we restore the printer's HDC settings and tell Windows that
  //we are through printing this document
  RestoreDC(fr.hdc, - 1);
  Printer.EndDoc;
  //Finally, we clear the RichEdit control's formatting buffer and delete
  //the saved page table information
  fr.chrg.cpMin := SendMessage(form2.docView.Handle, EM_FORMATRANGE, 0, 0);
  Finalize(FPageOffsets);
  //That's it
  form5.Hide;
end;

Si alguien imprime con esta funcion notará que la impresion sale centrada en la pagina A4, sin embargo, los margenes de los 4 lados son excesivamente grandes, si alguien pudiera agregar a esta funcion los margenes en centimetros, este tema quedaria cerrado para siempre.


Atte

Americo
Responder Con Cita
  #5  
Antiguo 19-03-2013
alsn alsn is offline
Miembro
NULL
 
Registrado: abr 2012
Posts: 20
Poder: 0
alsn Va por buen camino
Volviendo a tu primera función, prueba de esta forma:

Código Delphi [-]
procedure TForm5.PrintRichEdit(Rich: TRxRichEdit; LMargin, RMargin, TMargin, BMargin: real;
  Copies: integer; JobTitle: string);
var
  Loff, TOff, ROff, BOff   : integer;
  XRes, YRes, XOffs, YOffs : integer;
  R: TRect;
begin
  // Set the margins
   { set your needed values in milimeters }
  LOff := Round(LMargin*10);
  TOff := Round(TMargin*10);
  ROff := Round(RMargin*10);
  BOff := Round(BMargin*10);

  { Get printer data }
  XOffs := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX ); { minimum Left offset }
  YOffs := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY ); { minimum Top offset }
  XRes := GetDeviceCaps(Printer.Handle, LOGPIXELSX); { points per inch in X }
  YRes := GetDeviceCaps(Printer.Handle, LOGPIXELSY); { points per inch in Y }

  {Change Your values to printer Units }
  LOff := Round(LOff*XRes/25.4);
  TOff := Round(TOff*YRes/25.4);
  ROff := Round(ROff*XRes/25.4);
  BOff := Round(BOff*YRes/25.4);
  if Loff < XOffs then Loff := XOffs;
  if TOff < YOffs then TOff := YOffs;
  if ROff < XOffs then ROff := XOffs;
  if BOff < YOffs then BOff := YOffs;

  Rich.PageRect := Rect( LOff, TOff, Printer.PageWidth-ROff, Printer.PageHeight-BOff);
  // Print the desired number of copies
  while Copies > 0 do begin
    Application.ProcessMessages;
    Rich.Print(JobTitle);
    Dec(Copies);
  end;
end;

Saludos
Responder Con Cita
  #6  
Antiguo 20-03-2013
darkamerico darkamerico is offline
Miembro
 
Registrado: dic 2010
Posts: 227
Poder: 14
darkamerico Va por buen camino
Cool Si funciona!

Interesante, funcionó, agradezco tu tiempo y dedicacion en este caso.


Atte

Americo
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Traducción de rutina JAVA waly2k1 JAVA 2 24-07-2010 10:27:10
Rutina muy lenta... KAYO Firebird e Interbase 10 04-07-2007 17:14:44
Impresión de una ficha con TRichEdit entre otros Pernorak C++ Builder 4 30-05-2007 13:54:59
Problemas con rutina seek JF Sebastian OOP 0 03-02-2007 13:44:20
No sale rutina SQl ............ Coco_jac SQL 2 30-11-2005 16:52:44


La franja horaria es GMT +2. Ahora son las 13:46:13.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi