Solved

How to print a StringGrid

Posted on 1999-01-19
13
558 Views
Last Modified: 2010-04-06
Hi everybody

How do I print a StringGrid, I have never written a printer function before so this is very new to me.

If anybody has a function showing how to print a text (it dosn't have to be a stringgrid, just to get some clues about printing, I would accept that).

I have also thought of coping the contents to a RichEdit and use that to print, but how do I get the handle the column width in a richedit.

I'm pretty sure I will get this answer... get TAdvStringGrid, yes I know great component, but I would like to have the printing code.

      Koger
0
Comment
Question by:koger
  • 6
  • 4
  • 2
  • +1
13 Comments
 
LVL 44

Expert Comment

by:bruintje
ID: 1362457
Hi koger,

You could copy your Grid to a Richedit component.

//for all the rows in your grid
for i := 0 to Grid.RowCount-1 do

//put them in a Richedit field lines and rows are TStrings
Richedit.Lines.Add := Grid1.Rows[index of your row]

//I'm not sure if the plaintext property of the Richedit must be true can't test it out here :O(
Richedit.print

Hope this helps
:O)

0
 
LVL 17

Expert Comment

by:inthe
ID: 1362458
here is some code for printing text files ,memos,richedits,etc:
first remember to add "printers" to your "uses" section.
 procedure TForm1.Button1Click(Sender:TObject);
 Var
TempStr : String;
 ToPrint : String;
 P,F : TextFile ;
 begin
 ToPrint := opendialog1.filename;{this will print the file you      specify or change to ToProint:=memo1.text or whatever }
AssignFile(F,ToPrint);
Reset(F);
AssignPrn(P);
ReWrite(P);
Printer.Canvas.Font.Name := 'Courier New';      Printer.Canvas.Font.Size := 10;
 While Not Eof(F) Do Begin
  ReadLn(F,TempStr);
   WriteLn(P,TempStr);
  End;
 CloseFile(F);
CloseFile(P);
 end;

plus there is some code at the url below about printing stringgrids.
Regards Barry

http://x6.dejanews.com/getdoc.xp?AN=191925315&CONTEXT=916789583.1348206866&hitnum=31
0
 

Author Comment

by:koger
ID: 1362459
This way the column width would be different depending on the length of the text in each cells.


I was just wondering couldn't I copy the grid to a bitmap or canvas and then print this.
0
 
LVL 44

Expert Comment

by:bruintje
ID: 1362460
Hmmmm.................
After some thinking I wrote a comment but before I did post it did look into the link inthe provided and it was almost the same so I think you should look there because it's what you asked for. And the column widt would be reserved if you set that to the greatest cellwidt in your grid.

:O)
0
 

Author Comment

by:koger
ID: 1362461
Here is the procedure I have written, but it dosn't work I have some problems.

1. How do I print the text without resize, in my function the whole bitmap is fit to only one page. I need the papersize, but how can I do that

2. When I print more than one page, each page is started as a new printer spool.

3. When I draw on the bitmap, I have to save the bitmap and the load it before I am able to print it, sounds weird and it is ;-)





var
  FromCol,ToCol, I, X,Y, iRow,iCol: integer;
  MyBitmap: tbitmap;
  R: TRect;
begin
  if PrintDialog1.Execute = True then
  begin
    Printer.Title := Form1.Caption;
    Printer.Copies := PrintDialog1.Copies;
    MyBitmap := TBitmap.Create;
    MyBitmap.Height := Printer.PageHeight;
    MyBitmap.Width := Printer.PageWidth;
    MyBitmap.Canvas.Font := SortGrid1.Font;

    FromCol := 0;
    ToCol := 1;
    repeat //scan Cols

      X := 0;
      for I := FromCol to SortGrid1.ColCount-1 do//Get Cols with width that fits page
      begin
        Inc(X, SortGrid1.ColWidths[I]);
        if X >= Printer.PageWidth then
          Inc(ToCol,1);
      end;

      Y := 0;
      iRow := 1;
      repeat //Scan rows
        Inc(Y, SortGrid1.RowHeights[iRow]);
        if Y <= Printer.PageHeight then
        begin //Add contents to bitmap
          for iCol := FromCol to ToCol do
          begin
            //X Offset
            X := 0;
            for I := FromCol to iCol do
              Inc(X, SortGrid1.ColWidths[I]);
            if iCol = 0 then
              X := 0;
            //Text Rect
            R := Rect(X,Y, X+SortGrid1.ColWidths[iCol], Y+SortGrid1.RowHeights[iRow]);
            //Draw on the Canvas
            mybitmap.Canvas.TextRect(R, X, Y, SortGrid1.Cells[iCol, iRow]);

            Inc(iRow,1);
          end;
        end
        else
        begin //print page
          Image1.Height := Printer.PageHeight;
          Image1.Width := Printer.PageWidth;
          Image1.Canvas.Draw(0,0,mybitmap);

          MyBitmap.SaveToFile('c:\tmp.bmp');
          try
            MyBitmap.LoadFromFile('c:\tmp.bmp');

            Printer.BeginDoc;
            Printer.Canvas.Draw(0,0, MyBitmap);
            Printer.EndDoc;
          finally
            MyBitmap.Free;
          end;

          Y := 0;
        end;
      until
        iRow >= SortGrid1.RowCount-1;

      FromCol := ToCol;//Scan missing cols
    until
      FromCol >= SortGrid1.ColCount-1;
  end;
end;

0
 
LVL 17

Expert Comment

