PrintRX.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. ///////////////////////////////////////////////////////////////////////
  2. // PrintRX.cpp: implementation of the CPrintRX class. //
  3. // It is written by Robin-Fox, (2004-03-03)it is free to use; //
  4. // I am glad it will give you some help in learning do printing. //
  5. // and i will also be glad that you make it works better though your //
  6. // rewrite.let the open sourse project make the world better. //
  7. // ----in BeiJing //
  8. ///////////////////////////////////////////////////////////////////////
  9. #include "stdafx.h"
  10. #include "LYFZSendMsg.h"
  11. #include "PrintRX.h"
  12. #ifdef _DEBUG
  13. #undef THIS_FILE
  14. static char THIS_FILE[]=__FILE__;
  15. #define new DEBUG_NEW
  16. #endif
  17. //////////////////////////////////////////////////////////////////////
  18. /*
  19. Procedure for use :
  20. =========================================================================
  21. 1. Declare an object of CPrintRX.
  22. 2. Call the member-function InitToPrint() to choose a Printer and initialize the object.
  23. 3. Call the member-function StartPrint(). This function MUST be called immediately
  24. after InitToPrint(), before other class-functions are be called. It creats the
  25. print-document in the printer-spooler (at the end EndPrint() will be called, in
  26. order to release it).
  27. 4. Add the fonts, which are needed, with the member-function AddFont().
  28. Principle it is enough to generate one font. The function returns a handle of the
  29. type int, which is then needed from various other member-functions. For
  30. each necessary font the function must be called once. There are only 10 different
  31. fonts possible.After this function you should call SetFontFace() then.
  32. Default is m_Fonts[0][0].
  33. 5. Adjust the margins and the line-space with the member-funktions SetMargins() and
  34. SetDistance(). MoveTo() set the point of the cursor aginst of m_Margnis.
  35. 6. MoveTo() set the point of the cursor aginst of m_Margnis.
  36. 7. Call member-function StartPage(), in order to begin a new page. If the page ends
  37. call EndPage(). Should it be necessary to print more lines between the call of
  38. these two functions, than on one page fits, the class ensures that that EndPage()
  39. is called followed by a StartPage() automaticaly. A possibly necessary head- and
  40. footingline are created.
  41. 8. Lines are printed with the function DrawHLine() and DrwawVLine().
  42. etc.
  43. 9. Call the member-funktion EndPrint(), in order to release the document in the
  44. spooler.
  45. 10. there are some thing to do to better it, Draw BItamp, etc
  46. */
  47. // Construction/Destruction
  48. //////////////////////////////////////////////////////////////////////
  49. CPrintRX::CPrintRX()
  50. {
  51. for (int i=0; i<10; i++)
  52. {
  53. m_iFace[i] = 0;
  54. for (int j=0; j<4; j++)
  55. m_font[i][j] = new (CFont);
  56. }
  57. m_nFonts = 0;
  58. m_iFont = 0;
  59. m_pPrintDlg = NULL;
  60. m_Margins.SetRect(0, 0, 0, 0);
  61. m_yCur = 0;
  62. m_xCur = 0;
  63. m_iPage = 1;
  64. m_nCopies = 1;
  65. }
  66. CPrintRX::~CPrintRX()
  67. {
  68. for (int i=0; i<10; i++)
  69. for (int j=0; j<4; j++)
  70. delete (m_font[i][j]);
  71. if (m_pPrintDlg)
  72. delete (m_pPrintDlg);
  73. if(m_newfont.GetSafeHandle ())m_newfont.DeleteObject ();
  74. }
  75. int CPrintRX::DrawText(char *str, int iFont, int iFace, int format)
  76. {
  77. m_DC.TextOut(m_xCur, m_yCur, str);
  78. m_memdc.TextOut(m_xCur, m_yCur, str);
  79. return 1;
  80. }
  81. void DrawPrintBit(HDC hdc, Image *img, CRect rc)
  82. {
  83. try
  84. {
  85. if(img)
  86. {
  87. Graphics graph(hdc);
  88. graph.SetPageUnit(UnitPixel);
  89. graph.SetSmoothingMode(SmoothingModeHighQuality);
  90. int width=img->GetWidth();
  91. int height=img->GetHeight();
  92. Rect destinationRect(rc.left , rc.top , rc.Width (), rc.Height ());
  93. graph.DrawImage(img, destinationRect, 0,0,width,height,UnitPixel);
  94. }
  95. }
  96. catch(...)
  97. {
  98. }
  99. }
  100. void CPrintRX::SetColor(COLORREF col)
  101. {
  102. if(col==0)
  103. {
  104. m_DC.SetTextColor (col);
  105. m_DC.SetBkColor (0xffffff);
  106. m_memdc.SetTextColor (col);
  107. m_memdc.SetBkColor (0xffffff);
  108. }
  109. else
  110. {
  111. m_DC.SetTextColor (col);
  112. m_DC.SetBkColor (0);
  113. m_memdc.SetTextColor (col);
  114. m_memdc.SetBkColor (0);
  115. }
  116. }
  117. void CPrintRX::DrawImage(Image *pImg, CRect& m_rt)
  118. {
  119. DrawPrintBit( m_DC.GetSafeHdc (), pImg , CRect(CALCX(m_rt.left),CALCY(m_rt.top),CALCX(m_rt.right),CALCY(m_rt.bottom) ));
  120. DrawPrintBit( m_memdc.GetSafeHdc (), pImg , CRect(CALCX(m_rt.left),CALCY(m_rt.top),CALCX(m_rt.right),CALCY(m_rt.bottom) ));
  121. }
  122. void CPrintRX::DrawRect(CRect& m_rt)
  123. {
  124. m_DC.FillSolidRect (CRect(CALCX(m_rt.left),CALCY(m_rt.top),CALCX(m_rt.right),CALCY(m_rt.bottom) ), 0);
  125. m_memdc.FillSolidRect (CRect(CALCX(m_rt.left),CALCY(m_rt.top),CALCX(m_rt.right),CALCY(m_rt.bottom) ), 0);
  126. }
  127. int CPrintRX::DrawText(char *str, CRect& m_rt, int iFont, int iFace, int format)
  128. {
  129. SIZE Size;
  130. GetTextExtentPoint32(m_DC.GetSafeHdc(), str, strlen(str), &Size);
  131. int left, top;
  132. if (format & FORMAT_HCENTER)
  133. {
  134. left = CALCX(m_rt.left) + CALCX(m_rt.Width())/2 - Size.cx/2;
  135. if (left < CALCX(m_rt.left))
  136. left = CALCX(m_rt.left);
  137. }
  138. else if(format & FORMAT_RIGHT)
  139. {
  140. left = CALCX(m_rt.left) + CALCX(m_rt.Width()) - Size.cx;
  141. if (left < CALCX(m_rt.left))
  142. left = CALCX(m_rt.left);
  143. }
  144. else
  145. left = CALCX(m_rt.left);
  146. if (format & FORMAT_VCENTER)
  147. {
  148. top = CALCY(m_rt.top) + CALCY(m_rt.Height())/2 - Size.cy/2;
  149. if (top < CALCY(m_rt.top))
  150. top = CALCY(m_rt.top);
  151. }
  152. else top = CALCY(m_rt.top);
  153. m_DC.TextOut(left, top, str);
  154. m_memdc.TextOut(left, top, str);
  155. return 1;
  156. }
  157. int CPrintRX::DrawHLine(int x_left, int y_left, int x_right, int y_right)
  158. {
  159. m_DC.MoveTo(CALCX(m_Margins.left + x_left), CALCY(m_Margins.top + y_left));
  160. m_DC.LineTo(CALCX(m_Margins.left + x_right), CALCY(m_Margins.top + y_right));
  161. m_memdc.MoveTo(CALCX(m_Margins.left + x_left), CALCY(m_Margins.top + y_left));
  162. m_memdc.LineTo(CALCX(m_Margins.left + x_right), CALCY(m_Margins.top + y_right));
  163. return 0;
  164. }
  165. int CPrintRX::DrawHLine(int x_left, int y_left, int x_right, int y_right, CPen &newpen)
  166. {
  167. CPen* oldPen = m_DC.SelectObject(&newpen);
  168. m_DC.MoveTo(CALCX(m_Margins.left + x_left), CALCY(m_Margins.top + y_left));
  169. m_DC.LineTo(CALCX(m_Margins.left + x_right), CALCY(m_Margins.top + y_right));
  170. m_DC.SelectObject(oldPen);
  171. oldPen = m_memdc.SelectObject(&newpen);
  172. m_memdc.MoveTo(CALCX(m_Margins.left + x_left), CALCY(m_Margins.top + y_left));
  173. m_memdc.LineTo(CALCX(m_Margins.left + x_right), CALCY(m_Margins.top + y_right));
  174. m_memdc.SelectObject(oldPen);
  175. return 0;
  176. }
  177. void CPrintRX::DrawRect2(CRect &rc, int mode)
  178. {
  179. if(mode==0)return;
  180. else if(mode==1)
  181. {
  182. DrawHLine(rc.left , rc.top , rc.right , rc.top );
  183. DrawHLine(rc.left , rc.bottom , rc.right , rc.bottom );
  184. DrawVLine(rc.left , rc.top , rc.left , rc.bottom );
  185. DrawVLine(rc.right , rc.top , rc.right , rc.bottom );
  186. }
  187. else if(mode==2)
  188. {
  189. DrawHLine(rc.left , rc.bottom , rc.right , rc.bottom );
  190. }
  191. }
  192. int CPrintRX::DrawVLine(int x_up, int y_up, int x_bottom, int y_bottom)
  193. {
  194. m_DC.MoveTo(CALCX(m_Margins.left + x_up), CALCY(m_Margins.top + y_up));
  195. m_DC.LineTo(CALCX(m_Margins.left + x_bottom), CALCY(m_Margins.top + y_bottom));
  196. m_memdc.MoveTo(CALCX(m_Margins.left + x_up), CALCY(m_Margins.top + y_up));
  197. m_memdc.LineTo(CALCX(m_Margins.left + x_bottom), CALCY(m_Margins.top + y_bottom));
  198. return 0;
  199. }
  200. int CPrintRX::DrawVLine(int x_up, int y_up, int x_bottom, int y_bottom, CPen &newpen)
  201. {
  202. CPen* oldPen = m_DC.SelectObject(&newpen);
  203. m_DC.MoveTo(CALCX(m_Margins.left + x_up), CALCY(m_Margins.top + y_up));
  204. m_DC.LineTo(CALCX(m_Margins.left + x_bottom), CALCY(m_Margins.top + y_bottom));
  205. m_DC.SelectObject(oldPen);
  206. oldPen = m_memdc.SelectObject(&newpen);
  207. m_memdc.MoveTo(CALCX(m_Margins.left + x_up), CALCY(m_Margins.top + y_up));
  208. m_memdc.LineTo(CALCX(m_Margins.left + x_bottom), CALCY(m_Margins.top + y_bottom));
  209. m_memdc.SelectObject(oldPen);
  210. return 0;
  211. }
  212. int CPrintRX::AddFont(CFont &newfont)
  213. {
  214. return -1;
  215. }
  216. int CPrintRX::AddFont(LOGFONT *lf)
  217. {
  218. if (m_nFonts == 10)
  219. return -1;
  220. m_font[m_nFonts][FACE_NORMAL]->CreateFontIndirect(lf);
  221. lf->lfWeight = FW_BLACK;
  222. m_font[m_nFonts][FACE_NORMALBOLD]->CreateFontIndirect(lf);
  223. lf->lfWeight = FW_REGULAR;
  224. lf->lfHeight = CALCF(25);
  225. m_font[m_nFonts][FACE_BIG]->CreateFontIndirect(lf);
  226. lf->lfWeight = FW_BLACK;
  227. m_font[m_nFonts][FACE_BIGBOLD]->CreateFontIndirect(lf);
  228. m_nFonts ++;
  229. return 0;
  230. }
  231. int CPrintRX::SetFontFace(int iFont, BOOL bWeight, CString name)
  232. {
  233. /* ASSERT(iFont < 10);
  234. ASSERT(iFace < 4);
  235. m_iFont = iFont;
  236. m_iFace[m_iFont] = iFace;
  237. m_DC.SelectObject(m_font[m_iFont][m_iFace[m_iFont]]);
  238. */
  239. LOGFONT log;
  240. log.lfHeight = CALCF(iFont); //add a kind of fond,let height equles 13
  241. log.lfWidth = 0;
  242. log.lfEscapement = 0;
  243. log.lfOrientation = 0;
  244. if(bWeight)
  245. log.lfWeight = FW_BLACK;
  246. else
  247. log.lfWeight = FW_REGULAR;
  248. log.lfItalic = false;
  249. log.lfUnderline = false;
  250. log.lfStrikeOut = 0;
  251. log.lfCharSet = ANSI_CHARSET;
  252. log.lfOutPrecision = OUT_DEFAULT_PRECIS;
  253. log.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  254. log.lfQuality = DEFAULT_QUALITY;
  255. log.lfPitchAndFamily = DEFAULT_PITCH || FF_ROMAN;
  256. // strcpy (log.lfFaceName,"Arial");
  257. strcpy (log.lfFaceName,name);
  258. if(m_newfont.GetSafeHandle ())m_newfont.DeleteObject ();
  259. m_newfont.CreateFontIndirect(&log);
  260. m_DC.SelectObject(&m_newfont);
  261. m_memdc.SelectObject(&m_newfont);
  262. return 0;
  263. }
  264. int CPrintRX::InitToPrint(char *PrinterName = NULL, int Copies = 1)
  265. {
  266. if (m_pPrintDlg == NULL) // delete it in ~CPrintRX()
  267. // m_pPrintDlg = new CPrintDialog(FALSE,PD_DISABLEPRINTTOFILE);
  268. m_pPrintDlg = new CPrintDialog(FALSE,PD_ALLPAGES|PD_NOPAGENUMS,NULL);
  269. ASSERT(m_pPrintDlg != NULL);
  270. if (PrinterName == NULL) // which printer ist desired, and how much copies?
  271. {
  272. // if (m_pPrintDlg->DoModal() == IDCANCEL)
  273. //return (-1);
  274. if(!m_pPrintDlg->GetDefaults())
  275. {
  276. return -1;
  277. }
  278. m_hPrinter = m_pPrintDlg->GetPrinterDC();
  279. m_nCopies = m_pPrintDlg->GetCopies();
  280. }
  281. else // a printer is given by name..
  282. {
  283. if (m_PrinterDC.CreateDC(NULL, PrinterName, NULL, NULL) == 0)
  284. {
  285. m_LastErrNo = PRERR_CANTCREATEPRINTERDC;
  286. return (-1); // failed, then set the num of Last Error
  287. }
  288. m_hPrinter = m_PrinterDC;
  289. m_nCopies = Copies;
  290. }
  291. if (m_DC.Attach(m_hPrinter) == 0)
  292. return (-1);
  293. m_DC.m_bPrinting = TRUE;
  294. if (m_pPrintDlg)
  295. delete (m_pPrintDlg);
  296. m_pPrintDlg = NULL;
  297. LOGFONT log;
  298. log.lfHeight = CALCF(4); //add a kind of fond,let height equles 13
  299. // log.lfHeight = CALCF(13); //add a kind of fond,let height equles 13
  300. log.lfWidth = 0;
  301. log.lfEscapement = 0;
  302. log.lfOrientation = 0;
  303. log.lfWeight = FW_REGULAR;
  304. log.lfItalic = false;
  305. log.lfUnderline = false;
  306. log.lfStrikeOut = 0;
  307. log.lfCharSet = ANSI_CHARSET;
  308. log.lfOutPrecision = OUT_DEFAULT_PRECIS;
  309. log.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  310. log.lfQuality = DEFAULT_QUALITY;
  311. log.lfPitchAndFamily = DEFAULT_PITCH || FF_ROMAN;
  312. strcpy (log.lfFaceName,"Arial");
  313. AddFont(&log);
  314. m_iFont = 0; //set default font is index of 0
  315. if(m_bmp.m_hObject )
  316. {
  317. m_bmp.DeleteObject ();
  318. }
  319. if(m_memdc.m_hDC==NULL)
  320. m_memdc.CreateCompatibleDC (NULL);
  321. int width= m_DC.GetDeviceCaps(HORZRES);
  322. int height= m_DC.GetDeviceCaps(VERTRES);
  323. m_bmp.CreateCompatibleBitmap (&m_DC, width, height);
  324. m_memdc.SelectObject (&m_bmp);
  325. m_memdc.FillSolidRect (0,0,width, height,0xffffff);
  326. return 0;
  327. }
  328. int CPrintRX::StartPrint()
  329. {
  330. CString strTitle; // Get the application title
  331. DOCINFO di; // Initialise print document details
  332. strTitle.LoadString(AFX_IDS_APP_TITLE);
  333. ::ZeroMemory(&di, sizeof (DOCINFO));
  334. di.cbSize = sizeof (DOCINFO);
  335. di.lpszDocName = strTitle;
  336. // Begin a new print job
  337. //"winerror.h" #define FAILED(Status) ((HRESULT)(Status)<0)
  338. if FAILED(m_DC.StartDoc(&di) == -1) return (-1);
  339. // Get the printing extents and store in the m_DimDraw fields
  340. m_WorkSize.cx = m_DC.GetDeviceCaps(HORZRES);
  341. m_WorkSize.cy = m_DC.GetDeviceCaps(VERTRES);
  342. return 0;
  343. }
  344. int CPrintRX::EndPrint()
  345. {
  346. m_DC.EndDoc(); // end a print job
  347. m_DC.Detach(); // detach the printer DC
  348. return 0;
  349. }
  350. int CPrintRX::SetMargins(int Top, int Bottom, int Left, int Right)
  351. {
  352. if (Top > 0)
  353. m_Margins.top = Top;
  354. if (Bottom > 0)
  355. m_Margins.bottom = Bottom;
  356. if (Left > 0)
  357. m_Margins.left = Left;
  358. if (Right > 0)
  359. m_Margins.right = Right;
  360. m_yCur = CALCY(m_Margins.top);
  361. m_xCur = CALCX(m_Margins.left);
  362. return 0;
  363. }
  364. void CPrintRX::SetDistance(int punkte)
  365. {
  366. m_Abstand = punkte;
  367. }
  368. int CPrintRX::StartPage()
  369. {
  370. if (m_DC.StartPage() < 0)
  371. {
  372. m_LastErrNo = PRERR_STARTPAGEFAILED;
  373. return (-1);
  374. }
  375. m_yCur = CALCY(m_Margins.top);
  376. m_xCur = CALCX(m_Margins.left);
  377. return 0;
  378. }
  379. void CPrintRX::EndPage()
  380. {
  381. m_DC.EndPage();
  382. }
  383. void CPrintRX::NewPage()
  384. {
  385. m_DC.EndPage();
  386. m_DC.StartPage();
  387. m_yCur = CALCY(m_Margins.top);
  388. m_xCur = CALCX(m_Margins.left);
  389. }
  390. int CPrintRX::GetWidth()
  391. {
  392. return MulDiv(m_WorkSize.cx, 72, GetDeviceCaps(m_DC.m_hDC, LOGPIXELSX));
  393. }
  394. int CPrintRX::GetStrSize(char *str, CSize &size)
  395. {
  396. GetTextExtentPoint32(m_DC.GetSafeHdc(), str, strlen(str), &size);
  397. size.cx = MulDiv(size.cx, 72, GetDeviceCaps(m_DC.m_hDC, LOGPIXELSX));
  398. size.cy = MulDiv(size.cy, 72, GetDeviceCaps(m_DC.m_hDC, LOGPIXELSY));
  399. return 0;
  400. }
  401. void CPrintRX::MoveTo(int xCur, int yCur)
  402. {
  403. m_xCur = CALCX(m_Margins.left + xCur);
  404. m_yCur = CALCY(m_Margins.right + yCur);
  405. }
  406. void CPrintRX::CalcuRc(CRect &rc)
  407. {
  408. rc.left =CALCX(rc.left);
  409. rc.right =CALCX(rc.right);
  410. rc.top =CALCY(rc.top );
  411. rc.bottom =CALCY(rc.bottom );
  412. }
  413. CDC * CPrintRX::GetPDC()
  414. {
  415. return &m_memdc;
  416. }
  417. void CPrintRX::GetWidHei(int &w, int &h)
  418. {
  419. BITMAP bm;
  420. m_bmp.GetBitmap (&bm);
  421. w=bm.bmWidth ;
  422. h=bm.bmHeight ;
  423. }