Print Memo

How can I print the contents of a Memo-component? I prefer a few simple lines of code.
detempelAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

rarigoCommented:
Hi Detempel,

   How about this:

   MyMemo.Lines.Add('This');
   MyMemo.Lines.Add('That');
   MyMemo.Print(' ');?


Tchau,
Reginaldo

   


   
0
detempelAuthor Commented:
The component Memo has no method Print!
0
karooCommented:
detempel,

how bout painting to the printer cancvas i.e.

 Printer.BeginDoc;
 Memo1.PaintTo(Printer.Handle, 10, 10);
 Printer.EndDoc;

haven't tried this with a memo yet

regards Ben:)
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

karooCommented:
oops  
>>cancvas
meant canvas
0
detempelAuthor Commented:
The component Memo has no method Print!
0
detempelAuthor Commented:
Sorry for my last repeated comment. I refreshed my answer and consequently resend my latest comment.
0
karooCommented:
detempel,

looked at it again and i think using the Printers TextOut method is a better option:

procedure TForm1.Button1Click(Sender: TObject);
var
 I: Integer;
begin
 Printer.BeginDoc;
 for I := 0 to Memo1.Lines.Count -1 do
  Printer.Canvas.TextOut(10, I * 100, Memo1.Lines[I]);
 Printer.EndDoc;
end;
0
detempelAuthor Commented:
Hi Ben,

I tried your code. I get an error message immediately because you need 'Printers' in the 'uses clause'.

After adding 'Printers' in the 'uses clause' I get a printout!

Alas it's very small. Probably because the method 'PaintTo' is meant for graphics instead of text. Also there's a border line above the text and to the left of the text.

I prefer a way to print the contents of the Memo-component as text and not as graphics.

Erik.
0
karooCommented:
hi Erik:),

Yep, it's sending a bitmap, try using the TextOut method above, the only thing that i don't particularly like about it is the x and y coordinates which *i think* can differ depending on the printer.
Also, you will have to check the amount of lines you send to the printer and use the Printer.NewPage accordingly.

best of luck Ben:)
0
intheCommented:
{+------------------------------------------------------------
| Procedure PrintMemo
|
| Parameters:
|  aMemo: memo to print
|  centerVertical: true if output should be centered vertically
|  centerHorizontal: true if output should be centered
horizontally
| Call method:
|  static
| Description:
|  Prints the contents of a memo on the currently selected
|  printer, using the memos Font. The output can be centered
|  vertically and/or horizontally. Default margins will be used.
|  If the text does not fit onto one page the centerVertical
|  parameter is ignored.
| Error Conditions:
|  none
| Note:
|  requires Printers in the Uses clause.
|Created: 27.10.97 13:16:46 by P. Below
+------------------------------------------------------------}
Procedure PrintMemo( aMemo: TMemo;
                    centerVertical, centerHorizontal: Boolean );   Var
    topMargin, bottomMargin, leftMargin, rightMargin: Integer;
    x,y: Integer;
    maxLineLength: Integer;
    linecounter: Integer;
    lineheight : Integer;
  Begin
    { Set the default margins to 1 inch for top, bottom, 0.75 inch       for left and right margins. GetDeviceCaps is used to get the       printers resolution (dots per inch). The margin variables
      contain the position of the margin on paper, in dots, not the       distance from the border of the printing region! }
    topMargin := GetDeviceCaps( Printer.Handle, LOGPIXELSY );
    bottomMargin := Printer.PageHeight - topMargin;
 
    leftMargin := GetDeviceCaps( Printer.handle, LOGPIXELSX ) * 3 div 4;
    rightMargin := Printer.PageWidth - leftMargin;
 
    { Start the print job, assign the memo font to the printer
canvas.
      Note that we have to make sure the print job is closed
properly,
      thus the try finally block. }
    Printer.BeginDoc;
    try
      Printer.Canvas.Font.PixelsPerInch :=
        GetDeviceCaps( Printer.Canvas.Handle, LOGPIXELSY );
        { This is really only necessary for Delphi 1, due to a
          buglet. }
      Printer.Canvas.Font:= aMemo.Font;
 
      { Determine the height of a line in pixels }
      lineHeight := Printer.Canvas.TextHeight('Ay');
 
      If centerHorizontal Then Begin
        { Iterate once over all lines of the memo and determine the           length, in pixels, of the longest line. We need that to           adjust the leftMargin to center the text. }
        maxLineLength := 0;
        For linecounter := 0  To aMemo.Lines.Count-1 Do Begin
          x:= Printer.Canvas.TextWidth( aMemo.Lines[linecounter]);           If x > maxLineLength Then
            maxLineLength := x;
        End; { For }
 
        { Adjust the leftMargin to center the text into the
          available space between the current margins. }
        x := leftMargin +
            (rightMargin-leftMargin-maxLineLength) div 2;
        If x < leftMargin Then Begin
          { Problem, longest line does not fit into the available             space! We leave the margin untouched, the line will
            be truncated. }
        End { If }
        Else
          leftMargin := x;
      End; { If }
 
      If centerVertical Then Begin
        { Calculate the vertical space needed to print all lines,           adjust the topMargin to center the text as needed. }
        y := lineHeight * aMemo.Lines.Count;
        If y < (bottomMargin - topMargin) Then Begin
          topMargin :=
            topMargin + (bottomMargin - topMargin - y) div 2;
        End; { If }
        { Else
            space needed is larger than the height of a page,
            so ignore the center request. }
      End; { If }
 
      { Margins have been calculated, so we are finally set up
        to start printing lines. In the following code x and y
        hold the starting position of the next line. }
      x:= leftMargin;
      y:= topMargin;
      For linecounter := 0  To aMemo.Lines.Count-1 Do Begin
        Printer.Canvas.TextOut( x, y, aMemo.Lines[linecounter]);         y := y + lineHeight;
        If y >= bottomMargin Then Begin
          { Eject the page and start a new one, but only if
            the line we have just printed is not the last line
            anyway. EndDoc will eject the current page. }
          If linecounter < (aMemo.Lines.Count-1) Then Begin
            Printer.NewPage;
            y:= topMargin;
          End;
        End; { If }
      End; { For }
    finally
      Printer.EndDoc;
    end;
  End; { PrintMemo }