by:inthe
ID: 1362462
id suggest have a look at c:\temp.bmp and see if the text is ok there cause i think were you  put
Image1.Height := Printer.PageHeight;
Image1.Width := Printer.PageWidth;
is whats resizing your text.
oh i see
change bitmaps height and width to equal stringgrid1.width and height not printer pageheight/width ,see how that turns out and come back
Regards Barry
ps  i'd test it myself but my bloody printer  ran out of black ink and it's 2'0'clock in the morning :-)

what do you want to happen when the bitmap is too long to fit on a page ,maybe do some size checking first then  make and print 2 bitmaps eh.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:koger
ID: 1362463
First sorry to be sending such large texts, but this function almost works.

i still need to make the page fit to the page, that I'm printing if anyone has a clue, I would be glad to here it.

procedure TSortGrid.Print;
  procedure AddToPage(FromCol,ToCol,iRow,Y:Integer);
  var
    iCol,X,I: Integer;
    R: TRect;
    FmtOpts: TFormatOptions;
  begin
//Alignment must be done another day
    for iCol := FromCol to ToCol do
    begin
      //X Offset
      X := 0;
      for I := FromCol to iCol-1 do
        Inc(X, ColWidths[I]+1);
      //Text Rect
      R := Rect(X,Y, X+ColWidths[iCol], Y+RowHeights[iRow]);
      //Get Cell Format
      InitializeFormatOptions(FmtOpts);
      //Now do the OnGetCellFormat event if necessary.
      if Assigned(fOnGetCellFormat) then
        fOnGetCellFormat(Self, iCol, iRow, GetCellDrawState(iCol,iRow), FmtOpts);
      Printer.Canvas.Font := FmtOpts.Font;
      //Draw on the Canvas
      Printer.Canvas.TextRect(R, X, Y, Cells[iCol, iRow]);
    end;
  end;
var
  FromCol,ToCol, I, X,Y, iRow: integer;
begin
  if Printer.Printers.Count = 0 then
  begin
    MessageDlg('No Printer is installed', mtError, [mbOK],0);
    Exit;
  end;

  Printer.Title := PrintOptions.fJobTitle;
  Printer.Copies := PrintOptions.fCopies;
  Printer.BeginDoc;
  FromCol := -1;
  ToCol := 0;
  //scan Cols
  repeat
    //Scan missing cols
    if FromCol = ToCol then
    begin
      Inc(FromCol);
      Inc(ToCol);
    end
    else
      FromCol := ToCol;
    //Get Cols with width that fits page
    X := 0;
    for I := FromCol to ColCount-1 do
    begin
      Inc(X, ColWidths[I]+1);
      if X <= Printer.PageWidth then
       ToCol := I;
    end;

    AddToPage(FromCol,ToCol,0,0);
    Y := RowHeights[0];
    iRow := 1;
    repeat //Scan rows
      Inc(Y, RowHeights[iRow]);
      if Y <= Printer.PageHeight then
      begin //draw contents to canvas
        AddToPage(FromCol,ToCol,iRow,Y);
        Inc(iRow);
      end
      else//New page
      begin
        Printer.NewPage;
        AddToPage(FromCol,ToCol,0,0);
      end;
      if (iRow = RowCount) and (ToCol < ColCount-1) and (Y <= Printer.PageHeight) then
        Printer.NewPage;
    until
      iRow = RowCount;
  until
    ToCol = ColCount-1;
  Printer.EndDoc;
end;

0
 
LVL 17

Expert Comment

by:inthe
ID: 1362464
hi there hows it going?,code looks good
i cant compile any of above to try what is TFormatOptions ?
when you say "make the page fit to the page, that I'm printing"
are you saying you want the graphic to print to be the same width as the paper your printing on?how wide is the grid,is it wider than the paper or is paper wider than grid?

does'nt:
if X <= Printer.PageWidth then
       ToCol := I;
work?
below is another link  to take a quick look at ,about printing a ascii file using a string grid.probably not much help :-(


http://x2.dejanews.com/getdoc.xp?AN=217923914&CONTEXT=917140504.595853442&hitnum=40

Regards Barry

0
 

Author Comment

by:koger
ID: 1362465
Sorry some stuff from my TSortGrid component, just replace it with canvas := stringgrid1.font or something ;-)

I should do but when I print the grid, something unreadable is printet, I think it's because the contents of the grid isn't fit corretly.
0
 

Author Comment

by:koger
ID: 1362466
Adjusted points to 200
0
 

Author Comment

by:koger
ID: 1362467
Print Pixel scale

hi

I'm doing some textout to the printer.canvas, and having trouble specifing the y-offset for the next line. I'm printing from a stringgrid, and I thought that the rowheight could be the y-offset but on the printer.canvas this value must be around 2.5 larger or the lines are drawed on top of each other.
How to I get this const to multiply with stringgrid.rowheight, I sure it changes from printer to printer, depending on the paper and printer resolution.
0
 
LVL 17

Expert Comment

by:inthe
ID: 1362468
hi again,
i been tring this for ages and cant get it to work either but i dont have much time so i give you another link to take a look at
lots of code here.
http://x11.dejanews.com/getdoc.xp?AN=431890822&CONTEXT=917507925.2051997828&hitnum=1

Regards Barry
0
 
LVL 8

Accepted Solution

by:
ZifNab earned 200 total points
ID: 1362469
As you asked koger, I'll answer the question :-)

Hi koger,

As I understand your question, then your looking for the difference of pixels between screen and printer? Correct?

If so, this should be a solution :

XPixelsPerInch := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
YPixelsPerInch := GetDeviceCaps(Printer.Handle, LOGPIXELSY);

And screen.PixelsPerInch gives you the pixels per inch of your screen...

so devide these two and you get your constant...

or am I wrong?

Regards, Zif.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
This video discusses moving either the default database or any database to a new volume.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now