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.

409 lines
9.7 KiB

  1. /***********************************************************************
  2. MODULE : WMFPRINT.C
  3. FUNCTIONS : PrintWMF
  4. GetPrinterDC
  5. AbortProc
  6. AbortDlg
  7. COMMENTS :
  8. ************************************************************************/
  9. #include <windows.h>
  10. #include <windowsx.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <math.h>
  14. #include <objbase.h>
  15. extern "C" {
  16. #include "mfdcod32.h"
  17. }
  18. extern "C" {
  19. extern BOOL bConvertToGdiPlus;
  20. extern BOOL bUseGdiPlusToPlay;
  21. }
  22. #include "GdiPlus.h"
  23. int PrintToGdiPlus(HDC hdc, RECT * rc)
  24. {
  25. // 'rc' is device co-ordinates of rectangle.
  26. // Convert to world space.
  27. if (bEnhMeta)
  28. {
  29. Gdiplus::Metafile m1(hemf);
  30. Gdiplus::Rect r1(rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top);
  31. Gdiplus::Graphics g(hdc);
  32. g.SetPageUnit(Gdiplus::UnitPixel);
  33. if(g.DrawImage(&m1, r1) != Gdiplus::Ok)
  34. MessageBox(NULL, "An Error Occured while printing metafile with GDI+", "Error", MB_OK | MB_ICONERROR);
  35. }
  36. else
  37. {
  38. Gdiplus::Metafile m1((HMETAFILE)hMF, NULL);
  39. Gdiplus::Rect r1(rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top);
  40. Gdiplus::Graphics g(hdc);
  41. g.SetPageUnit(Gdiplus::UnitPixel);
  42. if(g.DrawImage(&m1, r1) != Gdiplus::Ok)
  43. MessageBox(NULL, "An Error Occured while printing metafile with GDI+", "Error", MB_OK | MB_ICONERROR);
  44. }
  45. return 1;
  46. }
  47. extern BOOL bUseGdiPlusToPlay;
  48. PRINTDLG pd;
  49. /***********************************************************************
  50. FUNCTION : PrintWMF
  51. PARAMETERS : void
  52. PURPOSE : draw the metafile on a printer dc
  53. CALLS : WINDOWS
  54. wsprintf
  55. MessageBox
  56. MakeProcInstance
  57. Escape
  58. CreateDialog
  59. SetMapMode
  60. SetViewportOrg
  61. SetViewportExt
  62. EnableWindow
  63. PlayMetaFile
  64. DestroyWindow
  65. DeleteDC
  66. APP
  67. WaitCursor
  68. GetPrinterDC
  69. SetPlaceableExts
  70. SetClipMetaExts
  71. MESSAGES : none
  72. RETURNS : BOOL - 0 if unable to print 1 if successful
  73. COMMENTS :
  74. HISTORY : 1/16/91 - created - drc
  75. 7/9/93 - modified for win32 and emf
  76. ************************************************************************/
  77. BOOL PrintWMF(BOOL Dialog)
  78. {
  79. char str[50];
  80. POINT lpPT;
  81. SIZE lpSize;
  82. DOCINFO di;
  83. RECT rc;
  84. memset(&di, 0, sizeof(di));
  85. //
  86. //display the hourglass cursor
  87. //
  88. WaitCursor(TRUE);
  89. //
  90. //get a DC for the printer
  91. //
  92. hPr = (HDC)GetPrinterDC(Dialog);
  93. //
  94. //if a DC could not be created then report the error and return
  95. //
  96. if (!hPr)
  97. {
  98. WaitCursor(FALSE);
  99. wsprintf((LPSTR)str, "Cannot print %s", (LPSTR)fnameext);
  100. MessageBox(hWndMain, (LPSTR)str, NULL, MB_OK | MB_ICONHAND);
  101. return (FALSE);
  102. }
  103. //
  104. //define the abort function
  105. //
  106. SetAbortProc(hPr, AbortProc);
  107. //
  108. //Initialize the members of a DOCINFO structure.
  109. //
  110. di.cbSize = sizeof(DOCINFO);
  111. di.lpszDocName = (bEnhMeta) ? "Print EMF" : "Print WMF";
  112. di.lpszOutput = (LPTSTR) NULL;
  113. //
  114. //Begin a print job by calling the StartDoc
  115. //function.
  116. //
  117. if (SP_ERROR == (StartDoc(hPr, &di)))
  118. {
  119. //if (Escape(hPr, STARTDOC, 4, "Metafile", (LPSTR) NULL) < 0) {
  120. MessageBox(hWndMain, "Unable to start print job",
  121. NULL, MB_OK | MB_ICONHAND);
  122. DeleteDC(hPr);
  123. return (FALSE);
  124. }
  125. //
  126. //clear the abort flag
  127. //
  128. bAbort = FALSE;
  129. //
  130. //Create the Abort dialog box (modeless)
  131. //
  132. hAbortDlgWnd = CreateDialog((HINSTANCE)hInst, "AbortDlg", hWndMain, AbortDlg);
  133. //
  134. //if the dialog was not created report the error
  135. //
  136. if (!hAbortDlgWnd)
  137. {
  138. WaitCursor(FALSE);
  139. MessageBox(hWndMain, "NULL Abort window handle",
  140. NULL, MB_OK | MB_ICONHAND);
  141. return (FALSE);
  142. }
  143. //
  144. //show Abort dialog
  145. //
  146. ShowWindow (hAbortDlgWnd, SW_NORMAL);
  147. //
  148. //disable the main window to avoid reentrancy problems
  149. //
  150. EnableWindow(hWndMain, FALSE);
  151. WaitCursor(FALSE);
  152. //
  153. //if we are still committed to printing
  154. //
  155. if (!bAbort)
  156. {
  157. if (!bUseGdiPlusToPlay)
  158. {
  159. //
  160. //if this is a placeable metafile then set its origins and extents
  161. //
  162. if (bPlaceableMeta)
  163. SetPlaceableExts(hPr, placeableMFHeader, WMFPRINTER);
  164. //
  165. //if this is a metafile contained within a clipboard file then set
  166. //its origins and extents accordingly
  167. //
  168. if ( (bMetaInRam) && (!bplaceableMeta) )
  169. SetClipMetaExts(hPr, lpMFP, lpOldMFP, WMFPRINTER);
  170. }
  171. //
  172. //if this is a "traditional" windows metafile
  173. //
  174. rc.left = 0;
  175. rc.top = 0;
  176. rc.right = GetDeviceCaps(hPr, HORZRES);
  177. rc.bottom = GetDeviceCaps(hPr, VERTRES);
  178. if (!bMetaInRam)
  179. {
  180. SetMapMode(hPr, MM_TEXT);
  181. SetViewportOrgEx(hPr, 0, 0, &lpPT);
  182. //
  183. //set the extents to the driver supplied values for horizontal
  184. //and vertical resolution
  185. //
  186. SetViewportExtEx(hPr, rc.right, rc.bottom, &lpSize );
  187. }
  188. //
  189. //play the metafile directly to the printer.
  190. //No enumeration involved here
  191. //
  192. if (bUseGdiPlusToPlay)
  193. {
  194. PrintToGdiPlus(hPr, &rc);
  195. }
  196. else
  197. {
  198. if (bEnhMeta)
  199. {
  200. DPtoLP(hPr, (LPPOINT)&rc, 2);
  201. PlayEnhMetaFile(hPr, hemf, &rc);
  202. }
  203. else
  204. PlayMetaFile(hPr, (HMETAFILE)hMF);
  205. }
  206. }
  207. //
  208. //eject page and end the print job
  209. //
  210. Escape(hPr, NEWFRAME, 0, 0L, 0L);
  211. EndDoc(hPr);
  212. EnableWindow(hWndMain, TRUE);
  213. //
  214. //destroy the Abort dialog box
  215. //
  216. DestroyWindow(hAbortDlgWnd);
  217. DeleteDC(hPr);
  218. return(TRUE);
  219. }
  220. /***********************************************************************
  221. FUNCTION : GetPrinterDC
  222. PARAMETERS : BOOL: Do we want to show a print DLG?
  223. PURPOSE : Get hDc for current device on current output port according
  224. to info in WIN.INI.
  225. CALLS : WINDOWS
  226. GetProfileString
  227. AnsiNext
  228. CreateDC
  229. MESSAGES : none
  230. RETURNS : HANDLE - hDC > 0 if success hDC = 0 if failure
  231. COMMENTS : Searches WIN.INI for information about what printer is
  232. connected, and if found, creates a DC for the printer.
  233. HISTORY : 1/16/91 - created - denniscr
  234. ************************************************************************/
  235. HANDLE GetPrinterDC(BOOL Dialog)
  236. {
  237. memset(&pd, 0, sizeof(PRINTDLG));
  238. pd.lStructSize = sizeof(PRINTDLG);
  239. pd.Flags = PD_RETURNDC | (Dialog?0:PD_RETURNDEFAULT);
  240. pd.hwndOwner = hWndMain ;
  241. return ((PrintDlg(&pd) != 0) ? pd.hDC : NULL);
  242. }
  243. /***********************************************************************
  244. FUNCTION : AbortProc
  245. PARAMETERS : HDC hPr - printer DC
  246. int Code - printing status
  247. PURPOSE : process messages for the abort dialog box
  248. CALLS : WINDOWS
  249. PeekMessage
  250. IsDialogMessage
  251. TranslateMessage
  252. DispatchMessage
  253. MESSAGES : none
  254. RETURNS : int
  255. COMMENTS :
  256. HISTORY : 1/16/91 - created - denniscr
  257. ************************************************************************/
  258. BOOL CALLBACK AbortProc(HDC hPr, int Code)
  259. {
  260. MSG msg;
  261. //
  262. //Process messages intended for the abort dialog box
  263. //
  264. while (!bAbort && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  265. if (!IsDialogMessage(hAbortDlgWnd, &msg))
  266. {
  267. TranslateMessage(&msg);
  268. DispatchMessage(&msg);
  269. }
  270. //
  271. //bAbort is TRUE (return is FALSE) if the user has aborted
  272. //
  273. return (!bAbort);
  274. }
  275. /***********************************************************************
  276. FUNCTION : AbortDlg
  277. PARAMETERS : HWND hDlg;
  278. unsigned msg;
  279. WORD wParam;
  280. LONG lParam;
  281. PURPOSE : Processes messages for printer abort dialog box
  282. CALLS : WINDOWS
  283. SetFocus
  284. MESSAGES : WM_INITDIALOG - initialize dialog box
  285. WM_COMMAND - Input received
  286. RETURNS : BOOL
  287. COMMENTS : This dialog box is created while the program is printing,
  288. and allows the user to cancel the printing process.
  289. HISTORY : 1/16/91 - created - denniscr
  290. ************************************************************************/
  291. INT_PTR CALLBACK AbortDlg(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  292. {
  293. switch(msg)
  294. {
  295. //
  296. //Watch for Cancel button, RETURN key, ESCAPE key, or SPACE BAR
  297. //
  298. case WM_INITDIALOG:
  299. //
  300. //Set the focus to the Cancel box of the dialog
  301. //
  302. SetFocus(GetDlgItem(hDlg, IDCANCEL));
  303. return (TRUE);
  304. case WM_COMMAND:
  305. return (bAbort = TRUE);
  306. }
  307. return (FALSE);
  308. }