Get width and height in pixel of a paper before printing [modified]
-
Is there any way? My application needs to generate a graphic that fit the paper for printing. (DPIs of printers might varify.)
system
modified on Friday, September 5, 2008 4:53 AM
hi, you need a to use a standard unit to define the size of ua graphic other than using pixels e.g inches, coz if you use pixels , each printer will come with different aspect ratios of the pixel units, and you cud have a printer whose one inch long on paper , is say 100 pixels while on the screen of your computer it could have been 150 pixels making an inch of your image so you end up having a different image on paper . this is what i advise you to do. and i give an example of making some cells and they'll print same way thy appear on screean define 2 variables in the header file of your view call them, int m_nCellWidth and m_nCellHeight; Inside the Draw function of your view put this code. m_nCellWidth = pDC->GetDeviceCaps(LOGPIXELSX); m_nCellHeight = pDC->GetDeviceCaps(LOGPIXELSY)/4; what does this function do before assingning some values in your integers. the Function GetDeviceCaps(PARAMS) is a member of pDC (screen or printer) and it returns (depending on parameters) the number of pixels of the Devise context that make up one inch of y-axis (if PARAMS are LOGPIXELSY) or x - axis (if PARAMS are LOGPIXELSX); now you have a unit that is equivalent to a quarter of an inch on y axis (vertical axis) of any printer m_nCellHeight and another m_nCellWidth representing a an inch on x-axis. it's not a must you divide by 4, to make a quarter inch unit for y-axis, you can still use a full inch, it's olnly that the example i want to give you requires a quarter of an inch unit. now put this code. ////////////////////////////////////// int nMyPageHeight = (20 * m_nCellHeight ); // about 20 cells int nMyPageWidth = (5* m_nCellWidth); // about 5 columns for (int i=0; i { // draw horizantal lines from left to right pDC->MoveTo(0,i * m_nCellHeight); pDC->LineTo(nMyPageWidth ,i * m_nCellHeight); } for (int j=0; j { // draw vertical lines top of page to bottom pDC->MoveTo(j *m_nCellWidth ,0); pDC->LineTo(j *m_nCellWidth ,nMyPageHeight); } //////////////////////////////////////////////////// now try to print your image and see what happens. note that the print function calls the OnDraw() function of the view class and passes pDC, pointer to the printer, so if you call this code in another function other than the draw, make sure you call the Function from the OnDraw() function and pass pDC to it, dont use CClientDC(),
-
hi, you need a to use a standard unit to define the size of ua graphic other than using pixels e.g inches, coz if you use pixels , each printer will come with different aspect ratios of the pixel units, and you cud have a printer whose one inch long on paper , is say 100 pixels while on the screen of your computer it could have been 150 pixels making an inch of your image so you end up having a different image on paper . this is what i advise you to do. and i give an example of making some cells and they'll print same way thy appear on screean define 2 variables in the header file of your view call them, int m_nCellWidth and m_nCellHeight; Inside the Draw function of your view put this code. m_nCellWidth = pDC->GetDeviceCaps(LOGPIXELSX); m_nCellHeight = pDC->GetDeviceCaps(LOGPIXELSY)/4; what does this function do before assingning some values in your integers. the Function GetDeviceCaps(PARAMS) is a member of pDC (screen or printer) and it returns (depending on parameters) the number of pixels of the Devise context that make up one inch of y-axis (if PARAMS are LOGPIXELSY) or x - axis (if PARAMS are LOGPIXELSX); now you have a unit that is equivalent to a quarter of an inch on y axis (vertical axis) of any printer m_nCellHeight and another m_nCellWidth representing a an inch on x-axis. it's not a must you divide by 4, to make a quarter inch unit for y-axis, you can still use a full inch, it's olnly that the example i want to give you requires a quarter of an inch unit. now put this code. ////////////////////////////////////// int nMyPageHeight = (20 * m_nCellHeight ); // about 20 cells int nMyPageWidth = (5* m_nCellWidth); // about 5 columns for (int i=0; i { // draw horizantal lines from left to right pDC->MoveTo(0,i * m_nCellHeight); pDC->LineTo(nMyPageWidth ,i * m_nCellHeight); } for (int j=0; j { // draw vertical lines top of page to bottom pDC->MoveTo(j *m_nCellWidth ,0); pDC->LineTo(j *m_nCellWidth ,nMyPageHeight); } //////////////////////////////////////////////////// now try to print your image and see what happens. note that the print function calls the OnDraw() function of the view class and passes pDC, pointer to the printer, so if you call this code in another function other than the draw, make sure you call the Function from the OnDraw() function and pass pDC to it, dont use CClientDC(),
I think if generate a graphic according to the paper size for printing, the graphic will not be scaled. I wrote as below. I'm not sure whether it works (no printer on hand). And it seems lack of a print pool, doesn't it? When it's printing, how to make it like MS Word?
void CFigDlg::OnBnClickedBtnPrint()
{
using namespace Gdiplus;CPrintDialog dlg(TRUE, PD\_RETURNDC|PD\_ALLPAGES|PD\_USEDEVMODECOPIES|PD\_NOPAGENUMS|PD\_HIDEPRINTTOFILE|PD\_NOSELECTION, this); if (dlg.DoModal()==IDOK) { DEVMODE \*pDM=dlg.GetDevMode(); HDC hDC=dlg.GetPrinterDC(); CDC dc; dc.Attach(hDC); int dpi\_x=dc.GetDeviceCaps(LOGPIXELSX); int dpi\_y=dc.GetDeviceCaps(LOGPIXELSY); Size size; size.Width=INT(pDM->dmPaperWidth\*dpi\_x/2.54f); size.Height=INT(pDM->dmPaperLength\*dpi\_y/2.54f); if (bool(m\_pFig)) { Bitmap \*pBm=m\_pFig->GenBitmap(size); Graphics g(hDC); g.DrawImage(pBm,0,0); delete pBm; } }
}
system