Click to See Complete Forum and Search --> : Printing to Default Printer


mmscg
July 12th, 2010, 07:49 AM
In the simple program below, what do I have to do to send the output
to the default printer rather than a message box?

#include <windows.h>


int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
{
int i;

for (int i=1; i < 6; i++)
{
MessageBox(NULL, i, NULL, MB_ICONWARNING);
}

return 0;
}

Printed page output like so:

1
2
3
4
5

Seems trivial I know, and yes I've searched, but I cannot find what I am looking for.

Marc G
July 12th, 2010, 09:20 AM
Maybe the following articles can get you started: http://www.codeguru.com/cpp/w-p/printing/

mmscg
July 14th, 2010, 12:23 PM
Thanks for link.

Those are a bit more complicated than I was hoping for, but if the only way,
I will try to understand.

In the mean time, I was hoping for a one line printer call

I found these 2 simple snippets, but when I insert either into my program it won't compile.

Any ideas what I am doing wrong?


fprintf(stdprn,"Test test test\f");



FILE *stdprn;
stdprn = fopen("PRN","wb");
fprintf(stdprn,"From Windows: Test test test\f");
fclose(stdprn);

MrViggy
July 14th, 2010, 02:15 PM
Define "won't compile". What are the errors?

Viggy

mmscg
July 18th, 2010, 10:55 AM
OK, I finally got this to work (not to printer, but a file).

I tested on two different computers.

0 errors, 0 warnings on both computers.


#include <windows.h>
#include <stdio.h>

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
PSTR lpCmdLine , int nCmdShow )
{

FILE *fp;
char *str;

fp = fopen("sample.txt", "w");

str = "line 1\n";
fwrite(str, 1, strlen(str), fp);

str = "line TWO\n";
fwrite(str, 1, strlen(str), fp);

MessageBox(NULL , TEXT("File Written") , lpCmdLine , MB_OK);

return 0;
}

Contents of sample.txt for both computers.

line 1
line TWO

Contents of debug window on one computer

'Print.exe': Loaded 'C:\... ...\WriteFile00\Debug\Print.exe', Symbols loaded.
'Print.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded.
'Print.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded.
'Print.exe': Loaded 'C:\WINDOWS\system32\user32.dll', No symbols loaded.
'Print.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll', No symbols loaded.
'Print.exe': Loaded 'C:\WINDOWS\system32\uxtheme.dll', No symbols loaded.
'Print.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll', No symbols loaded.
'Print.exe': Loaded 'C:\WINDOWS\system32\advapi32.dll', No symbols loaded.
'Print.exe': Loaded 'C:\WINDOWS\system32\rpcrt4.dll', No symbols loaded.
The program '[1316] Print.exe: Native' has exited with code 0 (0x0).

Contents of debug window on another computer

'Print.exe': Loaded 'C:\... ...\WriteFile00\Debug\Print.exe', Symbols loaded.
'Print.exe': Loaded 'C:\WINNT\system32\NTDLL.DLL', Cannot find or open a required DBG file.
'Print.exe': Loaded 'C:\WINNT\system32\USER32.DLL', Cannot find or open a required DBG file.
'Print.exe': Loaded 'C:\WINNT\system32\KERNEL32.DLL', Cannot find or open a required DBG file.
'Print.exe': Loaded 'C:\WINNT\system32\GDI32.DLL', Cannot find or open a required DBG file.
The program '[624] Print.exe: Native' has exited with code 0 (0x0).

Why the different output?

What does Cannot find or open a required DBG file mean?

S_M_A
July 18th, 2010, 11:39 AM
What does Cannot find or open a required DBG file mean?It just means that those dll's don't have any debug information, i.e. nothing to be worried about.

mmscg
July 18th, 2010, 11:49 AM
OK, Thanks!

I can continue on this path then.

mmscg
July 18th, 2010, 06:23 PM
Moving forward, I have this:

