Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Can not print in Landscape Mode

7 views
Skip to first unread message

ATC

unread,
Apr 19, 2003, 12:31:01 PM4/19/03
to
Hi,

I am trying desperately to print a report in Landscape
Mode with VC++, but even I try with "hDevMode" ... it
still always print in Portrait Mode:

CPrintDialog printDlg(FALSE, PD_RETURNDEFAULT |
PD_RETURNDC);

if (printDlg.DoModal() == IDCANCEL) return;

////////////////// Landscape Mode //////////////////////

HGLOBAL m_hDevMode;
HGLOBAL m_hDevNames;

PRINTDLG pd;
pd.lStructSize = (DWORD) sizeof(PRINTDLG);

// Lock memory handle.
DEVMODE FAR* pDevMode =
(DEVMODE FAR*)::GlobalLock(m_hDevMode);
LPDEVNAMES lpDevNames;
LPTSTR lpszDriverName, lpszDeviceName, lpszPortName;
HANDLE hPrinter;

// pDevMode is not TRUE, program not going this LOOP
if (pDevMode)
{
// Change printer settings in here.
pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
// Unlock memory handle.
lpDevNames = (LPDEVNAMES)GlobalLock
(pd.hDevNames);
lpszDriverName = (LPTSTR )lpDevNames +
lpDevNames->wDriverOffset;
lpszDeviceName = (LPTSTR )lpDevNames +
lpDevNames->wDeviceOffset;
lpszPortName = (LPTSTR )lpDevNames +
lpDevNames->wOutputOffset;

::OpenPrinter(lpszDeviceName, &hPrinter, NULL);
::DocumentProperties
(NULL,hPrinter,lpszDeviceName,pDevMode,

pDevMode, DM_IN_BUFFER|DM_OUT_BUFFER);

// Sync the pDevMode.
// See SDK help for DocumentProperties for
more info.
::ClosePrinter(hPrinter);
::GlobalUnlock(m_hDevNames);
::GlobalUnlock(m_hDevMode);
}

///////////////////// Standrad Printing /////////////////

CDC dc;
CPrintInfo Info;
CFont oFont;

dc.Attach(printDlg.GetPrinterDC()); // Get
and attach a printer DC
dc.SaveDC();
// RIA : Save the DC state
dc.m_bPrinting = TRUE;

CString strTitle; // Get
the application title
strTitle.LoadString(AFX_IDS_APP_TITLE);

DOCINFO di; //
Initialise print document details
::ZeroMemory (&di, sizeof (DOCINFO));
di.cbSize = sizeof (DOCINFO);
di.lpszDocName = strTitle;

BOOL bPrintingOK = dc.StartDoc(&di); // Begin
a new print job

....................................
....................................

Can any one know why? To show you my problem I can
send "my small project" if you provide me your Email
address

I appreciate a lot anyone try to help me here

Thanks

Joseph M. Newcomer

unread,
Apr 20, 2003, 9:53:55 PM4/20/03
to
Some code cleanups:

FAR is a meaningless word which only obscures what is going on. It is obsolete and can be
eliminated (it expands to an empty string).

Code is easier to read if there are no commas in declaration lists. If you need three
variables, use three lines to put them one, declare one variable per line.

pDevMode can never be TRUE; if it were, it would be the constant 1, which would be an
illegal pointer. The correct comment and test is
// if pDevMode is non-NULL, ...
if(pDevMode != NULL)

The value of pretending a pointer is a Boolean is a sloppy practice that dates back to the
PDP-11 compiler, which was so bad that it would actually generate code to test against
NULL instead of doing the job right. There is no reason to maintain this sloppy style in
modern programs.

I'm not sure where the LOOP is that you refer to; I see no loop here...

Confusing things are questions such as what do you mean by "standard printing" in the
comment? I don't know how this code relates to the previous code.

I see completely separate actions here; there is something that is setting landscape mode,
and there is the apparently disconnected code that seems to do printing. The last time I
tried to print landscape, many years ago, I did not even come close to an ::OpenPrinter
API, I just modified the device characteristics in the control blocks that came back from
getting the DC *that I was about to use for printing* and essentially it worked perfectly
the first time (well, except for the fact that I didn't have all the text in the right
places, and suchlike, but the landscape worked perfectly). I lose track in the code below
as to who is doing what to whom, and when, but my code was substantially simpler than what
I see here. If I could find it, I'd post it, but it seems to have gone away in the various
migrations of systems that have happened since that time. (I just did a fairly lengthy
grep of all files on three different servers while I did some other things, and could not
find anything dealing with landscape in any of them).

Also note that a HUGE number of the hits you will get if you do an MSDN search for
"landscape" tend to be of the form "printer brand X model Y will not print in landscape
mode...", so there is always a possibility that your driver for some reason has one of
these bugs.

I suggest studying the KB article Q140285. I see only superficial resemblance here between
your code and the code illustrated in that article. The article emphasizes that care is
required to do the setup, yet I don't see anything like what it suggests in the code
below. You should check out that article first. The description of
CRichEditCtrl::SetPaperSize contains references to setting landscape mode also, and may be
of some help. The MSDN also contains an article by Jeff Prosise on printing. There is
also an article from the Windows NT Professional magazine, by Robert Hummel, dated January
1999, which has a program that does a "print screen" and allows selecting landscape mode;
its code might help you. A cursory examination of some of the code associated with these
(apparently successful) programs (note that I didn't examine all of them) and a
superficial comparison with your code seems to show several major differences. I'd start
with one of these as a basis.
joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Anh

unread,
Apr 22, 2003, 12:25:11 AM4/22/03
to
Hi,

a) Thank you for help, I will try what you suggest & will
use your way with DC (if you post it)

b) However, someone did pointout the error from:

DEVMODE FAR *pDevMode=(DEVMODE FAR *)::GlobalLock
(m_hDevMode);

it must change to: DEVMODE FAR *pDevMode=(DEVMODE FAR
*)::GlobalLock(pd.hDevMode);

Now there is no more error and the pDevMode is set to
LandScape ... however ... It is not affected since later
I use the CDC dc ... dc.TextOut(x0,y0,x1,y1,....)

The result I still print in Portrait Mode (I do not know
why? even after printing: the pDevMode->dmOrientation
still equal = DMORIENT_LANDSCAPE;

I someone can point out why: It happens like that!

Regards,

>.
>

Joseph M. Newcomer

unread,
Apr 22, 2003, 12:18:56 PM4/22/03
to
As I pointed out, your code was convoluted (and I still don't understand what FAR means in
a Win32 program; drop it, it is noise). It is not clear what you set, where you set it,
and where you use it. When I printed in landscape, I created the DC, set the landscape
mode, printed, and released the DC. So I never could apply the phrase "later" to the use
of a DC. The DC was created, used, and disposed of. No "later" ever existed. And I never,
ever called OpenPrinter to set landscape mode.

And, as I pointed out, some drivers have problems with landscape mode, and there are a
HUGE number of hits to this effect when I searched the MSDN for "landscape". Some of these
suggest that there are things which must be done to make sure the driver works correctly.
joe

0 new messages