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
| Вернуться в корень Архива |