ListCtrlPrint.cpp
上传用户:ledldq
上传日期:2007-01-04
资源大小:95k
文件大小:9k
源码类别:

打印编程

开发平台:

Visual C++

  1. // ListCtrlPrint.cpp: implementation of the CListCtrlPrint class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "PrintManager.h"
  6. #include "ListCtrlPrint.h"
  7. #include "ListPrintSetup.h"
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. CListCtrlPrint::CListCtrlPrint()
  17. {
  18. rcMarginMM = CRect(10,10,10,10);
  19. szFtPrint = szFtHead = szFtFoot = CSize(0,0);
  20. pDx = NULL;
  21. iItemXPage = 1;
  22. iNumCol = 0;
  23. pList = NULL;
  24. szFoot = CSize(0,0);
  25. pFormat = NULL;
  26. pColTitle = NULL;
  27. iTotItem = 0;
  28. csFtHead = "Arial";
  29. csFtFoot = "Times New Roman";
  30. csFtPrint = "Arial";
  31. iFtHead = 12;
  32. iFtFoot = 6;
  33. iFtPrint = 8;
  34. }
  35. CListCtrlPrint::~CListCtrlPrint()
  36. {
  37. if (iNumCol) 
  38. {
  39. if (pDx) delete [] pDx;
  40. if (pFormat) delete [] pFormat;
  41. if (pColTitle)
  42. {
  43. for (int t = 0; t < iNumCol; t++)
  44. if (pColTitle[t]) delete [] pColTitle[t];
  45. delete [] pColTitle;
  46. }
  47. }
  48. }
  49. bool 
  50. CListCtrlPrint::OnPreparePrinting(CPrintInfo* pInfo, bool bPrintPreview)
  51. {
  52. pInfo->SetMinPage(1);
  53. if (!pList) return false;
  54. iTotItem = pList->GetItemCount();
  55. if (iTotItem <= 0) return false;
  56. ASSERT(pDx == NULL);
  57. CHeaderCtrl* pHeader = (CHeaderCtrl*)(pList->GetDlgItem(0));
  58. ASSERT(pHeader);
  59. iNumCol = pHeader->GetItemCount();
  60. if (iNumCol <= 0) return false;
  61. pDx = new int[iNumCol+1];
  62. pFormat = new int[iNumCol];
  63. pColTitle = new char *[iNumCol];
  64. ZeroMemory(pColTitle, sizeof(char *) * iNumCol);
  65. ZeroMemory(pDx, sizeof(int) * (iNumCol + 1));
  66. ZeroMemory(pFormat, sizeof(int) * iNumCol);
  67. char txt[128];
  68. for (int t = 0; t < iNumCol; t++)
  69. {
  70. HDITEM hi;
  71. hi.cchTextMax = 128;
  72. hi.pszText    = txt;
  73. hi.mask = HDI_TEXT|HDI_WIDTH|HDI_FORMAT;
  74. if (pHeader->GetItem(t, &hi))
  75. {
  76. pDx[t+1] = hi.cxy;
  77. pFormat[t] = hi.fmt;
  78. if (hi.cchTextMax > 0 && hi.pszText)
  79. {
  80. pColTitle[t] = new char[hi.cchTextMax];
  81. ASSERT(pColTitle[t]);
  82. lstrcpy(pColTitle[t], hi.pszText);
  83. }
  84. }
  85. }
  86. CListPrintSetup dlg;
  87. dlg.dlgSheet2.iSx = rcMarginMM.left;
  88. dlg.dlgSheet2.iUp = rcMarginMM.top;
  89. dlg.dlgSheet2.iDx = rcMarginMM.right;
  90. dlg.dlgSheet2.iDown = rcMarginMM.bottom;
  91. dlg.dlgSheet1.csFtHead = csFtHead;
  92. dlg.dlgSheet1.csFtFoot = csFtFoot;
  93. dlg.dlgSheet1.csFtPrint = csFtPrint;
  94. dlg.dlgSheet1.iFtHead = iFtHead;
  95. dlg.dlgSheet1.iFtFoot = iFtFoot;
  96. dlg.dlgSheet1.iFtPrint = iFtPrint;
  97. dlg.dlgSheet1.csHead = csPageHead;
  98. dlg.dlgSheet1.csFooter = csPageFooter;
  99. dlg.dlgSheet1.csPage = csPage;
  100. if (dlg.DoModal() == IDCANCEL) return false;
  101. rcMarginMM = CRect(dlg.dlgSheet2.iSx, dlg.dlgSheet2.iUp, dlg.dlgSheet2.iDx, dlg.dlgSheet2.iDown);
  102. csFtHead = dlg.dlgSheet1.csFtHead;
  103. csFtFoot = dlg.dlgSheet1.csFtFoot;
  104. csFtPrint = dlg.dlgSheet1.csFtPrint;
  105. iFtHead = dlg.dlgSheet1.iFtHead;
  106. iFtFoot = dlg.dlgSheet1.iFtFoot;
  107. iFtPrint = dlg.dlgSheet1.iFtPrint;
  108. csPageHead = dlg.dlgSheet1.csHead;
  109. csPageFooter = dlg.dlgSheet1.csFooter;
  110. csPage = dlg.dlgSheet1.csPage;
  111. return CPrinterJob::OnPreparePrinting(pInfo, bPrintPreview);
  112. }
  113. void 
  114. CListCtrlPrint::OnBeginPrinting(CDC * pDC, CPrintInfo * pInfo)
  115. {
  116. ftPrint.CreatePointFont(iFtPrint*10, csFtPrint, pDC);
  117. ftHead.CreatePointFont(iFtHead*10, csFtHead, pDC);
  118. ftFoot.CreatePointFont(iFtFoot*10, csFtFoot, pDC);;
  119. CString cs = "X";
  120. CFont * of = pDC->SelectObject(&ftPrint);
  121. szFtPrint = pDC->GetTextExtent(cs);
  122. pDC->SelectObject(&ftHead);
  123. szFtHead  = pDC->GetTextExtent(cs);
  124. pDC->SelectObject(&ftFoot);
  125. szFtFoot  = pDC->GetTextExtent(cs);
  126. pDC->SelectObject(of);
  127. szFtPrint.cy += 4;
  128. szFtHead.cy += 4;
  129. for (int t = 1; t <= iNumCol; t++) pDx[t] += pDx[t-1];
  130. CRect rcPrint(pInfo->m_rectDraw);
  131. SubtractMargin(pDC, rcPrint);
  132. double db = rcPrint.Width();
  133. db /= (double) pDx[iNumCol];
  134. for (t = 0; t <= iNumCol; t++) pDx[t] = (int)double(pDx[t] * db);
  135. ASSERT(pList);
  136. PrintListHead(pDC, rcPrint, true);
  137. PrintPageHead(pDC, rcPrint, 0, 0, true);
  138. CSize sz1 = PrintListFoot(pDC, rcPrint, true);
  139. CSize sz2 = PrintPageFoot(pDC, rcPrint, true);
  140. szFoot.cy = sz1.cy+sz2.cy + 2;
  141. iItemXPage = rcPrint.Height() / (szFtPrint.cy + 1) -1;
  142. int nPages = iTotItem / iItemXPage + 1;
  143. pInfo->SetMaxPage(nPages);
  144. }
  145. void 
  146. CListCtrlPrint::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
  147. {
  148. }
  149. void 
  150. CListCtrlPrint::SubtractMargin(CDC * pDC, CRect &rc)
  151. {
  152. CSize upsz(rcMarginMM.left*100, rcMarginMM.top*100);
  153. CSize dwsz(rcMarginMM.right*100, rcMarginMM.bottom*100);
  154. pDC->HIMETRICtoDP(&upsz);
  155. pDC->HIMETRICtoDP(&dwsz);
  156. rc.top    += upsz.cy;
  157. rc.left   += upsz.cx;
  158. rc.right  -= dwsz.cx;
  159. rc.bottom -= dwsz.cy;
  160. }
  161. void 
  162. CListCtrlPrint::OnPrint(CDC* pDC, CPrintInfo* pInfo)
  163. {
  164. CRect rcPrint(pInfo->m_rectDraw);
  165. SubtractMargin(pDC, rcPrint);
  166. int obkm = pDC->SetBkMode(TRANSPARENT);
  167. PrintPageHead(pDC, rcPrint, pInfo->m_nCurPage, (int) pInfo->GetMaxPage(), false);
  168. PrintListHead(pDC, rcPrint, false);
  169. int iFirst = (pInfo->m_nCurPage - 1) * iItemXPage;
  170. int iLast = (pInfo->m_nCurPage) * iItemXPage;
  171. int y = rcPrint.top;
  172. int x = rcPrint.left;
  173. CFont * oft = pDC->SelectObject(&ftPrint);
  174. CRect rc1;
  175. CString cs;
  176. int iMax = iTotItem;
  177. for (int i = iFirst; i < iLast; i++)
  178. {
  179. bool bIs = i < iMax;
  180. int box = 0;
  181. for (int t = 0; t < iNumCol; t++)
  182. {
  183. rc1.SetRect(rcPrint.left+pDx[t], y, rcPrint.left+pDx[t+1], y+szFtPrint.cy);
  184. if (bIs)
  185. {
  186. cs = pList->GetItemText(i, t);
  187. UINT ftm = DT_LEFT;
  188. if (pFormat[t]&HDF_CENTER) ftm = DT_CENTER;
  189. else if (pFormat[t]&HDF_RIGHT) ftm = DT_RIGHT;
  190. pDC->DrawText(cs, rc1, ftm|DT_VCENTER);
  191. }
  192. pDC->MoveTo(rc1.left,rc1.bottom);
  193. pDC->LineTo(rc1.left,rc1.top);
  194. pDC->LineTo(rc1.right,rc1.top);
  195. }
  196. pDC->LineTo(rc1.right,rc1.bottom);
  197. y += szFtPrint.cy + 1;
  198. }
  199. pDC->MoveTo(rcPrint.left,y);
  200. pDC->LineTo(rcPrint.right,y);
  201. pDC->SelectObject(oft);
  202. rcPrint = pInfo->m_rectDraw;
  203. SubtractMargin(pDC, rcPrint);
  204. rcPrint.top = rcPrint.bottom - szFoot.cy;
  205. PrintListFoot(pDC, rcPrint, false);
  206. PrintPageFoot(pDC, rcPrint, false);
  207. pDC->SetBkMode(obkm);
  208. }
  209. CSize 
  210. CListCtrlPrint::PrintPageHead(CDC * pDC, CRect & rcPage, const int nPage, const int iMaxPage, bool bCalc)
  211. {
  212. CFont * oft = pDC->SelectObject(&ftHead);
  213. int y = rcPage.top;
  214. int x = rcPage.left;
  215. CSize szPg(0,0);
  216. if (csPage != "")
  217. {
  218. CString cs;
  219. cs.Format(csPage, nPage, iMaxPage);
  220. CRect rc1(x,y,rcPage.right,y);
  221. pDC->DrawText(cs, rc1, DT_WORDBREAK|DT_CALCRECT|DT_RIGHT);
  222. rc1.left = rcPage.right - rc1.Width();
  223. rc1.right = rcPage.right;
  224. if (!bCalc) pDC->DrawText(cs, rc1, DT_WORDBREAK|DT_RIGHT);
  225. szPg = rc1.Size();
  226. }
  227. if (csPageHead != "")
  228. {
  229. CRect rc1(x,y,rcPage.right - szPg.cy,y);
  230. pDC->DrawText(csPageHead, rc1, DT_WORDBREAK|DT_CALCRECT|DT_LEFT);
  231. if (!bCalc) pDC->DrawText(csPageHead, rc1, DT_WORDBREAK|DT_LEFT);
  232. if (rc1.Height() > szPg.cy) szPg.cy = rc1.Height();
  233. }
  234. rcPage.top += szPg.cy;
  235. pDC->SelectObject(oft);
  236. return szPg;
  237. }
  238. CSize
  239. CListCtrlPrint::PrintPageFoot(CDC * pDC, CRect & rcPage, bool bCalc)
  240. {
  241. CFont * oft = pDC->SelectObject(&ftFoot);
  242. int y = rcPage.top;
  243. int x = rcPage.left;
  244. CSize szPg(0,0);
  245. if (csPageFooter != "")
  246. {
  247. CRect rc1(x,y,rcPage.right - szPg.cy,y);
  248. pDC->DrawText(csPageFooter, rc1, DT_WORDBREAK|DT_CALCRECT|DT_LEFT);
  249. if (!bCalc) pDC->DrawText(csPageFooter, rc1, DT_WORDBREAK|DT_LEFT);
  250. szPg.cy = rc1.Height();
  251. }
  252. rcPage.bottom -= szPg.cy;
  253. pDC->SelectObject(oft);
  254. return szPg;
  255. }
  256. CSize
  257. CListCtrlPrint::PrintListHead(CDC * pDC, CRect & rcPage, bool bCalc)
  258. {
  259. if (!bCalc)
  260. {
  261. CFont * oft = pDC->SelectObject(&ftPrint);
  262. CRect rcc(rcPage.left, rcPage.top, rcPage.right, rcPage.top + szFtPrint.cy);
  263. pDC->MoveTo(rcc.left, rcc.top);
  264. pDC->LineTo(rcc.right, rcc.top);
  265. pDC->LineTo(rcc.right, rcc.bottom);
  266. pDC->LineTo(rcc.left, rcc.bottom);
  267. pDC->LineTo(rcc.left, rcc.top);
  268. int box = 0;
  269. CRect rc1;
  270. int y = rcPage.top;
  271. for (int t = 0; t < iNumCol; t++)
  272. {
  273. rc1.SetRect(rcPage.left+pDx[t], y, rcPage.left+pDx[t+1], y+szFtPrint.cy);
  274. CString cs = pColTitle[t] ? pColTitle[t] : "";
  275. pDC->Rectangle(rc1);
  276. UINT ftm = DT_LEFT;
  277. if (pFormat[t]&HDF_CENTER) ftm = DT_CENTER;
  278. else if (pFormat[t]&HDF_RIGHT) ftm = DT_RIGHT;
  279. pDC->DrawText(cs, rc1, ftm|DT_VCENTER);
  280. pDC->MoveTo(rc1.left,rc1.bottom);
  281. pDC->LineTo(rc1.left,rc1.top);
  282. pDC->LineTo(rc1.right,rc1.top);
  283. }
  284. pDC->SelectObject(oft);
  285. }
  286. rcPage.top += szFtPrint.cy;
  287. return CSize(0,szFtPrint.cy);
  288. }
  289. CSize
  290. CListCtrlPrint::PrintListFoot(CDC * pDC, CRect & rcPage, bool bCalc)
  291. {
  292. return CSize(0,0);
  293. }