Solved

Printing Question

Posted on 1998-12-15
19
177 Views
Last Modified: 2013-12-03
When I print, and the text is less than a page long, everything works fine.  But when it's over a page long, it just cuts off the text, and doesn't start a new page.  I am programming in C(not MFC or C++), using Win32 API.  Do I have to do page breaks manually?  If I do, how can I tell when to do the page break?  The function for printing takes a LPTSTR as it's only parameter...  Thanks!

~Aaron
0
Comment
Question by:BudVVeezer
  • 10
  • 7
  • 2
19 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 100 total points
ID: 1417295
Well, you have to send 'StartPage()'/'EndPage()' commands to your printer. To do this, you'll have to know about the text's extent (by calling 'GetTextExtentPoint32()') and about the phisical page size (available via 'Escape ( hdc, GETPHYSPAGESIZE,...)'.
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1417296
jkr types faster...so I'll submit as comment


1. You have to do the page breaks manually, use the EndPage API call to force a page break

2. When you draw the text you need to keep track of when you reach the bottom of the page.  There are 2 obvious ways to do this :-

(a) Use TextOut (or other API) to draw the text a line at a time (e.g. if you have a long string with line breaks, you break the string yourself before parsing).  You can calculate the lenght of a string of text using GetTextExtent. Basically
- keep a variable of current pos on page.  
- TextOut a line at current pos
- increase the pos on the page by the height of the text
- if reached bottom of the page, do EndPage, then reset variable to 0 to go to top of next page
- repeat till you run out of text

This is the way I like to print, but it is more work.  With this approach you can control the layout exactly (e.g. if you don't want to split paragraphs over a page break) by varying the algorithm appropriately


or
(b) Use DrawText.  There is an option DT_CALCRECT which calculates the size of the rectangle required to fit the text.  So you call this to get the rect size, then output page 1 using a normal DrawText.  If not all the rectangle can fit on the page, do EndPage, and do DrawText again with the y-coord offset to ( -1 * page_height ), if still some left do EndPage then do DrawText again if the y-coord of (-2 * page_height), etc.
0
 
LVL 3

Author Comment

by:BudVVeezer
ID: 1417297
I am currently using DrawText, and would like to continue doing so.  Answers2000 ~you're on the right track, but when I tried doing it your way, it didn't work.  Could you by any chance post some sample code as to how to print w/DrawText?  Right now, it realizes that there are more than one pages, and it goes through the loop the appropriate amount of times, it just doesn't print the right stuff after the first page(page one still prints fine though).

~Aaron
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1417298
Aaron like I say I use method (a) so I don't have sample code with DrawText sitting around on my hard-disk.  (not sure I have publishable C/API sample code on HD disk as I mostly use MFC nowadays)

Why not post your code and I'll tell you how to correct it.

BTW you should make a decision on jkr's answer...he (or others) may not be aware that you still have questions (I myself don't generally look at locked questions always)
0
 
LVL 86

Expert Comment

by:jkr
ID: 1417299
Well, i am aware, and i'd suggest that you post the code also...
0
 
LVL 3

Author Comment

by:BudVVeezer
ID: 1417300
void PrintSelections(LPSTR String)
{
      DOCINFO            di;
    PRINTDLG      pd;
      RECT            r, Heading;
      int                        i, j = 0;

      memset ((void *) &pd, 0, sizeof(PRINTDLG));

    pd.lStructSize = sizeof(PRINTDLG);
    pd.hwndOwner   = NULL;
    pd.Flags       = PD_RETURNDC;
    pd.hInstance   = NULL;

      if(PrintDlg(&pd) == 0)      return;

         Heading.top = MARGIN;
      Heading.bottom = MARGIN + 500;
      Heading.right = GetDeviceCaps(pd.hDC, HORZRES) - MARGIN;
      Heading.left = MARGIN;

      i = DrawText(pd.hDC, String, strlen(String), &r, DT_CALCRECT);
      if(i > (GetDeviceCaps(pd.hDC, VERTRES) - MARGIN))
            j++;
      
      r.top = Heading.bottom + MARGIN;
      r.bottom = GetDeviceCaps(pd.hDC, VERTRES) - MARGIN;
      r.right = GetDeviceCaps(pd.hDC, HORZRES) - MARGIN;
      r.left = MARGIN;

      di.cbSize = sizeof(DOCINFO);
      di.lpszDocName = "Test Printing";
    di.lpszOutput = (LPTSTR) NULL;
    di.lpszDatatype = (LPTSTR) NULL;
    di.fwType = 0;

      StartDoc(pd.hDC, &di);
      for(i = 0; i <= j; i++)
      {
            StartPage(pd.hDC);

            r.top = Heading.bottom + MARGIN * -i;
            DrawText(pd.hDC, String, strlen(String), &r, DT_LEFT | DT_WORDBREAK);
            String = "";

            String = "Repnet 3 Call Report";
            DrawText(pd.hDC, String, strlen(String), &Heading, DT_CENTER | DT_WORDBREAK);

            EndPage(pd.hDC);
      }
      EndDoc(pd.hDC);
}

0
 
LVL 3

Author Comment

by:BudVVeezer
ID: 1417301
Please keep in mind that I was TIRED when I wrote this, and so it may make no sense.  =o)  I want each page to have that heading(hence the heading rect, etc) and then fit the string below it.  Thanks, to both of you!

~Aaron
0
 
LVL 3

Author Comment

by:BudVVeezer
ID: 1417302
If you could post the TextOut source code, that would work too, I can always rework the function...  I have been hacking around on this one for a while now, and am quite lost.  Answers, you answer makes sense, but I don't understand how I am supposed to change the y-coord.....do you mean change the rect.top value?  I tried doing that....but to no avail.  Grr, this is one of those things where I know I am doing something VERY stupid, but can't figure out what!  =o/  Thanks for you help, both of you!

