Printing to a printer onto a form
-
I need to have my printer print fields onto a form. So I need to print at precise locations of the form. I tried using MM_TEXT mode and cannot get the printer to print in exact location. I am trying MM_LOMETRIC, here are relevant source r_omap = pDC->SetMapMode (MM_LOMETRIC); pDC->SetViewportOrg (0,0); pDC->SetWindowOrg (0,0); pDC->SetTextAlign (TA_LEFT | TA_TOP); r_font.CreateFont (-40, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Courier New"); when I specify pDC->TextOut (1200, -140, str, sz); its moves x wise about 12.4 cm instead of 12 and about 1.9 cm down instead of 1.4 both x and y seem off by about 0.5 cm What am I missing ? Henri I am using Visual C++ 5.0
-
I need to have my printer print fields onto a form. So I need to print at precise locations of the form. I tried using MM_TEXT mode and cannot get the printer to print in exact location. I am trying MM_LOMETRIC, here are relevant source r_omap = pDC->SetMapMode (MM_LOMETRIC); pDC->SetViewportOrg (0,0); pDC->SetWindowOrg (0,0); pDC->SetTextAlign (TA_LEFT | TA_TOP); r_font.CreateFont (-40, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Courier New"); when I specify pDC->TextOut (1200, -140, str, sz); its moves x wise about 12.4 cm instead of 12 and about 1.9 cm down instead of 1.4 both x and y seem off by about 0.5 cm What am I missing ? Henri I am using Visual C++ 5.0
Usually what's missing with this is that software and the real world don't match up as precisely as one would like. Most printers don't ever actually see the whole sheet of paper, they're late detecting the top edge and often don't quite see the full width either, that's why they can't print accurately right to the edge of the paper ( a feature now advertised on some newer photo printers ). Most form printing applications I've seen have a user adjustable manual fudge factor prominent on the interface to allow for this. Coding for it is next to impossible because every model of printer is different, not well documented either and the same model can get worse over time due to ageing of spring based top edge detection. As you've gathered by now trying to print on preprinted stationery without a specialised printer is a mugs game. I wish you luck.
Nothing is exactly what it seems but everything with seems can be unpicked.
-
I need to have my printer print fields onto a form. So I need to print at precise locations of the form. I tried using MM_TEXT mode and cannot get the printer to print in exact location. I am trying MM_LOMETRIC, here are relevant source r_omap = pDC->SetMapMode (MM_LOMETRIC); pDC->SetViewportOrg (0,0); pDC->SetWindowOrg (0,0); pDC->SetTextAlign (TA_LEFT | TA_TOP); r_font.CreateFont (-40, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Courier New"); when I specify pDC->TextOut (1200, -140, str, sz); its moves x wise about 12.4 cm instead of 12 and about 1.9 cm down instead of 1.4 both x and y seem off by about 0.5 cm What am I missing ? Henri I am using Visual C++ 5.0
Try calling GetDeviceCaps() on your printer DC to obtain the PHYSICALOFFSETX and PHYSICALOFFSETY values. Your device may have a non-printable margin that you need to take into account. Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
I need to have my printer print fields onto a form. So I need to print at precise locations of the form. I tried using MM_TEXT mode and cannot get the printer to print in exact location. I am trying MM_LOMETRIC, here are relevant source r_omap = pDC->SetMapMode (MM_LOMETRIC); pDC->SetViewportOrg (0,0); pDC->SetWindowOrg (0,0); pDC->SetTextAlign (TA_LEFT | TA_TOP); r_font.CreateFont (-40, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Courier New"); when I specify pDC->TextOut (1200, -140, str, sz); its moves x wise about 12.4 cm instead of 12 and about 1.9 cm down instead of 1.4 both x and y seem off by about 0.5 cm What am I missing ? Henri I am using Visual C++ 5.0
Here's a quick sample to plop into a new CScrollView doc/view app to see if the results are consistent using print preview. It's more of a WYSIWYG approach and simplifies printing because it uses the same drawing code to print that is used for the screen. Try this out in a new project then adapt what you need to your application. NOTE: This was previous post of mine describing the print paging mechanism to someone but it demonstrates general printing. I hope it helps. //CDocument members... // Header file .h protected: CSize m_DocSize; // Implementation file .cpp CSize CYourDoc::GetDocSize() const { return m_DocSize; } CYourDoc::CYourDoc() { // TODO: add one-time construction code here m_DocSize=CSize(2000,2800); } //CScrollView members... // Header file .h private: int m_nPage; // Implementation file .cpp CYourView::CYourView() { // TODO: add construction code here SetScrollSizes(MM_TEXT,CSize(0,0)); // Set arbitrary values m_nPage=1; } /*************************************** NOTE: The pInfo parameter is uncommented ****************************************/ void CYourView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* pInfo) { // TODO: add extra initialization before printing pInfo->SetMaxPage(3); } void CYourView::OnPrint(CDC* pDC, CPrintInfo* pInfo) { // TODO: Add your specialized code here and/or call the base class m_nPage=pInfo->m_nCurPage; CScrollView::OnPrint(pDC, pInfo); } void CYourView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) { CScrollView::OnPrepareDC(pDC); // TODO: Add your specialized code here and/or call the base class // Set up the DC for the current scale factor int nExtentX; int nExtentY; CSize sizeDoc; CRect rectClient; pDC->SetMapMode(MM_ISOTROPIC); // Get pertinent rectangle data GetClientRect(&rectClient); sizeDoc=GetDocument()->GetDocSize(); sizeDoc.cy=(-sizeDoc.cy); // Y goes down as it increments pDC->SetWindowExt(sizeDoc); // Window extent is size of document // Calculate viewport extent nExtentX=rectClient.Width(); nExtentY=(int)((nExtentX*sizeDoc.cy)/(sizeDoc.cx)); // What kind of device context do we have? if (pDC->IsPrinting()==TRUE) { pDC->SetViewportExt(pDC->GetDeviceCaps(HORZRES),-pDC->GetDeviceCaps(VERTRES)); } else { // Context is for screen pDC->SetViewportExt(nExtentX,nExtentY); } } void CYourView::ResetScrollBars() { CSize sizeD
-
Try calling GetDeviceCaps() on your printer DC to obtain the PHYSICALOFFSETX and PHYSICALOFFSETY values. Your device may have a non-printable margin that you need to take into account. Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
I tried your suggestion, some follow up. When using Textout (x, y, str, sz); will the printer take location 0,0 from it's margi offsets or from the physical edge of the page. if PHYSICALOFFSETX return 100 if PHYSICALOFFSETY retunr 100 and I call textOut (0, 0, ...); will printer print from it's margin. Also GetDevCap for PHYSICALOFFSETX / Y return 100 is that in pixels ? Because I set MM_LOMETRIC if in Millemter would not make sense. I do not see any documentation on return values. Thanks Henri
-
I tried your suggestion, some follow up. When using Textout (x, y, str, sz); will the printer take location 0,0 from it's margi offsets or from the physical edge of the page. if PHYSICALOFFSETX return 100 if PHYSICALOFFSETY retunr 100 and I call textOut (0, 0, ...); will printer print from it's margin. Also GetDevCap for PHYSICALOFFSETX / Y return 100 is that in pixels ? Because I set MM_LOMETRIC if in Millemter would not make sense. I do not see any documentation on return values. Thanks Henri
Henri wrote:
I tried your suggestion
I can't guarantee that's a good idea :)
Henri wrote:
nd I call textOut (0, 0, ...); will printer print from it's margin.
I believe 0,0 is at the start of the printable area. If you print there, where does it appear on the page?
Henri wrote:
GetDevCap for PHYSICALOFFSETX / Y return 100 is that in pixels ?
It's in device units - pixels/dots.
Henri wrote:
Because I set MM_LOMETRIC if in Millemter would not make sense.
Yes. You'll need to use GetDeviceCaps(LOGPIXELSX//LOGPIXELSY) to get avalues to help you convert between pixels and inches/millimeters.
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Henri wrote:
I tried your suggestion
I can't guarantee that's a good idea :)
Henri wrote:
nd I call textOut (0, 0, ...); will printer print from it's margin.
I believe 0,0 is at the start of the printable area. If you print there, where does it appear on the page?
Henri wrote:
GetDevCap for PHYSICALOFFSETX / Y return 100 is that in pixels ?
It's in device units - pixels/dots.
Henri wrote:
Because I set MM_LOMETRIC if in Millemter would not make sense.
Yes. You'll need to use GetDeviceCaps(LOGPIXELSX//LOGPIXELSY) to get avalues to help you convert between pixels and inches/millimeters.
Mark Salsbery Microsoft MVP - Visual C++ :java:
Hi Mark, First thanks for your help, truly appreciated. Here's the bottom line I have tried practically all permutations of mapping modes ... with latest one as shown. Here is the one consistancy, despite the fact that, pDC->GetDeviceCaps (PHYSICALOFFSETX); pDC->GetDeviceCaps (PHYSICALOFFSETY); are the same (happens to be 100 for both) location 0,0 offset's horizontally 1/8 of inch and vertically 1/4 of an inch. The same happens for any point. Any clues as to why I keep getting this discranpency ? r_xmargin = pDC->GetDeviceCaps (PHYSICALOFFSETX); r_ymargin = pDC->GetDeviceCaps (PHYSICALOFFSETY); pDC->SetMapMode(MM_ISOTROPIC); pDC->SetWindowOrg(0, 0); pDC->SetWindowExt(600, 600); // logical window is 600 dpi pDC->SetViewportOrg(0, 0); // GetDeviceCaps(LOGPIXELSX)and Y are 600 // Device viewport is dpi of actual output device. pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX), pDC->GetDeviceCaps(LOGPIXELSY)); // r_xmargin and r_ymargin happen to both be 100 pDC->SetTextAlign (TA_LEFT | TA_TOP); pDC->TextOut (0, 0, "x", 1); pDC->TextOut (r_xmargin, 100, "x", 1); pDC->TextOut (r_xmargin/2, 200, "x", 1); pDC-?TextOut (r_xmargin + 50, 300, "x", 1); Henri Thanks again PS. Feel free to email me at paley007@msn.com
-
Hi Mark, First thanks for your help, truly appreciated. Here's the bottom line I have tried practically all permutations of mapping modes ... with latest one as shown. Here is the one consistancy, despite the fact that, pDC->GetDeviceCaps (PHYSICALOFFSETX); pDC->GetDeviceCaps (PHYSICALOFFSETY); are the same (happens to be 100 for both) location 0,0 offset's horizontally 1/8 of inch and vertically 1/4 of an inch. The same happens for any point. Any clues as to why I keep getting this discranpency ? r_xmargin = pDC->GetDeviceCaps (PHYSICALOFFSETX); r_ymargin = pDC->GetDeviceCaps (PHYSICALOFFSETY); pDC->SetMapMode(MM_ISOTROPIC); pDC->SetWindowOrg(0, 0); pDC->SetWindowExt(600, 600); // logical window is 600 dpi pDC->SetViewportOrg(0, 0); // GetDeviceCaps(LOGPIXELSX)and Y are 600 // Device viewport is dpi of actual output device. pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX), pDC->GetDeviceCaps(LOGPIXELSY)); // r_xmargin and r_ymargin happen to both be 100 pDC->SetTextAlign (TA_LEFT | TA_TOP); pDC->TextOut (0, 0, "x", 1); pDC->TextOut (r_xmargin, 100, "x", 1); pDC->TextOut (r_xmargin/2, 200, "x", 1); pDC-?TextOut (r_xmargin + 50, 300, "x", 1); Henri Thanks again PS. Feel free to email me at paley007@msn.com
Do GetDeviceCaps(LOGPIXELSX) and GetDeviceCaps(LOGPIXELSY) give you the same values? Also, instead of printing text to test this, draw lines or solid blocks. Your "x" text is immediately going to add some "margin" above the "x" since it's not a capital letter. Of course, there's more font metrics involved than just the height. Drawing graphics will give you a much better idea what you're working with. What type of printer is it? Also, check out Matthew Faithfull's comments in his reply above. Mark
Mark Salsbery Microsoft MVP - Visual C++ :java: