Printing problem
Adrian_Glanvill@stockley-park.sterling.com
Monday, April 24, 1995
Not sure if this problem is strictly MFC related, but here goes anyway...
When printing out each page of my document, I blit a bitmap into the top-left
corner of the page. I'm testing this on an HP Laserjet 4, which defaults to
600dpi mode, and it works fine. If, however, I change the resolution to 300dpi,
the bitmap gets drawn just over halfway across the page instead of at the left
hand edge.
The code I am using in my OnPrint() function is as follows :
// m_pLogoDC is a memory DC already set up earlier
// Print logo:
if (m_pLogoDC && pDC->GetDeviceCaps(RASTERCAPS) & RC_STRETCHBLT )
{
m_pOldBitmap = m_pLogoDC->SelectObject(m_pLogo);
// change map mode to guarantee physical dimensions of logo on page
int nOldMode = pDC->SetMapMode(MM_HIMETRIC);
// transfer from the memory dc to the printer dc
pDC->StretchBlt(0, 0, 1000, -1000, m_pLogoDC, 0, 0, 112, 112, SRCCOPY);
// restore original map mode and clear bitmap
pDC->SetMapMode(nOldMode);
m_pLogoDC->SelectObject(m_pOldBitmap);
}
Apart from using magic numbers, what's wrong with this code ?
============================================================================
Adrian Glanvill Phone : +44-181-867-8275
Sterling Software E-Mail : Adrian_Glanvill@stockley-park.sterling.com
============================================================================
RND - Gan Chai Beng -- locbg@venus.likom.com.my
Tuesday, July 18, 1995
I use VC++ 1.5.
I load a bitmap and stretch it to a device context of the view. It seems
everything correct. But if I print it to printer, some of the image on the top
of bitmap is truncated.
StretchBlt( DestHDC,
0, 0,
SrcWidth, SrcHeight,
SrcHDC,
0, 0,
SrcWidth, SrcHeight,
SRCCOPY);
If I change the code to :
StretchBlt( DestHDC,
**eg. 30, 30,
SrcWidth, SrcHeight,
SrcHDC,
0, 0,
SrcWidth, SrcHeight,
SRCCOPY);
all the image will print out. What the printer driver I used is PostScript
Printer.
I think this may be the top margin of page setup problem. Any idea of this ?
How I can get the top margin value as printing ?
Jack
Friday, February 16, 1996
I'm calling code similar to the following from my OnDraw() function in a
CView derived class:
Interestingly enough, it prints on a monochrome Postscript printer but
not on my HP 855C Color printer. Additionally, depending on the size of
the rect, it may or may not print.
For example:
void CPrintView::OnDraw(CDC* pDC)
{
CPrintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CPoint ptOrigin(225,255);
CSize sz(93,273);
Draw(pDC,CRect(ptOrigin,ptOrigin+sz));
}
void CPrintView::Draw(CDC* pDC, const CRect& rc)
{
CSize sz(rc.Size());
CPoint pos(rc.TopLeft());
CDC dc;
dc.CreateDC("DISPLAY",0,0,0);
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC,sz.cx,sz.cy);
BITMAP bitmap;
bmp.GetObject(sizeof(BITMAP),&bitmap);
memDC.SelectObject(&bmp);
CBrush br(RGB(0,0,0));
memDC.FillRect(&CRect(CPoint(0,0),sz),&br);
pDC->SetMapMode(MM_TEXT);
pDC->BitBlt(pos.x, pos.y, sz.cx, sz.cy, &memDC, 0, 0, SRCCOPY);
}
Andreas Will -- a.will@T-Online.de
Sunday, February 18, 1996
>
>I'm calling code similar to the following from my OnDraw() function in a
>CView derived class:
>Interestingly enough, it prints on a monochrome Postscript printer but
>not on my HP 855C Color printer. Additionally, depending on the size of
>the rect, it may or may not print.
>
>For example:
..snip..
>
> CDC dc;
> dc.CreateDC("DISPLAY",0,0,0);
You create a dc that is compatible to your display not necessarily your printer.
I don't know about the capabilities of your PS-printer but it's driver
probably makes it compatible to the screen display.
You should call dc.CreateCompatibleDC(pDC) to get a printer-compatible dc
You can ask for the bits per pixel (bpp) of your printer dc by calling
pDC->GetDeviceCaps(BITSPIXEL) (also: not all devices support BitBlt)
If your bitmap uses more bpp you have a problem:
MSVC 1.5 help quote:
An application can select a bitmap into memory device contexts only and
into only one memory device context at a time.
The format of the bitmap must either be monochrome or compatible
with the device context; if it is not, SelectObject returns an error.
Best regards
Andy
/////////////////
Andreas Will
Jever, Germany
inet: a.will@t-online.de
cserve: 101537,3347
/////////////////
David Shak -- Dshak@TORONTO.DELRINA.com
Thursday, February 22, 1996
>>I'm calling code similar to the following from my OnDraw() function in
a
>>CView derived class:
>>Interestingly enough, it prints on a monochrome Postscript printer but
>>not on my HP 855C Color printer. Additionally, depending on the size of
>>the rect, it may or may not print.
>>
>>For example:
>..snip..
>>
>> CDC dc;
>> dc.CreateDC("DISPLAY",0,0,0);
>You create a dc that is compatible to your display not necessarily your
>printer.
>I don't know about the capabilities of your PS-printer but it's driver
>probably makes it compatible to the screen display.
>You should call dc.CreateCompatibleDC(pDC) to get a printer-compatible
dc
>You can ask for the bits per pixel (bpp) of your printer dc by calling
> pDC->GetDeviceCaps(BITSPIXEL) (also: not all devices support BitBlt)
>If your bitmap uses more bpp you have a problem:
> MSVC 1.5 help quote:
> An application can select a bitmap into memory device contexts only and
> into only one memory device context at a time.
> The format of the bitmap must either be monochrome or compatible
> with the device context; if it is not, SelectObject returns an error.
If you notice in the original code, the CDC object 'dc' is
used to in
dc.CreateDC("DISPLAY",0,0,0);
but no where else this must have been test code that was not taken
out...
also notice that the original code does call CreateCompatibleDC correctly
(I think).
Strangely enough I am having a similar (possibly the exact) problem,
I am also having difficulty printing bitmaps but ( and this is really
weird)
only on some machines... It works on my NT 3.51 machine but not on
another NT 3.51 machine printing to the same printer. I've tried my test
app on allot of machines and there seems to be no configuration that
works all the time.
The app is failing in the SelectObject but I have no idea why. ( remember
it does work on some machines)
I'm doing the simplest of examples... here is the code
void CPrintView::OnDraw(CDC* pDC)
{
CDC memDC;
CBitmap bitmap, *pOldBitmap;
BITMAP bitmapInfo;
bitmap.LoadBitmap( IDB_THING);
bitmap.GetObject( sizeof( bitmapInfo), &bitmapInfo);
memDC.CreateCompaibleDC( pDC);
pOldBitmap = (CBitmap*)memDC.SelectObject( &bitmap); // fails here
// on some machines
ASSERT( pOldBitmap);
pDC->BitBlt( 0, 0, bitmapInfo.bmWidth, bitmapInfo.bmHeight, &memDC, 0,
0, SRCCOPY);
memDC.SelectObject( pOldBitmap);
}
I think solving this problem will also solve the first problem.
( by the way the sample app was made with the VC4 app wizard)
Dave.
dhylands@creo.bc.ca
Friday, February 23, 1996
[Mini-digest: 2 responses]
Hi Dave,
> Strangely enough I am having a similar (possibly the exact) problem,
> I am also having difficulty printing bitmaps but ( and this is really
> weird) only on some machines... It works on my NT 3.51 machine but not on
> another NT 3.51 machine printing to the same printer. I've tried my test
> app on allot of machines and there seems to be no configuration that
> works all the time.
> The app is failing in the SelectObject but I have no idea why. ( remember
> it does work on some machines)
The answer doesn't have anything to do with MFC but it probably explains
whats happening.
Make sure that both printer drivers are actually using the same PSCRIPT.DLL
file. It seems like there are minor changes to each one with each service pack
and version of NT (It probably it isn't it just seems that way).
Check C:\WINNT35\SYSTEM32\SPOOL\DRIVERS\W32ALPHA (or w32x86) and ALL of the
numbered directories found here.
All of the PSCRIPT.DLL's should have the same date/timestamp and size.
All of the PSCRPTUI.DLL's should have the same date/timestamp and size.
The ones on the machine that doesn't work are probably different from the ones
on the machine that does work.
After you install a printer, make sure that run the appropriate service pack
again (installing a printer may copy in old files off your diskettes or CD which
were updated on a service pack).
Even after installing the service pack, I would double check the date and file
sizes and see if they've been updated.
NT 3.51 for Intel ships with
May 26 10:57:00 1995 220944 pscript.dll
May 26 10:57:00 1995 184592 pscrptui.dll
NT 3.51 Service Pack 2 for Intel has DLL's with the following date & size:
Oct 7 10:57:02 1995 221456 PSCRIPT.DLL
Oct 7 10:57:02 1995 184592 PSCRPTUI.DLL
Dave Hylands Email: DHylands@creo.bc.ca 3700 Gilmore Way
Senior Software Developer Tel: (604) 451-2700 x2329 Burnaby B.C.
Creo Products Inc. Fax: (604) 437-9891 Canada V5G 4M1
-----From: Jack.Zucker@software.rockwell.com (Zucker, Jack)
>If your bitmap uses more bpp you have a problem:
> MSVC 1.5 help quote:
> An application can select a bitmap into memory device contexts only and
> into only one memory device context at a time.
> The format of the bitmap must either be monochrome or compatible
> with the device context; if it is not, SelectObject returns an error.
If you notice in the original code, the CDC object 'dc' is
used to in
dc.CreateDC("DISPLAY",0,0,0);
but no where else this must have been test code that was not taken
out...
Yes that is correct. I forgot to take it out but it has nothing to do
with the problem.
also notice that the original code does call CreateCompatibleDC correctly
(I think).
No that's not correct. I'm getting a CDC* in my function which is the
printer DC.
I'm doing the following:
CDC memDC;
memDC.CreateCompatibleDC(pDC);
This is correct.
I think your statement regarding having the bitmap selected into only one
DC at a time or having the bitmap be incompatible with the destination DC
is probably not the problem either. In my test code, I always selected
the previous bitmap back into the memory DC and the printer DC had it's
previous bitmap reselected via calls to SaveDC() and RestoreDC().
Additionally, the bitmap was created and destroyed each time the function
was called. The bitmap was a color bitmap so there could possibly be an
issue there but since I created the bitmap by using the printer DC as in:
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC /*PrinterDC*/,width,height);
This should not have been a problem.
In fact, here is the code:
void MyView::PrintThisSucker(CDC* pPrinterDC /* MM_TEXT mode */)
{
CDC memDC;
memDC.CreateCompatibleDC(pPrinterDC);
CBitmap bmp;
bmp.CreateCompatibleBitmap(pPrinterDC,93,273);
CBrush brush(RGB(255,0,0));
CBitmap* pOld = memDC.SelectObject(&bmp);
memDC.FillRect(&CRect(0,0,93,273),&brush);
pPrinterDC->BitBlt(0,0,93,273,&memDC,0,0,SRCCOPY);
memDC.SelectObject(pOld);
}
Again, this works on the HP855C but not on the postscript printer. (Or is
it the other way around ?) In any event, if I change the memDC and Bitmap
to use a "DISPLAY" dc, it then prints on the opposite printer only. It
still never prints on both. The other thing that changes is if I change
the width and height. For some reason, 93x273 seems to be a magical
number because it prints on both printers if I change it to something
like 100x300. (Both printers support 300x300 DPI)
-Jaz
David Shak -- Dshak@TORONTO.DELRINA.com
Tuesday, February 27, 1996
>The answer doesn't have anything to do with MFC but it probably explains
>whats happening.
>Make sure that both printer drivers are actually using the same
PSCRIPT.DLL
>file. It seems like there are minor changes to each one with each
service
>pack
>and version of NT (It probably it isn't it just seems that way).
>Check C:\WINNT35\SYSTEM32\SPOOL\DRIVERS\W32ALPHA (or w32x86) and ALL of
the
>numbered directories found here.
......snip......
I really don't think the problem is with bad drivers... that would mean
the machine should not print bitmaps at all ( and that's not the case)
or that MFC does not work with these printer drivers which seems
unlikely.
......snip........
>void MyView::PrintThisSucker(CDC* pPrinterDC /* MM_TEXT mode */)
>{
> CDC memDC;
> memDC.CreateCompatibleDC(pPrinterDC);
> CBitmap bmp;
> bmp.CreateCompatibleBitmap(pPrinterDC,93,273);
> CBrush brush(RGB(255,0,0));
> CBitmap* pOld = memDC.SelectObject(&bmp);
> memDC.FillRect(&CRect(0,0,93,273),&brush);
> pPrinterDC->BitBlt(0,0,93,273,&memDC,0,0,SRCCOPY);
> memDC.SelectObject(pOld);
>}
In the above code, creating a bitmap and then BitBliting it is
not necessary, one call to FillRect using the correct DC
should work fine.
Dave.
Jack
Friday, March 01, 1996
You wrote:
>>void MyView::PrintThisSucker(CDC* pPrinterDC /* MM_TEXT mode */)
>>{
>> CDC memDC;
>> memDC.CreateCompatibleDC(pPrinterDC);
>> CBitmap bmp;
>> bmp.CreateCompatibleBitmap(pPrinterDC,93,273);
>> CBrush brush(RGB(255,0,0));
>
>> CBitmap* pOld = memDC.SelectObject(&bmp);
>> memDC.FillRect(&CRect(0,0,93,273),&brush);
>
>> pPrinterDC->BitBlt(0,0,93,273,&memDC,0,0,SRCCOPY);
>
>> memDC.SelectObject(pOld);
>>}
>
>In the above code, creating a bitmap and then BitBliting it is
>not necessary, one call to FillRect using the correct DC
>should work fine.
>
>Dave.
>
You missed the point. The FillRect() is just a placeholder for additional
code which can't simply be
draw to the destination DC.
-Jaz
| Вернуться в корень Архива
|