~Aaron
0
 
LVL 86

Expert Comment

by:jkr
ID: 1417303
Well, in the 'good(?) old times' of Win3.x i used 'TextOut()' for this task also... and changing the y-offset is indeed changing r.top...
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 3

Author Comment

by:BudVVeezer
ID: 1417304
See, the thing is, if I do it via TextOut, that means I have to parse a complicated string...and I guess I am just lazy.  =o)  I fixed some of the code so that it's less messy, and easier to work with(I think), I'll post it.  It still doesn't print right.  It prints the correct amount of pages(though that's not very well tested), but it prints the SAME stuff on every page..  =(  Please help!

~Aaron
0
 
LVL 3

Author Comment

by:BudVVeezer
ID: 1417305
void PrintSelections(LPSTR String)
{
      DOCINFO            di;
    PRINTDLG      pd;
      RECT            r, Heading;
      int                        i, j = 0;
      LPSTR            pHeading = "Repnet 3 Call Report";

      memset ((void *) &pd, 0, sizeof(PRINTDLG));

    pd.lStructSize = sizeof(PRINTDLG);
    pd.hwndOwner   = NULL;
    pd.Flags       = PD_RETURNDC;
    pd.hInstance   = NULL;

      if(PrintDlg(&pd) == 0)      return;

         Heading.top = MARGIN;
      Heading.bottom = MARGIN + 500;
      Heading.right = GetDeviceCaps(pd.hDC, HORZRES) - MARGIN;
      Heading.left = MARGIN;

      i = DrawText(pd.hDC, String, strlen(String), &r, DT_CALCRECT);
      
      r.top = Heading.bottom + MARGIN;
      r.bottom = GetDeviceCaps(pd.hDC, VERTRES) - MARGIN;
      r.right = GetDeviceCaps(pd.hDC, HORZRES) - MARGIN;
      r.left = MARGIN;

      j = i / (r.bottom - r.top) + 1;

      r.bottom = i;

      di.cbSize = sizeof(DOCINFO);
      di.lpszDocName = "Test Printing";
    di.lpszOutput = (LPTSTR) NULL;
    di.lpszDatatype = (LPTSTR) NULL;
    di.fwType = 0;

      StartDoc(pd.hDC, &di);
      for(i = 0; i <= j; i++)
      {
            StartPage(pd.hDC);
            
            if(i > 0)
                  r.top *= -i;
            
            DrawText(pd.hDC, pHeading, strlen(pHeading), &Heading, DT_CENTER | DT_WORDBREAK);
            DrawText(pd.hDC, String, strlen(String), &r, DT_LEFT | DT_WORDBREAK | DT_EXPANDTABS);

            EndPage(pd.hDC);
      }
      EndDoc(pd.hDC);
}

0
 
LVL 86

Expert Comment

by:jkr
ID: 1417306
Well, i'm not surprised that there's the same stuff on every page, as 'String' isn't changed within the loop...
0
 
LVL 3

Author Comment

by:BudVVeezer
ID: 1417307
How am I supposed to keep track of what printed?  This is my first attempt at programming anything for printing..so I'm sorry that I am asking such dumb questions.

~Aaron
0
 
LVL 86

Expert Comment

by:jkr
ID: 1417308
Well, you could e.g. use a 'static' local variable in the printing function that keeps track how many lines have been printed, and when the maximum is reached, 'EndPage()' is called and the variable is reset...
0
 
LVL 3

Author Comment

by:BudVVeezer
ID: 1417309
um, I guess I'm at a loss here....could you post some sample code on that...?  Because, as I understand it, DrawText takes the string you give it, and puts the entire string in the rect...  Boy, before this problem, I used to think I was a programmer..  :o)  Sorry for all the trouble!

~Aaron
0
 
LVL 86

Expert Comment

by:jkr
ID: 1417310
OK, there's a little example (just patched it together to illustrate what to do, not guaranteed to work and partly 16 bit infected):

BOOL      bTextAvail = TRUE;
dwExtent  = GetTextExtent(hDC,"0",1);

nX=(int) (dwExtent&0x0000FFFF);
nY=(int)((dwExtent&0xFFFF0000)/0x10000);


while ( bTextAvail)
{
 for(i=0;i<uLinesPerPage;i++)
     {
      if (pcLineEnd=strstr(pcLineStart,"\r\n"))
        uLineLength=pcLineEnd-pcLineStart;
      else
        uLineLength=strlen(pcLineStart);

      TextOut(hDC,nX,dLineDist*nY*i+nY/4, // print with a little bit offset from frame: nY/4
            pcLineStart,uLineLength);

      if (!pcLineEnd)
      {
         bTextAvail = FALSE;
       break;
        }

      pcLineStart=pcLineEnd+2;
     }
 EndPage( hDC);
}
0
 
LVL 3

Author Comment

by:BudVVeezer
ID: 1417311
I won't be able to get back to this problem until Monday, as I am at home for the weekend, and have no printer at home..  =(  I'llget back to you though!

~Aaron
0
 
LVL 86

Expert Comment

by:jkr
ID: 1417312
OK, have a nice weekend! ;o)
0
 
LVL 3

Author Comment

by:BudVVeezer
ID: 1417313
I'm going to give you the points now, because you deserve them after all the crap I've been making you do!  But please, do help me if I leave some comments.  =o)

~Aaron
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Visual Fox Pro commands 15 28
Mixed results 10 69
Problem to packaging 1 74
Windows Process running 3 40
As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

758 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

21 Experts available now in Live!

Get 1:1 Help Now