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.

1373 lines
40 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. prtcovpg.c
  5. Abstract
  6. Three componants of the composite page description file:
  7. 1) A header describing the other two componants.
  8. 2) An embebbed meta file of the page description objects.
  9. 3) Text strings (or resource ID's of string data
  10. requiring substitution of user data passed in to the
  11. function).
  12. Routine parses componants of composite page description file as
  13. created by the Windows XP "FaxCover" application; renders the
  14. objects to the DC, if hdc is not NULL.
  15. Author:
  16. Julia J. Robinson
  17. Revision History:
  18. Julia J. Robinson 6-7-96
  19. Julia J. Robinson 9-20-96 Allow passing paper size and orientation.
  20. Sasha Bessonov 10-28-99 Fixed initialization of view port for non printer devices
  21. Environment:
  22. Windows XP
  23. --*/
  24. #include <windows.h>
  25. #include <commdlg.h>
  26. #include <winspool.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <tchar.h>
  30. #include "faxutil.h"
  31. #include "prtcovpg.h"
  32. #include "resource.h"
  33. #include "strsafe.h"
  34. #define INITIAL_SIZE_OF_STRING_BUFFER 64
  35. #define NOTE_INDEX 22 // Index of "{Note}" in the InsertionTitle array.
  36. BYTE UNICODE_Signature[20]= {0x46,0x41,0x58,0x43,0x4F,0x56,0x45,0x52,0x2D,0x56,0x45,0x52,0x30,0x30,0x35,0x77,0x87,0x00,0x00,0x00};
  37. //
  38. // Resource ID's corresponding to fields of USERDATA.
  39. //
  40. WORD InsertionTagResourceID[]=
  41. {
  42. IDS_PROP_RP_NAME, // "{Recipient Name}"
  43. IDS_PROP_RP_FXNO, // "{Recipient Fax Number}"
  44. IDS_PROP_RP_COMP, // "{Recipient's Company}"
  45. IDS_PROP_RP_ADDR, // "{Recipient's Street Address}"
  46. IDS_PROP_RP_CITY, // "{Recipient's City}"
  47. IDS_PROP_RP_STAT, // "{Recipient's State}"
  48. IDS_PROP_RP_ZIPC, // "{Recipient's Zip Code}"
  49. IDS_PROP_RP_CTRY, // "{Recipient's Country}"
  50. IDS_PROP_RP_TITL, // "{Recipient's Title}"
  51. IDS_PROP_RP_DEPT, // "{Recipient's Department}"
  52. IDS_PROP_RP_OFFI, // "{Recipient's Office Location}"
  53. IDS_PROP_RP_HTEL, // "{Recipient's Home Telephone #}"
  54. IDS_PROP_RP_OTEL, // "{Recipient's Office Telephone #}"
  55. IDS_PROP_SN_NAME, // "{Sender Name}"
  56. IDS_PROP_SN_FXNO, // "{Sender Fax #}"
  57. IDS_PROP_SN_COMP, // "{Sender's Company}"
  58. IDS_PROP_SN_ADDR, // "{Sender's Address}"
  59. IDS_PROP_SN_TITL, // "{Sender's Title}"
  60. IDS_PROP_SN_DEPT, // "{Sender's Department}"
  61. IDS_PROP_SN_OFFI, // "{Sender's Office Location}"
  62. IDS_PROP_SN_HTEL, // "{Sender's Home Telephone #}"
  63. IDS_PROP_SN_OTEL, // "{Sender's Office Telephone #}"
  64. IDS_PROP_SN_EMAL, // "{Sender's E-mail}"
  65. IDS_PROP_MS_NOTE, // "{Note}"
  66. IDS_PROP_MS_SUBJ, // "{Subject}"
  67. IDS_PROP_MS_TSNT, // "{Time Sent}"
  68. IDS_PROP_MS_NOPG, // "{# of Pages}"
  69. IDS_PROP_RP_TOLS, // "{To: List}"
  70. IDS_PROP_RP_CCLS // "{Cc: List}"
  71. };
  72. LPTSTR
  73. ConvertStringToTString(LPCWSTR lpcwstrSource)
  74. /*++
  75. Routine Description:
  76. Converts string to T format
  77. Arguments:
  78. lpcwstrSource - source
  79. Return Value:
  80. Copied string or NULL
  81. Comment:
  82. The function returns NULL if lpcwstrSource == NULL or conversion failed
  83. --*/
  84. {
  85. LPTSTR lptstrDestination;
  86. if (!lpcwstrSource)
  87. return NULL;
  88. #ifdef UNICODE
  89. lptstrDestination = StringDup( lpcwstrSource );
  90. #else // !UNICODE
  91. lptstrDestination = UnicodeStringToAnsiString( lpcwstrSource );
  92. #endif // UNICODE
  93. return lptstrDestination;
  94. }
  95. DWORD
  96. CopyWLogFontToTLogFont(
  97. IN const LOGFONTW * plfSourceW,
  98. OUT LOGFONT * plfDest)
  99. {
  100. /*++
  101. Routine Description:
  102. This fuction copies a LogFont structure from UNICODE format
  103. to T format.
  104. Arguments:
  105. plfSourceW - reference to input UNICODE LongFont structure
  106. plfDest - reference to output LongFont structure
  107. Return Value:
  108. WINAPI last error
  109. --*/
  110. #ifndef UNICODE
  111. int iCount;
  112. #else
  113. HRESULT hr;
  114. #endif
  115. plfDest->lfHeight = plfSourceW->lfHeight ;
  116. plfDest->lfWidth = plfSourceW->lfWidth ;
  117. plfDest->lfEscapement = plfSourceW->lfEscapement ;
  118. plfDest->lfOrientation = plfSourceW->lfOrientation ;
  119. plfDest->lfWeight = plfSourceW->lfWeight ;
  120. plfDest->lfItalic = plfSourceW->lfItalic ;
  121. plfDest->lfUnderline = plfSourceW->lfUnderline ;
  122. plfDest->lfStrikeOut = plfSourceW->lfStrikeOut ;
  123. plfDest->lfCharSet = plfSourceW->lfCharSet ;
  124. plfDest->lfOutPrecision = plfSourceW->lfOutPrecision ;
  125. plfDest->lfClipPrecision = plfSourceW->lfClipPrecision ;
  126. plfDest->lfQuality = plfSourceW->lfQuality ;
  127. plfDest->lfPitchAndFamily = plfSourceW->lfPitchAndFamily ;
  128. SetLastError(0);
  129. #ifdef UNICODE
  130. hr = StringCchCopy(
  131. plfDest->lfFaceName,
  132. LF_FACESIZE,
  133. plfSourceW->lfFaceName);
  134. if (FAILED(hr))
  135. {
  136. return HRESULT_CODE(hr);
  137. }
  138. #else
  139. iCount = WideCharToMultiByte(
  140. CP_ACP,
  141. 0,
  142. plfSourceW->lfFaceName,
  143. -1,
  144. plfDest->lfFaceName,
  145. LF_FACESIZE,
  146. NULL,
  147. NULL
  148. );
  149. if (!iCount)
  150. {
  151. return GetLastError();
  152. }
  153. #endif
  154. return ERROR_SUCCESS;
  155. }
  156. DWORD WINAPI
  157. PrintCoverPage(
  158. HDC hDC,
  159. PCOVERPAGEFIELDS pUserData,
  160. LPCTSTR lpctstrTemplateFileName,
  161. PCOVDOCINFO pCovDocInfo
  162. )
  163. /*++
  164. Renders the coverpage into a printer DC using the size of a printer page.
  165. Also returns information on the cover page. See param documentation.
  166. Arguments:
  167. hDC - Device context. If NULL, we just read the file and set *pFlags
  168. pUserData - pointer to a structure containing user data
  169. for text insertions. May be NULL.
  170. lpctstrTemplateFileName - Name of the file created by the page editor,
  171. containing the META file.
  172. pCovDocInfo - pointer to structure contining information about the cover page file.
  173. This includes
  174. pCovDocInfo->NoteRect
  175. - Coordinates of the "Note" insertion rectangle, returned
  176. in device coordinates. This will be all 0 if hDC is NULL
  177. pCovDocInfo->Flags
  178. - Returns bitwise OR of the following (or more):
  179. COVFP_NOTE if .cov file contains a Note field.
  180. COVFP_SUBJECT if .cov file contains a Subject field.
  181. COVFP_NUMPAGES if .cov file contains Num Pages field.
  182. pCovDocInfo->PaperSize
  183. - may use in DEVMODE as dmPaperSize
  184. pCovDocInfo->Orientation
  185. - may use in DEVMODE as dmOrientation
  186. pCovDocInfo->NoteFont
  187. - Logfont structure to be used in rendering the NOTE.
  188. This will be meaningless if hDC is NULL.
  189. --*/
  190. {
  191. RECT ClientRect;
  192. DEBUG_FUNCTION_NAME(TEXT("PrintCoverPage"));
  193. Assert(lpctstrTemplateFileName);
  194. memset(&ClientRect,0,sizeof(ClientRect));
  195. if (hDC)
  196. {
  197. DWORD FullPrinterWidth; // PHYSICALWIDTH
  198. DWORD FullPrinterHeight; // PHYSICALHEIGHT
  199. DWORD PrinterUnitsX; // PHYSICALWIDTH - (width of margins)
  200. DWORD PrinterUnitsY; // PHYSICALHEIGHT - (height of margins)
  201. FullPrinterWidth = GetDeviceCaps( hDC, PHYSICALWIDTH );
  202. PrinterUnitsX = FullPrinterWidth - 2 * GetDeviceCaps( hDC, PHYSICALOFFSETX );
  203. FullPrinterHeight = GetDeviceCaps( hDC, PHYSICALHEIGHT );
  204. PrinterUnitsY = FullPrinterHeight - 2 * GetDeviceCaps( hDC, PHYSICALOFFSETY );
  205. ClientRect.top = GetDeviceCaps( hDC, PHYSICALOFFSETY );
  206. ClientRect.left = GetDeviceCaps( hDC, PHYSICALOFFSETX );
  207. ClientRect.right = ClientRect.left + FullPrinterWidth -1;
  208. ClientRect.bottom = ClientRect.top + PrinterUnitsY - 1;
  209. }
  210. return RenderCoverPage(
  211. hDC,
  212. &ClientRect,
  213. pUserData,
  214. lpctstrTemplateFileName,
  215. pCovDocInfo,
  216. FALSE
  217. );
  218. }
  219. DWORD WINAPI
  220. RenderCoverPage(
  221. HDC hDC,
  222. LPCRECT lpcRect,
  223. PCOVERPAGEFIELDS pUserData,
  224. LPCTSTR lpctstrTemplateFileName,
  225. PCOVDOCINFO pCovDocInfo,
  226. BOOL bPreview
  227. )
  228. /*++
  229. Renders a coverpage into a rectangle in the provided dc. Also returns information on the
  230. cover page. See param documentation.
  231. Arguments:
  232. hDC - Device context. If NULL, we just read the file and set *pFlags
  233. lpcRect - pointer to a RECT that specifies the rectangle into which the
  234. cover page template will be rendered.
  235. pUserData - pointer to a structure containing user data
  236. for text insertions. May be NULL.
  237. lpctstrTemplateFileName - Name of the file created by the page editor,
  238. containing the META file.
  239. pCovDocInfo - pointer to structure contining information about the cover page file.
  240. This includes
  241. pCovDocInfo->NoteRect
  242. - Coordinates of the "Note" insertion rectangle, returned
  243. in device coordinates. This will be all 0 if hDC is NULL
  244. pCovDocInfo->Flags
  245. - Returns bitwise OR of the following (or more):
  246. COVFP_NOTE if .cov file contains a Note field.
  247. COVFP_SUBJECT if .cov file contains a Subject field.
  248. COVFP_NUMPAGES if .cov file contains Num Pages field.
  249. pCovDocInfo->PaperSize
  250. - may use in DEVMODE as dmPaperSize
  251. pCovDocInfo->Orientation
  252. - may use in DEVMODE as dmOrientation
  253. pCovDocInfo->NoteFont
  254. - Logfont structure to be used in rendering the NOTE.
  255. This will be meaningless if hDC is NULL.
  256. pPreview - boolean flag that is TRUE if the function should render the text for
  257. cover page preview in the wizard and is FALSE for all other cases
  258. of normal full-size rendering.
  259. --*/
  260. {
  261. ENHMETAHEADER MetaFileHeader;
  262. UINT HeaderSize;
  263. LPBYTE pMetaFileBuffer = NULL;
  264. const BYTE *pConstMetaFileBuffer;
  265. DWORD rVal = ERROR_SUCCESS;
  266. INT TextBoxNbr;
  267. COLORREF PreviousColor;
  268. HFONT hThisFont = NULL;
  269. HGDIOBJ hPreviousFont;
  270. DWORD NbrBytesRead;
  271. RECT TextRect;
  272. RECT NoteRect;
  273. TEXTBOX TextBox; // buffer for reading in a TEXTBOX
  274. HENHMETAFILE MetaFileHandle = NULL;
  275. HANDLE CompositeFileHandle = INVALID_HANDLE_VALUE;
  276. COMPOSITEFILEHEADER CompositeFileHeader;
  277. INT HeightDrawn; // return value of DrawText()
  278. INT ReadBufferSize; // size of buffer for reading in strings.
  279. INT ThisBufSize; // size buffer needed for current text string.
  280. LPWSTR pStringReadIn = NULL; // buffer for reading in strings.
  281. LPWSTR pTmpString = NULL; // temporary pointer to realocated memory.
  282. LPTSTR pWhichTextToRender = NULL;// pStringReadIn v. ArrayOfData[i]
  283. LPTSTR lptstrStringReadIn = NULL;// LPTSTR of pStringReadIn
  284. LPTSTR lptstrArrayOfData = NULL;// ArrayOfData[i]
  285. INT i; // loop index
  286. LPTSTR * ArrayOfData; // uses pointers in UserData as ragged array.
  287. int CallersDCState = 0; // returned by SaveDC
  288. int MyDCState = 0; // returned by SaveDC
  289. DWORD ThisBit; // Flag field for current index.
  290. DWORD Flags; // Return these if pFlags != NULL.
  291. WORD MoreWords[3]; // Scale, PaperSize, and Orientation
  292. LOGFONT NoteFont; // Logfont structure found in the NOTE box
  293. LOGFONT FontDef; // Logfont structure
  294. HRGN hRgn = NULL;
  295. SIZE orgExt;
  296. POINT orgOrigin;
  297. SIZE orgPortExt;
  298. DWORD dwReadingOrder = 0;
  299. DEBUG_FUNCTION_NAME(TEXT("RenderCoverPage"));
  300. //
  301. // Initialize return values, handles, and pointers.
  302. //
  303. NoteRect.left = 0;
  304. NoteRect.right = 0;
  305. NoteRect.top = 0;
  306. NoteRect.bottom = 0;
  307. Flags = 0;
  308. hThisFont = NULL;
  309. CompositeFileHandle = INVALID_HANDLE_VALUE;
  310. MyDCState = 0;
  311. CallersDCState = 0;
  312. //
  313. // Initialize a Pointer so that
  314. //
  315. // ArrayOfData[0] ===== pUserData->RecName ,
  316. // ArrayOfData[1] ===== pUserData->RecFaxNumber ,
  317. // ... etc. ...
  318. if (pUserData){
  319. ArrayOfData = &pUserData->RecName;
  320. }
  321. ZeroMemory( &CompositeFileHeader, sizeof(COMPOSITEFILEHEADER) );
  322. ZeroMemory( &TextBox, sizeof(TEXTBOX) );
  323. //
  324. // Open the composite data file.
  325. //
  326. CompositeFileHandle = CreateFile(
  327. lpctstrTemplateFileName,
  328. GENERIC_READ,
  329. FILE_SHARE_READ,
  330. NULL,
  331. OPEN_EXISTING,
  332. FILE_ATTRIBUTE_NORMAL,
  333. NULL
  334. );
  335. if (CompositeFileHandle == INVALID_HANDLE_VALUE) {
  336. DebugPrintEx(
  337. DEBUG_ERR,
  338. TEXT("Failed to open COV template file [%s] (ec: %ld)"),
  339. lpctstrTemplateFileName,
  340. rVal
  341. );
  342. rVal = GetLastError();
  343. goto exit;
  344. }
  345. if(!ReadFile(CompositeFileHandle,
  346. &CompositeFileHeader,
  347. sizeof(CompositeFileHeader),
  348. &NbrBytesRead,
  349. NULL))
  350. {
  351. rVal = GetLastError();
  352. DebugPrintEx(
  353. DEBUG_ERR,
  354. TEXT("Failed to read composite file header (ec: %ld)"),
  355. rVal
  356. );
  357. goto exit;
  358. }
  359. //
  360. // Check the 20-byte signature in the header to see if the file
  361. // contains ANSI or UNICODE strings.
  362. //
  363. if ((sizeof(CompositeFileHeader) != NbrBytesRead) ||
  364. memcmp( UNICODE_Signature, CompositeFileHeader.Signature, 20 ))
  365. {
  366. rVal = ERROR_BAD_FORMAT;
  367. DebugPrintEx(
  368. DEBUG_ERR,
  369. TEXT("CompositeFile signature mismatch (ec: %ld)"),
  370. rVal
  371. );
  372. goto exit;
  373. }
  374. //
  375. // Extract the embedded META file from the composite file and move
  376. // into meta file buffer
  377. //
  378. pMetaFileBuffer = (LPBYTE) malloc( CompositeFileHeader.EmfSize );
  379. if (!pMetaFileBuffer){
  380. rVal = ERROR_NOT_ENOUGH_MEMORY;
  381. DebugPrintEx(
  382. DEBUG_ERR,
  383. TEXT("Failed to allocated metafile buffer (ec: %ld)"),
  384. rVal
  385. );
  386. goto exit;
  387. }
  388. if ((!ReadFile(
  389. CompositeFileHandle,
  390. pMetaFileBuffer,
  391. CompositeFileHeader.EmfSize,
  392. &NbrBytesRead,
  393. NULL ) ||
  394. CompositeFileHeader.EmfSize != NbrBytesRead))
  395. {
  396. rVal = GetLastError();
  397. DebugPrintEx(
  398. DEBUG_ERR,
  399. TEXT("Failed to read metafile (ec: %ld)"),
  400. rVal
  401. );
  402. goto exit;
  403. }
  404. if (hDC) { // Rendering
  405. int CRComplexity;
  406. hRgn = CreateRectRgnIndirect( lpcRect);
  407. if (!hRgn)
  408. {
  409. rVal = GetLastError();
  410. DebugPrintEx(
  411. DEBUG_ERR,
  412. TEXT("CreateRectRgnIndirect() failed (ec: %ld)"),
  413. rVal
  414. );
  415. goto exit;
  416. }
  417. CRComplexity = SelectClipRgn( hDC, hRgn );
  418. if (ERROR == CRComplexity)
  419. {
  420. rVal = ERROR_GEN_FAILURE;
  421. DebugPrintEx(
  422. DEBUG_ERR,
  423. TEXT("SelectClipRgn() failed (reported region complexity: %ld)"),
  424. CRComplexity
  425. );
  426. goto exit;
  427. }
  428. //
  429. // Save Device Context state
  430. //
  431. CallersDCState = SaveDC( hDC );
  432. if (CallersDCState == 0) {
  433. rVal = GetLastError();
  434. DebugPrintEx(
  435. DEBUG_ERR,
  436. TEXT("SaveDC() failed (ec: %ld)"),
  437. rVal
  438. );
  439. goto exit;
  440. }
  441. //
  442. // Set device context appropriately for rendering both text and metafile.
  443. //
  444. if (!CompositeFileHeader.EmfSize){
  445. //
  446. // No objects to render.
  447. //
  448. rVal = ERROR_NO_MORE_FILES;
  449. DebugPrintEx(
  450. DEBUG_ERR,
  451. TEXT("No objects to render in EMF file")
  452. );
  453. goto exit;
  454. }
  455. pConstMetaFileBuffer = pMetaFileBuffer;
  456. //
  457. // Create an enhanced metafile, in memory, from the data in the buffer.
  458. //
  459. MetaFileHandle = SetEnhMetaFileBits(
  460. CompositeFileHeader.EmfSize,
  461. pConstMetaFileBuffer
  462. );
  463. if (!MetaFileHandle) {
  464. rVal = GetLastError();
  465. DebugPrintEx(
  466. DEBUG_ERR,
  467. TEXT("SetEnhMetaFileBits() failed (ec: %ld)"),
  468. rVal);
  469. goto exit;
  470. }
  471. //
  472. // verify the metafile header.
  473. //
  474. HeaderSize = GetEnhMetaFileHeader(
  475. MetaFileHandle,
  476. sizeof(ENHMETAHEADER),
  477. &MetaFileHeader
  478. );
  479. if (!HeaderSize){
  480. rVal = GetLastError();
  481. DebugPrintEx(
  482. DEBUG_ERR,
  483. TEXT("GetEnhMetaFileHeader() failed (ec: %ld)"),
  484. rVal);
  485. goto exit;
  486. }
  487. //
  488. // Render the MetaFile
  489. //
  490. if (!PlayEnhMetaFile( hDC, MetaFileHandle, lpcRect )) {
  491. rVal = GetLastError();
  492. DebugPrintEx(
  493. DEBUG_ERR,
  494. TEXT("PlayEnhMetaFile() failed (ec: %ld)"),
  495. rVal);
  496. goto exit;
  497. }
  498. //
  499. // Set Device Context for rendering text.
  500. // Undo any changes that occurred when rendering the metafile.
  501. //
  502. RestoreDC( hDC, MyDCState );
  503. MyDCState = 0;
  504. if (CLR_INVALID == SetBkMode( hDC, TRANSPARENT)){
  505. rVal = GetLastError();
  506. DebugPrintEx(
  507. DEBUG_ERR,
  508. TEXT("SetBkMode() failed (ec: %ld)"),
  509. rVal);
  510. goto exit;
  511. }
  512. //
  513. // Set a mapping mode that will allow us to output the text boxes
  514. // in the same scale as the metafile.
  515. //
  516. if (!SetMapMode(hDC,MM_ANISOTROPIC))
  517. {
  518. rVal = GetLastError();
  519. DebugPrintEx(
  520. DEBUG_ERR,
  521. TEXT("SetMapMode() failed (ec: %ld)"),
  522. rVal);
  523. goto exit;
  524. }
  525. //
  526. // Set the logical coordinates to the total size (positve + negative) of the x and y axis
  527. // which is the same as the size of the cover page.
  528. //
  529. if (!SetWindowExtEx(
  530. hDC,
  531. CompositeFileHeader.CoverPageSize.cx,
  532. -CompositeFileHeader.CoverPageSize.cy,
  533. &orgExt
  534. ))
  535. {
  536. rVal = GetLastError();
  537. DebugPrintEx(
  538. DEBUG_ERR,
  539. TEXT("SetWindowExtEx() failed (ec: %ld)"),
  540. rVal);
  541. goto exit;
  542. };
  543. //
  544. // We map the logical space to a device space which is the size of the rectangle into
  545. // which we played the meta file.
  546. //
  547. if (!SetViewportExtEx(
  548. hDC,lpcRect->right - lpcRect->left,
  549. lpcRect->bottom - lpcRect->top,&orgPortExt
  550. ))
  551. {
  552. rVal = GetLastError();
  553. DebugPrintEx(
  554. DEBUG_ERR,
  555. TEXT("SetViewportExtEx() failed (ec: %ld)"),
  556. rVal);
  557. goto exit;
  558. };
  559. //
  560. // We map logical point (0,0) to the middle of the device space.
  561. //
  562. if (!SetWindowOrgEx(
  563. hDC,
  564. -CompositeFileHeader.CoverPageSize.cx/2,
  565. CompositeFileHeader.CoverPageSize.cy/2,
  566. &orgOrigin))
  567. {
  568. rVal = GetLastError();
  569. DebugPrintEx(
  570. DEBUG_ERR,
  571. TEXT("SetWindowOrgEx() failed (ec: %ld)"),
  572. rVal);
  573. goto exit;
  574. };
  575. }
  576. //
  577. // Initialize buffer for reading in strings.
  578. //
  579. ReadBufferSize = INITIAL_SIZE_OF_STRING_BUFFER;
  580. pStringReadIn = (LPWSTR) malloc( ReadBufferSize );
  581. if (!pStringReadIn) {
  582. rVal = ERROR_NOT_ENOUGH_MEMORY;
  583. DebugPrintEx(
  584. DEBUG_ERR,
  585. TEXT("Failed to allocate initial strings buffer (ec: %ld)"),
  586. rVal);
  587. goto exit;
  588. }
  589. //
  590. // Read in Text Box objects from the composite file and print out the text.
  591. //
  592. for (TextBoxNbr=0; TextBoxNbr < (INT) CompositeFileHeader.NbrOfTextRecords; ++TextBoxNbr)
  593. {
  594. if ((!ReadFile( CompositeFileHandle, &TextBox, sizeof(TEXTBOX), &NbrBytesRead, NULL)) ||
  595. NbrBytesRead != sizeof(TEXTBOX))
  596. {
  597. rVal = GetLastError();
  598. DebugPrintEx(
  599. DEBUG_ERR,
  600. TEXT("Failed to read text box number %ld (ec: %ld)"),
  601. TextBoxNbr,
  602. rVal);
  603. goto exit;
  604. }
  605. //
  606. // Check buffer size, lock buffer, and
  607. // read in variable length string of text.
  608. //
  609. ThisBufSize = sizeof(WCHAR) * (TextBox.NumStringBytes + 1);
  610. if (ReadBufferSize < ThisBufSize) {
  611. pTmpString = realloc( pStringReadIn, ThisBufSize );
  612. if (!pTmpString)
  613. {
  614. rVal = ERROR_NOT_ENOUGH_MEMORY;
  615. DebugPrintEx(
  616. DEBUG_ERR,
  617. TEXT("Failed to realloc text box number %ld buffer. Requested size was %ld (ec: %ld)"),
  618. TextBoxNbr,
  619. ThisBufSize,
  620. rVal);
  621. goto exit;
  622. }
  623. else
  624. {
  625. pStringReadIn = pTmpString;
  626. pTmpString = NULL;
  627. }
  628. }
  629. if ((!ReadFile( CompositeFileHandle, (void*)pStringReadIn, TextBox.NumStringBytes, &NbrBytesRead, NULL)) ||
  630. NbrBytesRead != TextBox.NumStringBytes)
  631. {
  632. rVal = GetLastError();
  633. DebugPrintEx(
  634. DEBUG_ERR,
  635. TEXT("Failed to read text box number %ld content (ec: %ld)"),
  636. TextBoxNbr,
  637. rVal);
  638. goto exit;
  639. }
  640. pStringReadIn[TextBox.NumStringBytes / sizeof(WCHAR)] = 0;
  641. if (lptstrStringReadIn) {
  642. MemFree(lptstrStringReadIn);
  643. lptstrStringReadIn = NULL;
  644. }
  645. if (pStringReadIn && (!(lptstrStringReadIn = ConvertStringToTString(pStringReadIn))))
  646. {
  647. rVal = ERROR_NOT_ENOUGH_MEMORY;
  648. DebugPrintEx(
  649. DEBUG_ERR,
  650. TEXT("Failed to covert string to TString (ec: %ld)"),
  651. rVal);
  652. goto exit;
  653. }
  654. if (hDC)
  655. {
  656. //
  657. // Correct position of text box.
  658. //
  659. TextRect.top = max( TextBox.PositionOfTextBox.top, TextBox.PositionOfTextBox.bottom );
  660. TextRect.left = min( TextBox.PositionOfTextBox.left, TextBox.PositionOfTextBox.right );
  661. TextRect.bottom = min( TextBox.PositionOfTextBox.top, TextBox.PositionOfTextBox.bottom );
  662. TextRect.right = max( TextBox.PositionOfTextBox.left, TextBox.PositionOfTextBox.right );
  663. }
  664. if (TextBox.ResourceID)
  665. {
  666. //
  667. // Text box contains a FAX PROPERTY field.
  668. // Find appropriate field of USERDATA for this resource ID.
  669. //
  670. for (i=0,ThisBit=1; i<NUM_INSERTION_TAGS; ++i,ThisBit<<=1)
  671. {
  672. if (TextBox.ResourceID == InsertionTagResourceID[i])
  673. {
  674. lptstrArrayOfData = pUserData ? ArrayOfData[i] : NULL;
  675. //
  676. // Set Flags bit to indicate this FAX PROPERTY field is present.
  677. //
  678. Flags |= ThisBit;
  679. break;
  680. }
  681. }
  682. if (TextBox.ResourceID == IDS_PROP_MS_NOTE && hDC)
  683. {
  684. //
  685. // NOTE field found. Return its rectangle in device coordinates.
  686. // Return its LOGFONT with height adjusted for device coordinates.
  687. //
  688. NoteRect = TextRect;
  689. LPtoDP( hDC, (POINT*)&NoteRect, 2 );
  690. if ((rVal = CopyWLogFontToTLogFont(&TextBox.FontDefinition,&NoteFont)) != ERROR_SUCCESS)
  691. {
  692. DebugPrintEx(
  693. DEBUG_ERR,
  694. TEXT("CopyWLogFontToTLogFont() failed (ec: %ld)"),
  695. rVal);
  696. goto exit;
  697. }
  698. NoteFont.lfHeight = (LONG)MulDiv(
  699. (int)NoteFont.lfHeight,
  700. GetDeviceCaps( hDC, LOGPIXELSY ),
  701. 100
  702. );
  703. }
  704. }
  705. pWhichTextToRender = (lptstrStringReadIn[0] != (TCHAR)'\0') ? lptstrStringReadIn : lptstrArrayOfData;
  706. if (hDC && pWhichTextToRender)
  707. {
  708. //
  709. // Set text color and font for rendering text.
  710. //
  711. PreviousColor = SetTextColor( hDC, TextBox.TextColor );
  712. if (PreviousColor == CLR_INVALID){
  713. rVal = GetLastError();
  714. DebugPrintEx(
  715. DEBUG_ERR,
  716. TEXT("SetTextColor() failed (ec: %ld)"),
  717. rVal);
  718. goto exit;
  719. }
  720. if ((rVal = CopyWLogFontToTLogFont(&TextBox.FontDefinition,&FontDef)) != ERROR_SUCCESS)
  721. {
  722. DebugPrintEx(
  723. DEBUG_ERR,
  724. TEXT("CopyWLogFontToTLogFont() failed (ec: %ld)"),
  725. rVal);
  726. goto exit;
  727. }
  728. if (bPreview)
  729. {
  730. //
  731. // For CoverPage Preview, we want to get only TT font
  732. // That is able to draw a small letters.
  733. //
  734. //
  735. // Add OUT_TT_ONLY_PRECIS to force the TTF
  736. //
  737. FontDef.lfOutPrecision |= OUT_TT_ONLY_PRECIS;
  738. }
  739. hThisFont = CreateFontIndirect( &FontDef );
  740. if (!hThisFont) {
  741. rVal = GetLastError();
  742. DebugPrintEx(
  743. DEBUG_ERR,
  744. TEXT("CreateFontIndirect() failed (ec: %ld)"),
  745. rVal);
  746. goto exit;
  747. }
  748. hPreviousFont = SelectObject( hDC, hThisFont );
  749. if (!hPreviousFont) {
  750. rVal = GetLastError();
  751. DebugPrintEx(
  752. DEBUG_ERR,
  753. TEXT("SelectObject() failed (ec: %ld)"),
  754. rVal);
  755. goto exit;
  756. }
  757. if (bPreview)
  758. {
  759. //
  760. // Now check that created font is real TTF
  761. //
  762. TEXTMETRIC TextMetric;
  763. HGDIOBJ hPrevFont = NULL;
  764. if (!GetTextMetrics(hDC, &TextMetric))
  765. {
  766. rVal = GetLastError();
  767. DebugPrintEx(DEBUG_ERR, _T("GetTextMetrics() failed (ec: %ld)"), rVal);
  768. goto exit;
  769. }
  770. if ( ! ( (TextMetric.tmPitchAndFamily & TMPF_TRUETYPE) > 0))
  771. {
  772. //
  773. // This is not TT font
  774. // In this case, the selected font cannot correct represent
  775. // the small letters in the CoverPage preview.
  776. // So, we hard-coded put the font to be Tahoma, which is TTF
  777. //
  778. HRESULT hr = StringCchCopy(
  779. FontDef.lfFaceName,
  780. LF_FACESIZE,
  781. _T("Tahoma"));
  782. if (FAILED(hr))
  783. {
  784. //
  785. // Should never happen, large enough buffer.
  786. //
  787. ASSERT_FALSE;
  788. }
  789. //
  790. // Create new font
  791. //
  792. hThisFont = CreateFontIndirect( &FontDef );
  793. if (!hThisFont)
  794. {
  795. rVal = GetLastError();
  796. DebugPrintEx(DEBUG_ERR, _T("CreateFontIndirect(2) failed (ec: %ld)"), rVal);
  797. goto exit;
  798. }
  799. hPrevFont = SelectObject( hDC, hThisFont );
  800. if (!hPrevFont)
  801. {
  802. rVal = GetLastError();
  803. DebugPrintEx(DEBUG_ERR, _T("SelectObject(2) failed (ec: %ld)"), rVal);
  804. goto exit;
  805. }
  806. //
  807. // Delete previous font - the one that was created wrong
  808. //
  809. DeleteObject(hPrevFont);
  810. }
  811. }
  812. dwReadingOrder = 0;
  813. if (TextBox.ResourceID && StrHasRTLChar(LOCALE_SYSTEM_DEFAULT, pWhichTextToRender))
  814. {
  815. dwReadingOrder = DT_RTLREADING;
  816. }
  817. //
  818. // Render the text.
  819. //
  820. HeightDrawn = DrawText(hDC,
  821. pWhichTextToRender,
  822. -1,
  823. &TextRect,
  824. DT_NOPREFIX | DT_WORDBREAK | TextBox.TextAlignment | dwReadingOrder);
  825. if (!HeightDrawn)
  826. {
  827. rVal = GetLastError();
  828. DebugPrintEx(
  829. DEBUG_ERR,
  830. TEXT("DrawText() failed for textbox #%ld with content [%s] (ec: %ld)"),
  831. TextBoxNbr,
  832. pWhichTextToRender,
  833. rVal);
  834. goto exit;
  835. }
  836. //
  837. // Restore previous font and release the handle to the selected font
  838. //
  839. SelectObject( hDC, (HFONT)hPreviousFont );
  840. SetTextColor( hDC, PreviousColor );
  841. DeleteObject( hThisFont );
  842. hThisFont = NULL;
  843. }
  844. //
  845. // Null the data string so it won't be accidently used in the next data field.
  846. //
  847. lptstrArrayOfData = NULL;
  848. } // Ends loop over all textboxes.
  849. //
  850. // Read on to get Orientation and PaperSize
  851. //
  852. if ((!ReadFile( CompositeFileHandle, MoreWords, 3*sizeof(WORD), &NbrBytesRead, NULL )) ||
  853. NbrBytesRead != 3 * sizeof(WORD))
  854. {
  855. rVal = GetLastError();
  856. DebugPrintEx(
  857. DEBUG_ERR,
  858. TEXT("Failed to read Orientation and PaperSize (ec: %ld)"),
  859. rVal);
  860. goto exit;
  861. }
  862. exit:
  863. if (MetaFileHandle)
  864. {
  865. DeleteEnhMetaFile( MetaFileHandle );
  866. }
  867. if (lptstrStringReadIn)
  868. {
  869. MemFree(lptstrStringReadIn);
  870. }
  871. if (hThisFont)
  872. {
  873. DeleteObject( hThisFont );
  874. }
  875. if (pStringReadIn) {
  876. free( pStringReadIn );
  877. }
  878. if (pMetaFileBuffer)
  879. {
  880. free( pMetaFileBuffer );
  881. }
  882. if (CompositeFileHandle != INVALID_HANDLE_VALUE)
  883. {
  884. CloseHandle( CompositeFileHandle );
  885. }
  886. if( MyDCState )
  887. {
  888. RestoreDC( hDC, MyDCState );
  889. }
  890. if( CallersDCState )
  891. {
  892. RestoreDC( hDC, CallersDCState );
  893. }
  894. if (rVal == 0 && pCovDocInfo != NULL)
  895. {
  896. pCovDocInfo->Flags = Flags;
  897. pCovDocInfo->NoteRect = NoteRect;
  898. pCovDocInfo->PaperSize = (short) MoreWords[1];
  899. pCovDocInfo->Orientation = (short) MoreWords[2];
  900. pCovDocInfo->NoteFont = NoteFont;
  901. }
  902. if (hRgn)
  903. {
  904. DeleteObject(hRgn);
  905. }
  906. return rVal;
  907. }
  908. DWORD
  909. PrintCoverPageToFile(
  910. LPTSTR lptstrCoverPage,
  911. LPTSTR lptstrTargetFile,
  912. LPTSTR lptstrPrinterName,
  913. short sCPOrientation,
  914. short sCPYResolution,
  915. PCOVERPAGEFIELDS pCPFields)
  916. /*++
  917. Author:
  918. Ronen Barenboim 25-March-2000
  919. Routine Description:
  920. Renders a cover page template into a TIFF file by printing it into file using the specified printer.
  921. Arguments:
  922. [IN] lptstrCoverPage - Full path to the cover page template file.
  923. [IN] lptstrTargetFile - Full path to the file in which the TIFF will be stores.
  924. The function will create this file.
  925. [IN] lptstrPrinterName - The name of the printer to which the cover page will be printed
  926. in order to generate the TIFF file.
  927. [IN] sCPOrientation - The cover page orientation.
  928. [IN] sCPYResolution - coverpage Y resolution. 0 for the printer default
  929. [IN] pCPFields - Points to a cover page information structure. Its fields will be used to
  930. replace the cov template fields.
  931. Return Value:
  932. ERROR_SUCCESS on success. A Win32 error code on failure.
  933. --*/
  934. {
  935. COVDOCINFO covDocInfo;
  936. DOCINFO DocInfo;
  937. HDC hDC = NULL;
  938. INT JobId = 0;
  939. BOOL bRet = FALSE;
  940. DWORD dwRet = ERROR_SUCCESS;
  941. BOOL bEndPage = FALSE;
  942. LONG lSize;
  943. HANDLE hPrinter = NULL;
  944. PDEVMODE pDevMode = NULL;
  945. DEBUG_FUNCTION_NAME(TEXT("PrintCoverPageToFile"));
  946. Assert(lptstrPrinterName);
  947. Assert(lptstrTargetFile);
  948. Assert(pCPFields);
  949. Assert(lptstrCoverPage);
  950. Assert (sCPOrientation == DMORIENT_LANDSCAPE || sCPOrientation == DMORIENT_PORTRAIT);
  951. Assert (sCPYResolution == 0 || sCPYResolution == 98 || sCPYResolution == 196);
  952. //
  953. // open the printer for normal access (this should always work)
  954. //
  955. if (!OpenPrinter( lptstrPrinterName, &hPrinter, NULL ))
  956. {
  957. dwRet = GetLastError();
  958. DebugPrintEx(
  959. DEBUG_ERR,
  960. TEXT("OpenPrinter failed. Printer Name = %s , ec = %ld"),
  961. lptstrPrinterName,
  962. dwRet);
  963. goto exit;
  964. }
  965. //
  966. // Get the default devmode
  967. //
  968. lSize = DocumentProperties( NULL, hPrinter, NULL, NULL, NULL, 0 );
  969. if (lSize <= 0)
  970. {
  971. dwRet = GetLastError();
  972. DebugPrintEx(
  973. DEBUG_ERR,
  974. TEXT("DocumentProperties failed. ec = %ld"),
  975. dwRet);
  976. goto exit;
  977. }
  978. //
  979. // allocate memory for the DEVMODE
  980. //
  981. pDevMode = (PDEVMODE) MemAlloc( lSize );
  982. if (!pDevMode)
  983. {
  984. DebugPrintEx(
  985. DEBUG_ERR,
  986. TEXT("Cant allocate DEVMODE."));
  987. dwRet = ERROR_NOT_ENOUGH_MEMORY;
  988. goto exit;
  989. }
  990. //
  991. // get the default document properties
  992. //
  993. if (DocumentProperties( NULL, hPrinter, NULL, pDevMode, NULL, DM_OUT_BUFFER ) != IDOK)
  994. {
  995. dwRet = GetLastError();
  996. DebugPrintEx(
  997. DEBUG_ERR,
  998. TEXT("DocumentProperties failed. ec = %ld"),
  999. dwRet);
  1000. goto exit;
  1001. }
  1002. //
  1003. // Set the correct orientation
  1004. //
  1005. pDevMode->dmOrientation = sCPOrientation;
  1006. //
  1007. // Set the correct reolution
  1008. //
  1009. if (0 != sCPYResolution)
  1010. {
  1011. //
  1012. // Set the coverpage resolution to the same value as the body tiff file
  1013. //
  1014. pDevMode->dmYResolution = sCPYResolution;
  1015. }
  1016. //
  1017. // Create the device context
  1018. //
  1019. hDC = CreateDC( NULL, lptstrPrinterName, NULL, pDevMode);
  1020. if (!hDC)
  1021. {
  1022. dwRet = GetLastError();
  1023. DebugPrintEx(
  1024. DEBUG_ERR,
  1025. TEXT("CreateDC on printer %s failed (ec: %ld)"),
  1026. lptstrPrinterName,
  1027. dwRet);
  1028. goto exit;
  1029. }
  1030. //
  1031. // Set the document information
  1032. //
  1033. DocInfo.cbSize = sizeof(DOCINFO);
  1034. DocInfo.lpszDocName = TEXT("");
  1035. DocInfo.lpszOutput = lptstrTargetFile;
  1036. DocInfo.lpszDatatype = NULL;
  1037. DocInfo.fwType = 0;
  1038. //
  1039. // Start the print job
  1040. //
  1041. JobId = StartDoc( hDC, &DocInfo );
  1042. if (JobId <= 0)
  1043. {
  1044. dwRet = GetLastError();
  1045. DebugPrintEx(
  1046. DEBUG_ERR,
  1047. TEXT("StartDoc failed (ec: %ld)"),
  1048. dwRet);
  1049. goto exit;
  1050. }
  1051. if (StartPage(hDC) <= 0)
  1052. {
  1053. dwRet = GetLastError();
  1054. DebugPrintEx(
  1055. DEBUG_ERR,
  1056. TEXT("StartPage failed (ec: %ld)"),
  1057. dwRet);
  1058. goto exit;
  1059. }
  1060. bEndPage = TRUE;
  1061. //
  1062. // Do the actual rendering work.
  1063. //
  1064. dwRet = PrintCoverPage(
  1065. hDC,
  1066. pCPFields,
  1067. lptstrCoverPage,
  1068. &covDocInfo);
  1069. if (ERROR_SUCCESS != dwRet)
  1070. {
  1071. DebugPrintEx(
  1072. DEBUG_ERR,
  1073. TEXT("PringCoverPage failed (ec: %ld). COV file: %s Target file: %s"),
  1074. dwRet,
  1075. lptstrCoverPage,
  1076. lptstrTargetFile);
  1077. }
  1078. exit:
  1079. if (JobId)
  1080. {
  1081. if (TRUE == bEndPage)
  1082. {
  1083. if (EndPage(hDC) <= 0)
  1084. {
  1085. dwRet = GetLastError();
  1086. DebugPrintEx(
  1087. DEBUG_ERR,
  1088. TEXT("EndPage failed - %d"),
  1089. dwRet);
  1090. }
  1091. }
  1092. if (EndDoc(hDC) <= 0)
  1093. {
  1094. dwRet = GetLastError();
  1095. DebugPrintEx(
  1096. DEBUG_ERR,
  1097. TEXT("EndDoc failed - %d"),
  1098. dwRet);
  1099. }
  1100. }
  1101. if (hDC)
  1102. {
  1103. bRet = DeleteDC( hDC );
  1104. if (!bRet)
  1105. {
  1106. DebugPrintEx(
  1107. DEBUG_ERR,
  1108. TEXT("DeleteDc failed - %d"),
  1109. GetLastError());
  1110. }
  1111. Assert(bRet);
  1112. }
  1113. if (hPrinter)
  1114. {
  1115. if (!ClosePrinter (hPrinter))
  1116. {
  1117. DebugPrintEx(
  1118. DEBUG_ERR,
  1119. TEXT("ClosePrinter failed - %d"),
  1120. GetLastError());
  1121. }
  1122. }
  1123. MemFree (pDevMode);
  1124. return dwRet;
  1125. }