#include <windows.h>
#include <stdio.h>

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
PSTR lpCmdLine , int nCmdShow )
{

FILE *fp;
char *str;
char buffer [33];

fp = fopen("sample.txt", "w");

str = "output:\n";
fwrite(str, 1, strlen(str), fp);

for (int i=1; i < 6; i++)
{

switch ( i )
{
case 1:
str = "(1st line)\n";
break;
case 2:
str = "(2nd line)\n";
break;
case 3:
str = "(3rd line)\n";
break;
case 4:
str = "(4th line)\n";
break;
case 5:
str = "(5th line)\n";
break;
}

fwrite("i = ",1,4,fp);
fwrite(itoa(i, buffer, 10), 1, 1, fp);
fwrite(" ", 1, 3, fp);
fwrite(str, 1, strlen(str), fp);

}

MessageBox(NULL , TEXT("File Written") , lpCmdLine , MB_OK);

return 0;
}

Contents of sample.txt:

output:
i = 1 (1st line)
i = 2 (2nd line)
i = 3 (3rd line)
i = 4 (4th line)
i = 5 (5th line)

Is it possible to replace the four fwrites with one, ang get the same output?

Something like?

fwrite("i = " & i & " " & str, 1, 18, fp);

Paul McKenzie
July 18th, 2010, 06:39 PM
const char *sArray[] = {
"(1st line)\n",
"(2nd line)\n",
"(3rd line)\n",
"(4th line)\n",
"(5th line)\n"
};
//..
for (int i = 0; i < sizeof(sArray) / sizeof(sArray[0]); ++i )
{
// no case statement needed now
str = sArray[i];
//...
}

Regards,

Paul McKenzie

mmscg
July 19th, 2010, 04:56 PM
Thanks Paul for the reply.

I was not trying to get rid of the switch block, but rather have one fwrite statement to accomodate different data types; strings, integers, etc.

I found that the fprintf statement would give me what I was after.

#include <windows.h>
#include <stdio.h>

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
PSTR lpCmdLine , int nCmdShow )
{

FILE *fp;
char *str;
byte b;

b=255;
fp = fopen("sample.txt", "w");

str = "output:\n";
fwrite(str, 1, strlen(str), fp);

for (int i=1; i < 6; i++)
{

switch ( i )
{
case 1:
str = "(1st line)";
b=34;
break;
case 2:
str = "(2nd line)";
b=127;
break;
case 3:
str = "(3rd line)";
b=122;
break;
case 4:
str = "(4th line)";
b=13;
break;
case 5:
str = "(5th line)";
b=94;
break;
}

fprintf(fp,"i = %d %s %x\n", i, str, b);

}

MessageBox(NULL , TEXT("File Written") , lpCmdLine , MB_OK);

return 0;
}

sample.txt file

output:
i = 1 (1st line) 22
i = 2 (2nd line) 7f
i = 3 (3rd line) 7a
i = 4 (4th line) d
i = 5 (5th line) 5e

Seems OK.

Now to try to put this in my real program, and see if it gives me the output I am after.

mmscg
July 21st, 2010, 07:39 AM
I think I have the "printing" working correctly,
but I find some strange results when looking over the printed output.

Is it a problem with my fprintf usage?

In the output below generated by the following code,
why the 8 characters «««««««« following untitled?

Code:

//-------------------------------------------------------
LPVOID Alloc(DWORD dwSize)
{
return HeapAlloc(g_hheap, HEAP_ZERO_MEMORY, dwSize);
}
//-------------------------------------------------------


//-------------------------------------------------------
struct EVENT {
int nData;
LPBYTE lpData;
};

typedef struct EVENT EVENT;
typedef struct EVENT *LPEVENT;

LPEVENT lpEvent;
DWORD dw;

dw = 8;
lpEvent->nData = dw;
lpEvent->lpData = (LPBYTE)Alloc(lpEvent->nData);
mmioRead(hmmio, (HPSTR)lpEvent->lpData, lpEvent->nData);

