Printing Issues Straight Win32 API

I have never printed in Win32 API before, before NOW, I should say. I'm using Petzold to learn how to print, and I've already discovered how to circumvent a good deal of Petzold's examples to make it more simple, such as getting the default printer without going through all of the rigamarole in some of Petzold's examples, but one thing I haven't figured out yet is this...

In Petzold in his POPPRINT program (chapter 13), he allocates his buffer line by line. He is getting his text from the edit box, and instead of getting all of his text into a buffer, he is allocating it line by line, printing it, then allocating it again, printing, etc. Here is his code, and I have two questions following...

First, before he starts printing, he does this...

PTSTR pstrBuffer=malloc(sizeof (TCHAR) * (iCharsPerLine + 1) );

Obviously, he didn't need to typecast with his compiler. At any rate, this is BEFORE he enters the print loop. Now, once inside the print loop, he does this...

*(int *)pstrBuffer=iCharsPerLine;

I don't understand this last statement. Please somebody explain it to me SIMPLY.

Secondly, is there not a way to just get the whole text of the entire edit box into a string and then print it out instead of allocating it on each line pass?

If so, how would I print out each line out of the buffer?

I hope I've been clear. If not, let me know and I'll have another go.
Last edited on
I should add, I know how to get the entire text of the edit control into a string, so that's not the issue. What I meant was, once I've gotten the entire text into a string, isn't there some way to print it out from that string without having to do it Petzold's way, i.e., allocating it line by line?
Actually, here's what I think I understand so far...

the code *(int *)pstrBuffer=iCharsPerLine; means that he is allocating the number of characters per line to the pointer pstrBuffer. IOW, he is making sure there is room in that buffer for that many characters.

But then he does this in his text output immediately after the above statement --

TextOut(pd.hDC, 0, yChar * iLine, pstrBuffer, (int) SendMessage(hwndEdit, EMGETLINE, (WPARAM) iLineNum, (LPARAM) pstrBuffer));

Now HOW does that get the text from the edit box INTO pstrBuffer???
Last edited on
Okay, I know I'll have answers when you guys get back to work tomorrow, but until then I'm going to keep talking to myself...

and I've figured out most of it. I now know (which I should have caught, it's so simple), that the EM_GETLINE is how he's getting the text into the buffer.

So in essence, I think all of my questions have been answered except if anyone knows how to run the print loop without allocating the buffer each time, i.e., to instead get ALL of the text in the edit box and THEN run the print loop, but then, after having run this a few times now, perhaps Petzold's way is simpler.

So, when you're all taking breaks tomorrow to come over here and help out, any thoughts, clarifications would be appreciated.

Also, I'd appreciate it if some could explain more perfectly to me the pointer statement above. I know what it's doing, but I don't understand why it's doing it, especially the first part of the pointer, i.e., *(int *)pstrBuffer...

As I say, I know WHAT it's doing, but I still don't really understand it.
Last edited on
 
*(int *)pstrBuffer=iCharsPerLine;


Store at the address pstrBuffer (cast from a TCHAR* to an int*) the number iCharsPerLine.

That's what I thought as I progressed, but why then does he FIRST declare his initial statement outside of the printer loop beforehand, iow, why does he do this BEFORE the printer loop --

[code]PTSTR pstrBuffer=malloc(sizeof (TCHAR) * (iCharsPerLine + 1) );

Since he allocates each time the printer moves to a new line, why this initial dec? Why not just leave it at NULL until you get INSIDE the printer loop?
Does this help?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <windows.h>
#include <tchar.h>
#include <cstdlib>
#include <cstdio>

//  1) allocate a buffer of 11 bytes;
//  2) store number 10 at base offset;
//  3) fill remaining ten bytes with '0' through '9'
//  4) run loop from number stored at offset zero (10) to 10

int main()
{
 int iCharsPerLine=10;     //assign 10
 TCHAR tc=48;              //48 is asciiz for '0', i.e., zero.
 PTSTR pstrBuffer=(TCHAR*)malloc(sizeof(TCHAR) * (iCharsPerLine + 1) );  //allocate 11 bytes if not unicode
 printf("pstrBuffer          = %u\n",(unsigned)pstrBuffer);   //output base address of memory allocation
 *(int*)pstrBuffer=iCharsPerLine;                    //store the number 10 at base address
 printf("*(TCHAR*)pstrBuffer = %d\n\n",*(TCHAR*)pstrBuffer);
 for(int i=1;i<=10; i++)
 {
     pstrBuffer[i]=tc;
     tc++;
 }
 for(int i=1; i<=*(TCHAR*)pstrBuffer; i++)
     printf("%d\t%c\t%u\t%u\n",i,pstrBuffer[i],pstrBuffer[i],&pstrBuffer[i]);
 free(pstrBuffer);
 getchar();

 return 0;
}

/*
pstrBuffer          = 3413800
*(TCHAR*)pstrBuffer = 10

          %c      %u       %u
i       pBuf[i] pBuf[i] &pBuf[i]
================================
1       0       48      3413801
2       1       49      3413802
3       2       50      3413803
4       3       51      3413804
5       4       52      3413805
6       5       53      3413806
7       6       54      3413807
8       7       55      3413808
9       8       56      3413809
10      9       57      3413810

*/
I have to admit I never did any printing directly from Win32. Its always been good enough for me to output data to a text file, a database, to Excel, or to Word, and let folks format and print stuff from there the way they want it. From what you are describing though it sounds like just drawing to the screen, i.e., one line at a time. Actually, I think that was the general idea of Windows output.
Just dwrawing to the screen one line at time is I think -- now that I've played with Petzold's example many times and different ways -- the best way to go. It allows one to format the data better that way if one wants to.

I am like you; i.e., in the past I've simply either out-putted to a file or to the clipboard and just let the user then paste into his favorite text editor, but now I have made a good bit of progress in allowing the user another option.

I have a lot of note fields in my main major application, and now the user is able to not only output to a file or clipboard, but to the printer as well. I could have done without the print option, but I figured it was time to learn.
Actually, here's what I think I understand so far...

the code *(int *)pstrBuffer=iCharsPerLine; means that he is allocating the number of characters per line to the pointer pstrBuffer. IOW, he is making sure there is room in that buffer for that many characters.

But then he does this in his text output immediately after the above statement --

TextOut(pd.hDC, 0, yChar * iLine, pstrBuffer, (int) SendMessage(hwndEdit, EMGETLINE, (WPARAM) iLineNum, (LPARAM) pstrBuffer));

Now HOW does that get the text from the edit box INTO pstrBuffer???


When you send the EMGETLINE request to an editbox - you pass pass a buffer for it (the editbox) to put the text into. You put the maximum number of characters you want to be read (in order to avoid buffer overflow) into the start of the buffer as an integer.
So that is what he is doing with this code:
(int *)pstrBuffer=iCharsPerLine;
So before the editbox writes the line into the buffer, it reads the buffer (as a int*) to get the required maximum characters required, then fills the buffer.

See what I mean??


Yes, I now see what you mean. I found that without declaring the first buffer with malloc() that I was not allocating the space. Now I see what you're saying.
Topic archived. No new replies allowed.