0
karooCommented:
Erik,

this works even better than the TextOut method i suggested:

procedure PrintStrings(Strings: TStrings);
var
  Prn: TextFile;
  I: Integer;
begin
  if Strings.Count = 0 then Exit;
  AssignPrn(Prn);
  try
    Rewrite(Prn);
    for I:= 0 to Strings.Count -1 do
      WriteLn(Prn, Strings.Strings[I]);
  finally
    CloseFile(Prn);
  end;
end;

regards Ben:)
0
detempelAuthor Commented:
Hi Ben,

PrintStrings is better. I already found it using the search-engine. However I get exactly the same results as when I used the method TextOut.

It would be nice if I could control the size of the text and the font I like to use.

Erik.

0
detempelAuthor Commented:
inthe,

Very third-generation-like code. But since I can use cut and paste I'm willing to give it a try.

Erik.
0
karooCommented:
Erik,

>>
It would be nice if I could control the size of the text and the font I like to use.
<<
you can:

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  Printer.BeginDoc;
  Printer.Canvas.Font.Style:= [fsBold, fsItalic];
  Printer.Canvas.Font.Size:= 10;
  //etc.
  for I := 0 to Memo1.Lines.Count -1 do
    Printer.Canvas.TextOut(10, I * 100, Memo1.Lines[I]);
  Printer.EndDoc;
end;
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
intheCommented:
hi
printing memos is a pain and maybe old code but it works ;-)
and this line will print in same font as whats in the memo
Printer.Canvas.Font:= aMemo.Font;
Regards..
0
detempelAuthor Commented:
Ben,

I prefer the procedure PrintStrings. Is there a way to change font-characteristics there? I don't want to know about pixels and coordinates like in the method TextOut and the procedure PrintMemo.

Erik.
0
IndefreiCommented:
Hi, Erik
I like barry's answer
(Hi, Pierre)
it gives you more possibilities to intervene

in a preview you could change the whole font with adding to
onFormactivate the getfontnames

function EnumFontsProc(var LogFont: TLogFont; var TextMetric: TTextMetric;
  FontType: Integer; Data: Pointer): Integer; stdcall;
begin
  TStrings(Data).Add(LogFont.lfFaceName);
  Result := 1;
end;

procedure TPreview1.GetFontNames;
var
  DC: HDC;
begin
  DC := GetDC(0);
  EnumFonts(DC, nil, @EnumFontsProc, Pointer(Schriftart.Items));
  ReleaseDC(0, DC);
  Schriftart.Sorted := True;
end;

adding a tcombobox for the fonts, a tedit for the fontsize and a tUpDown for scalinc the fontsize

procedure TPreview1.SchriftartChange(Sender: TObject);
begin

 Memo1.Font.Name := Schriftart.Items[Schriftart.ItemIndex];
end;

procedure Tpreview1.FontSizeChange(Sender: TObject);
begin
   memo1.Font.size:= StrToInt(Fontsize.text);
end;
a lot of answers and possibilities for just 50 pts
cheers
Indi
0
detempelAuthor Commented:
This answer doesn't meet my requirements. I want a simple solution.
0
detempelAuthor Commented:
Hi Indefrei,

I'm sorry but your answer is too complex. It's not that I don't understand it, but I don't want to dig in so deep.

Erik.
0
detempelAuthor Commented:
Hi Ben/karoo,

I want to give the points to you. So can you answer my question.

I'm using the PrintStrings-variant. I can change the Font-properties using 'Printer.Canvas.Font'. This way I don't have to worry about coordinates and stuff.

Thanks,
Erik.
0
IndefreiCommented:
No problem
Like to see interested and promptly reacting people like you
thanks
Indi
0
edeyCommented:
Perhaps it would be easier just to use a TRichEdit, no?  Unless there is a very good reason to stick with the plaintext TMemo, a TRichEdit offers a lot more functionality, including a print method.


GL
Mike
0
detempelAuthor Commented:
Thanks for your help.

Erik.
0
detempelAuthor Commented:
Hi Edey,

Good suggestion. I think I'm going to use the RichEdit-component like you suggested since it has a Print-method. I've given my points to 'karoo' already because he helped me on the way on my 'memo-quest'. Hope you don't mind that I'm giving the points to him/her.

Thanks,
Erik.
0
karooCommented:
Erik,

>>him/her
him:)

glad to have helped, sorry i didn't get a chance to respond to your last comment directed to me, see that you figured it out anyway.
good luck:)
Ben.
0
MasterOfDisasterCommented:
Hi, well the  PrintMemo procedure works fine, but I've still a little problem, how can I print #9 tabs with it?? I just get ugly unprintable signs :(
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.