fprintf(fp,"lpEvent->nData = %d\n", lpEvent->nData);
fprintf(fp,"lpEvent->lpData = <%s>\n", lpEvent->lpData);
//-------------------------------------------------------

Output:

lpEvent->nData = 8
lpEvent->lpData = <untitled««««««««>

Marc G
July 21st, 2010, 09:06 AM
Because lpEvent->lpData is not NULL terminated.
If you want to read 8 characters from a file into a buffer and later print it, it's best to allocate 9 bytes, read 8 bytes from file and set the 9th byte to \0. That way, fprintf will stop correctly at the \0 and will not print garbage.

mmscg
July 21st, 2010, 12:38 PM
I think I understand what you are saying, and I will try as you suggest.

What I do not understand is the length of my returned string; 8 characters in untitled and 8 «

Is lpEvent->lpData a pointer to a buffer?

If yes, does this buffer have a fixed or limiting size?

Marc G
July 21st, 2010, 01:45 PM
Yes, lpEvent->lpData is some kind of buffer.
When you pass it to fprintf, fprintf will just output characters until it finds a \0 character.

mmscg
July 24th, 2010, 10:47 PM
With regards to the code/output in Post #11, I would like output as so:

lpEvent->nData = 8
lpEvent->lpData = <untitled««««««««>
char 1 = u = hex = 75
char 2 = n = hex = 6E
char 3 = t = hex = 74
char 4 = i = hex = 69
char 5 = t = hex = 74
char 6 = l = hex = 6C
char 7 = e = hex = 65
char 8 = d = hex = 64

This now is not a question of how to use the fprintf function, but rather
how to read each character in turn from the lpEvent->lpData string and convert to hex.

Marc G
July 25th, 2010, 09:32 AM
Something like:
for (int i=0; i<lpEvent->nData; ++i)
{
cout << "char " << i << " = " << lpEvent->lpData[i]
<< " = hex = " << hex << (int)lpEvent->lpData[i] << endl;
}

mmscg
July 25th, 2010, 12:03 PM
Works perfect!

I coudn't get the cout to work, but I did it with fprintf.

Thanks!

Marc G
July 28th, 2010, 02:47 AM
What was the problem with cout?
Did you include <iostream>?
Did you put "using namespace std;" at the top of the CPP file?

mmscg
August 10th, 2010, 06:55 PM
I am making progress with printing to a file, but have run into a problem that I don't understand.

I am trying to read a MIDI file and print out the contents.

The code below works for standard type 0 MIDI files (these have only 1 track).

If I use the same code, but open a type 1 MIDI file (these have more than 1 track), the program crashes.

Can someone spot my error?


#include <windows.h>

#pragma comment (lib, "winmm.lib")

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct EVENT {
BYTE state;
BYTE data1;
BYTE data2;
BYTE type;
int nData;
LPBYTE lpData;
DWORD dwDelta;

struct EVENT *lpNext;
};
typedef struct EVENT EVENT;
typedef struct EVENT *LPEVENT;

HANDLE g_hheap = NULL;

BOOL ReadMidiFile(LPTSTR lpszFileName);
BOOL ReadTrack(HMMIO hmmio, LPEVENT *lplpEvent);
void ReadAndReverse(HMMIO hmmio, LPVOID lpData, DWORD dwSize);
void ReadDelta(HMMIO hmmio, LPDWORD lpdwDelta);
LPVOID Alloc(DWORD dwSize);
BOOL PrintOut(LPEVENT lpEvent);

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
{
g_hheap = HeapCreate(0, 4096, 0);
if (g_hheap == NULL)
return 0;

if (!ReadMidiFile(TEXT("SMFtype0.mid")))
//if (!ReadMidiFile(TEXT("SMFtype1.mid")))

MessageBox(NULL, TEXT("error"), NULL, MB_ICONWARNING);

HeapDestroy(g_hheap);

return 0;
}

