Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

307 lines
6.8 KiB

  1. /* File: D:\WACKER\tdll\printdc.c (Created: 26-Jan-1994)
  2. *
  3. * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 3 $
  7. * $Date: 7/08/02 6:45p $
  8. */
  9. #include <windows.h>
  10. #pragma hdrstop
  11. #include <term\res.h>
  12. #include "stdtyp.h"
  13. #include "assert.h"
  14. #include "print.h"
  15. #include "print.hh"
  16. #include "session.h"
  17. #include "tdll.h"
  18. #include "htchar.h"
  19. #include "globals.h"
  20. #define MAX_NUM_PRINT_DC 5
  21. struct stPrintTable
  22. {
  23. HPRINT hPrintHdl;
  24. HDC hDCPrint;
  25. };
  26. static struct stPrintTable stPrintCtrlTbl[MAX_NUM_PRINT_DC];
  27. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  28. * FUNCTION:
  29. * printCtrlCreateDC
  30. *
  31. * DESCRIPTION:
  32. * This function is used to create the Printer DC for the supplied Print
  33. * handle. It is done in this function so a table that contains both the
  34. * DC and the Print Handle can be maintained. This is necessary so the
  35. * PrintAbortProc function (which receives an HDC only) can determine
  36. * which Print Handle is associated with the HDC.
  37. *
  38. * The DC created by this function uses the Printer Name in the supplied
  39. * Printer Handle. If this name is not supplied, the function returns 0;
  40. *
  41. * ARGUMENTS:
  42. * HPRINT - The External Print handle.
  43. *
  44. * RETURNS:
  45. * HDC - A device context if successful, otherwise 0.
  46. *
  47. */
  48. HDC printCtrlCreateDC(const HPRINT hPrint)
  49. {
  50. const HHPRINT hhPrint = (HHPRINT)hPrint;
  51. TCHAR szPrinter[256];
  52. TCHAR *szDriver, *szOutput;
  53. int nIdx,
  54. iSize;
  55. HDC hDC;
  56. if (hPrint == 0)
  57. {
  58. assert(FALSE);
  59. return 0;
  60. }
  61. if (hhPrint->achPrinterName[0] == 0)
  62. {
  63. assert(FALSE);
  64. return 0;
  65. }
  66. for (nIdx = 0; nIdx < MAX_NUM_PRINT_DC; nIdx++)
  67. {
  68. if (stPrintCtrlTbl[nIdx].hPrintHdl == 0)
  69. {
  70. GetProfileString("Devices", hhPrint->achPrinterName, "",
  71. szPrinter, sizeof(szPrinter));
  72. hDC = 0;
  73. if ((szDriver = strtok(szPrinter, ",")) &&
  74. (szOutput = strtok(NULL, ",")))
  75. {
  76. hDC = CreateDC(szDriver, hhPrint->achPrinterName, szOutput,
  77. hhPrint->pstDevMode);
  78. }
  79. if (hDC == 0)
  80. {
  81. assert(FALSE);
  82. return 0;
  83. }
  84. if (hhPrint->pszPrinterPortName != 0)
  85. {
  86. free(hhPrint->pszPrinterPortName);
  87. hhPrint->pszPrinterPortName = NULL;
  88. }
  89. iSize = StrCharGetByteCount(szOutput) + 1;
  90. hhPrint->pszPrinterPortName = malloc((unsigned int)iSize);
  91. StrCharCopyN(hhPrint->pszPrinterPortName, szOutput, iSize);
  92. stPrintCtrlTbl[nIdx].hDCPrint = hDC;
  93. stPrintCtrlTbl[nIdx].hPrintHdl = hPrint;
  94. return (hDC);
  95. }
  96. }
  97. assert(FALSE);
  98. return 0;
  99. }
  100. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  101. * FUNCTION:
  102. * printCtrlDeleteDC
  103. *
  104. * DESCRIPTION:
  105. * This function will destroy the print HDC accociated with the
  106. * Printer Handle passed as the argument. See printCtrlCreateDC for
  107. * more information.
  108. *
  109. * ARGUMENTS:
  110. * HPRINT - The External Printer Handle.
  111. *
  112. * RETURNS:
  113. * void
  114. *
  115. */
  116. void printCtrlDeleteDC(const HPRINT hPrint)
  117. {
  118. const HHPRINT hhPrint = (HHPRINT)hPrint;
  119. int nIdx;
  120. if (hPrint == 0)
  121. assert(FALSE);
  122. if (hhPrint->hDC == 0)
  123. assert(FALSE);
  124. for (nIdx = 0; nIdx < MAX_NUM_PRINT_DC; nIdx++)
  125. {
  126. if (stPrintCtrlTbl[nIdx].hPrintHdl == hPrint)
  127. {
  128. if (DeleteDC(hhPrint->hDC) == TRUE)
  129. {
  130. stPrintCtrlTbl[nIdx].hPrintHdl = 0;
  131. stPrintCtrlTbl[nIdx].hDCPrint = 0;
  132. hhPrint->hDC = 0;
  133. return;
  134. }
  135. else
  136. {
  137. assert(FALSE);
  138. }
  139. }
  140. }
  141. assert(FALSE);
  142. return;
  143. }
  144. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  145. * FUNCTION:
  146. * printCtrlLookupDC
  147. *
  148. * DESCRIPTION:
  149. * This function returns the External Print Handle that includes the
  150. * supplied HDC. This function was designed to be called by the
  151. * PrintAbortProc routine. See printCtrlCreateDC for more info.
  152. *
  153. * ARGUMENTS:
  154. * HDC hDC - A (printer) device context.
  155. *
  156. * RETURNS:
  157. * HPRINT - An External print handle.
  158. *
  159. */
  160. HPRINT printCtrlLookupDC(const HDC hDC)
  161. {
  162. int nIdx;
  163. for (nIdx = 0; nIdx < MAX_NUM_PRINT_DC; nIdx++)
  164. {
  165. if (stPrintCtrlTbl[nIdx].hDCPrint == hDC)
  166. return stPrintCtrlTbl[nIdx].hPrintHdl;
  167. }
  168. assert(FALSE);
  169. return 0;
  170. }
  171. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  172. * FUNCTION:
  173. * printOpenDC
  174. *
  175. * DESCRIPTION:
  176. * Does the nasty work of opening a printer DC and initializing it.
  177. *
  178. * ARGUMENTS:
  179. * HHPRINT hhPrint - Internal print handle.
  180. *
  181. * RETURNS:
  182. * TRUE on success.
  183. *
  184. */
  185. int printOpenDC(const HHPRINT hhPrint)
  186. {
  187. HHPRINT hhSessPrint;
  188. int iLineHeight;
  189. int iVertRes;
  190. TCHAR achDocTitle[80];
  191. if (hhPrint == 0)
  192. {
  193. assert(FALSE);
  194. return FALSE;
  195. }
  196. if (hhPrint->hDC)
  197. return TRUE;
  198. // Get the printer information from the session print handle. This
  199. // includes the printer name and other attributes that may have been
  200. // setup by the common print dialogs.
  201. //
  202. hhSessPrint = (HHPRINT) sessQueryPrintHdl(hhPrint->hSession);
  203. printQueryPrinterInfo( hhSessPrint, hhPrint );
  204. // Create the DC.
  205. //
  206. hhPrint->hDC = printCtrlCreateDC((HPRINT)hhPrint);
  207. if (hhPrint->hDC == 0)
  208. {
  209. assert(FALSE);
  210. return FALSE;
  211. }
  212. printSetFont(hhPrint);
  213. printSetMargins(hhPrint);
  214. hhPrint->cx = hhPrint->marginsDC.left;
  215. hhPrint->cy = hhPrint->marginsDC.top;
  216. /* -------------- Figure out how many lines per page ------------- */
  217. GetTextMetrics(hhPrint->hDC, &hhPrint->tm);
  218. hhPrint->tmHeight = hhPrint->tm.tmHeight;
  219. iLineHeight = hhPrint->tm.tmHeight + hhPrint->tm.tmExternalLeading;
  220. iVertRes = GetDeviceCaps(hhPrint->hDC, VERTRES);
  221. iVertRes -= (hhPrint->marginsDC.top + hhPrint->marginsDC.bottom);
  222. if (iLineHeight == 0) //need to prevent a divide by zero error
  223. iLineHeight = 1;
  224. hhPrint->nLinesPerPage = max( iVertRes / iLineHeight, 1);
  225. hhPrint->nLinesPrinted = 0;
  226. if (LoadString(glblQueryDllHinst(), IDS_PRINT_CAPTURE_DOC,
  227. achDocTitle, sizeof(achDocTitle)/sizeof(TCHAR)))
  228. {
  229. lstrcpy(hhPrint->achDoc, achDocTitle);
  230. }
  231. /* -------------- Setup the Print Abort Proc ------------- */
  232. hhPrint->nStatus = SetAbortProc(hhPrint->hDC, (ABORTPROC)printAbortProc);
  233. /* -------------- Open printer ------------- */
  234. hhPrint->di.cbSize = sizeof(DOCINFO);
  235. hhPrint->di.lpszDocName = hhPrint->achDoc;
  236. hhPrint->di.lpszOutput = (LPTSTR)NULL;
  237. // StartDoc.
  238. //
  239. hhPrint->nStatus = StartDoc(hhPrint->hDC, &hhPrint->di);
  240. DbgOutStr("\r\nStartDoc: %d", hhPrint->nStatus, 0, 0, 0, 0);
  241. // StartPage.
  242. //
  243. if (hhPrint->nStatus > 0)
  244. {
  245. hhPrint->nStatus = StartPage(hhPrint->hDC);
  246. printSetFont( hhPrint );
  247. DbgOutStr("\r\nStartPage: %d", hhPrint->nStatus, 0, 0, 0, 0);
  248. }
  249. else
  250. {
  251. return FALSE;
  252. }
  253. if (hhPrint->nStatus <= 0)
  254. return FALSE;
  255. return TRUE;
  256. }