BOOL ReadMidiFile(LPTSTR lpszFileName)
{
HMMIO hmmio;
WORD i;
WORD wTrack;
WORD wFormat;
WORD wTime;
DWORD dwMagic;
DWORD dwDataLen;
LPEVENT *lplpEvent;

hmmio = mmioOpen(lpszFileName, NULL, MMIO_READ);
if (hmmio == NULL) {
MessageBox(NULL, TEXT("error"), NULL, MB_ICONWARNING);
return FALSE;
}

mmioRead(hmmio, (HPSTR)&dwMagic, sizeof(DWORD));
if (dwMagic != *(LPDWORD)"MThd") {
mmioClose(hmmio, 0);
return FALSE;
}

ReadAndReverse(hmmio, &dwDataLen, sizeof(DWORD));
if (dwDataLen != 6) {
mmioClose(hmmio, 0);
return FALSE;
}

ReadAndReverse(hmmio, &wFormat, sizeof(WORD));
ReadAndReverse(hmmio, &wTrack, sizeof(WORD));
ReadAndReverse(hmmio, &wTime, sizeof(WORD));

lplpEvent = (LPEVENT *)Alloc(sizeof(DWORD) * wTrack);

for (i = 0; i < wTrack; i++) {
if (!ReadTrack(hmmio, &lplpEvent[i])) {
MessageBox(NULL, TEXT("error"), NULL, MB_ICONWARNING);
mmioClose(hmmio, 0);
return FALSE;
}
}

MessageBox(NULL, TEXT("ALL MIDI tracks read"), TEXT("OK"), MB_OK);

mmioClose(hmmio, 0);

return TRUE;
}

BOOL ReadTrack(HMMIO hmmio, LPEVENT *lplpEvent)
{
BYTE statePrev = 0;
DWORD dwLen;
DWORD dwMagic;
LPEVENT lpEvent;


mmioRead(hmmio, (HPSTR)&dwMagic, sizeof(DWORD));
if (dwMagic != *(LPDWORD)"MTrk")
return FALSE;

ReadAndReverse(hmmio, &dwLen, sizeof(DWORD));

lpEvent = (LPEVENT)Alloc(sizeof(EVENT));

*lplpEvent = lpEvent;

for (;;) {
ReadDelta(hmmio, &lpEvent->dwDelta);

mmioRead(hmmio, (HPSTR)&lpEvent->state, sizeof(BYTE));
if (!(lpEvent->state & 0x80)) {
lpEvent->state = statePrev;
mmioSeek(hmmio, -1, SEEK_CUR);
}

switch (lpEvent->state & 0xF0) {

case 0x80:
case 0x90:
case 0xA0:
case 0xB0:
case 0xE0:
mmioRead(hmmio, (HPSTR)&lpEvent->data1, sizeof(BYTE));
mmioRead(hmmio, (HPSTR)&lpEvent->data2, sizeof(BYTE));
break;
case 0xC0:
case 0xD0:
mmioRead(hmmio, (HPSTR)&lpEvent->data1, sizeof(BYTE));
lpEvent->data2 = 0;
break;

case 0xF0:
if (lpEvent->state == 0xF0) {
mmioRead(hmmio, (HPSTR)&lpEvent->nData, sizeof(BYTE));

lpEvent->lpData = (LPBYTE)Alloc(lpEvent->nData + 1);
lpEvent->lpData[0] = lpEvent->state;
mmioRead(hmmio, (HPSTR)(lpEvent->lpData + 1), lpEvent->nData);

lpEvent->nData++;
}
else if (lpEvent->state == 0xFF) {
DWORD dw;
DWORD tmp;

mmioRead(hmmio, (HPSTR)&lpEvent->type, sizeof(BYTE));

dw = (DWORD)-1;

switch (lpEvent->type) {

case 0x00: dw = 2; break;
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07: break;
case 0x20: dw = 1; break;
case 0x21: dw = 1; break;
case 0x2F: dw = 0; break;
case 0x51: dw = 3; break;
case 0x54: dw = 5; break;
case 0x58: dw = 4; break;
case 0x59: dw = 2; break;
case 0x7F: break;

default:
MessageBox(NULL, TEXT("error"), NULL, MB_ICONWARNING);
return FALSE;

}

tmp = dw;

if (dw != -1) {
ReadDelta(hmmio, &dw);
if (dw != tmp) {
MessageBox(NULL, TEXT("error"), NULL, MB_ICONWARNING);
return FALSE;
}
}
else
ReadDelta(hmmio, &dw);

lpEvent->nData = dw;
lpEvent->lpData = (LPBYTE)Alloc(lpEvent->nData);
mmioRead(hmmio, (HPSTR)lpEvent->lpData, lpEvent->nData);

if (lpEvent->type == 0x2F)
return TRUE;
}
else
;

break;

default:
MessageBox(NULL, TEXT("error"), NULL, MB_ICONWARNING);
return FALSE;

}



PrintOut((LPEVENT)lpEvent);


statePrev = lpEvent->state;

lpEvent->lpNext = (LPEVENT)Alloc(sizeof(EVENT));
lpEvent = lpEvent->lpNext;
if (lpEvent == NULL)
break;

}

return FALSE;
}

void ReadAndReverse(HMMIO hmmio, LPVOID lpData, DWORD dwSize)
{
BYTE i;
BYTE tmp;
LPBYTE lp = (LPBYTE)lpData;
LPBYTE lpTail = lp + dwSize - 1;

mmioRead(hmmio, (HPSTR)lp, dwSize);

for (i = 0; i < dwSize / 2; i++) {
tmp = *lp;
*lp = *lpTail;
*lpTail = tmp;

lp++;
lpTail--;
}
}

void ReadDelta(HMMIO hmmio, LPDWORD lpdwDelta)
{
int i;
BYTE tmp;

*lpdwDelta = 0;

for (i = 0; i < sizeof(DWORD); i++) {
mmioRead(hmmio, (HPSTR)&tmp, sizeof(BYTE));

*lpdwDelta = ( (*lpdwDelta) << 7 ) | (tmp & 0x7F);

if (!(tmp & 0x80))
break;
}
}

LPVOID Alloc(DWORD dwSize)
{
return HeapAlloc(g_hheap, HEAP_ZERO_MEMORY, dwSize);
}

BOOL PrintOut(LPEVENT lpEvent)
{
FILE *fp;
const char *str = "--------";

fp = fopen("printout.txt", "a");

fprintf(fp,"%s\n", str);
fprintf(fp,"lpEvent->dwDelta = %d\n", lpEvent->dwDelta);
fprintf(fp,"lpEvent->state = %X\n", lpEvent->state);
fprintf(fp,"lpEvent->type = %X\n", lpEvent->type);
fprintf(fp,"lpEvent->data1 = %X\n", lpEvent->data1);
fprintf(fp,"lpEvent->data2 = %X\n", lpEvent->data2);
fprintf(fp,"lpEvent->nData = %d\n", lpEvent->nData);
fprintf(fp,"lpEvent->lpData = <%s>\n", lpEvent->lpData);

if (lpEvent->lpData[0] == 0xF0)
{
for (int i=0; i<lpEvent->nData; ++i)
{
fprintf(fp," char = <%X>\n", (int)lpEvent->lpData[i]);
}
}

return TRUE;
}

mmscg
August 11th, 2010, 06:46 AM
I should add, the program operates properly for both type 0 and type 1 MIDI files,
it is just my printing code that causes problems.

mani3355
August 12th, 2010, 12:22 AM
hi,


we should add, the program operates properly for both type 0 and type 1 MIDI files,
it is just my printing code that causes problems.

regards,
phe9oxis,
http://www.guidebuddha.com