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.

824 lines
20 KiB

  1. /* File: D:\WACKER\tdll\print.c (Created: 14-Jan-1994)
  2. *
  3. * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 9 $
  7. * $Date: 7/08/02 6:44p $
  8. */
  9. #include <windows.h>
  10. #pragma hdrstop
  11. //#define DEBUGSTR
  12. #include <term\res.h>
  13. #include "stdtyp.h"
  14. #include "mc.h"
  15. #include "misc.h"
  16. #include "assert.h"
  17. #include "globals.h"
  18. #include "session.h"
  19. #include "print.h"
  20. #include "print.hh"
  21. #include "errorbox.h"
  22. #include "tdll.h"
  23. #include "term.h"
  24. #include "htchar.h"
  25. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  26. * FUNCTION:
  27. *
  28. * DESCRIPTION:
  29. *
  30. * ARGUMENTS:
  31. *
  32. * RETURNS:
  33. *
  34. */
  35. void printTellError(const HSESSION hSession, const HPRINT hPrint,
  36. const INT iStatus)
  37. {
  38. if (iStatus < 0)
  39. {
  40. if (iStatus & SP_NOTREPORTED)
  41. {
  42. TCHAR achBuf[256];
  43. TCHAR achTitle[256];
  44. achBuf[0] = TEXT('\0');
  45. achTitle[0] = TEXT('\0');
  46. LoadString(glblQueryDllHinst(),
  47. IDS_PRINT_TITLE,
  48. achTitle,
  49. sizeof(achTitle) / sizeof(TCHAR));
  50. switch (iStatus)
  51. {
  52. case SP_OUTOFDISK:
  53. LoadString(glblQueryDllHinst(),
  54. IDS_PRINT_NOMEM,
  55. achBuf,
  56. sizeof(achBuf) / sizeof(TCHAR));
  57. break;
  58. case SP_OUTOFMEMORY:
  59. LoadString(glblQueryDllHinst(),
  60. IDS_PRINT_CANCEL,
  61. achBuf,
  62. sizeof(achBuf) / sizeof(TCHAR));
  63. break;
  64. case SP_USERABORT:
  65. break;
  66. default:
  67. {
  68. const HHPRINT hhPrint = (HHPRINT)hPrint;
  69. if (hhPrint == 0 || !hhPrint->fUserAbort)
  70. {
  71. LoadString(glblQueryDllHinst(),
  72. IDS_PRINT_ERROR,
  73. achBuf,
  74. sizeof(achBuf) / sizeof(TCHAR));
  75. }
  76. }
  77. break;
  78. }
  79. if (achBuf[0] != TEXT('\0'))
  80. {
  81. TimedMessageBox(sessQueryHwnd(hSession),
  82. achBuf,
  83. achTitle,
  84. MB_ICONEXCLAMATION | MB_OK,
  85. 0);
  86. }
  87. }
  88. }
  89. return;
  90. }
  91. //*jcm
  92. #if 0
  93. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  94. * FUNCTION:
  95. * PrintKillJob
  96. *
  97. * DESCRIPTION:
  98. * Kills a print job. Called when session is closing and stuff is
  99. * printing.
  100. *
  101. * ARGUMENTS:
  102. * HSESSION hSession - external session handle.
  103. *
  104. * RETURNS:
  105. * VOID
  106. *
  107. */
  108. VOID PrintKillJob(HSESSION hSession)
  109. {
  110. HHPRINT hPr;
  111. INT iStatus = 0;
  112. HGLOBAL hMem;
  113. assert(hSession);
  114. // It is possible that the print job ended by the time we got
  115. // here so if the handle is 0, return quietly.
  116. hPr = (HHPRINT)mGetPrintHdl(hSession);
  117. if (hPr == (HHPRINT)0)
  118. return;
  119. /* -------------- Kill this print job ------------- */
  120. TimerDestroy(&hPr->hTimer);
  121. DbgOutStr("\r\nTimer Destroy in PrintKillJob\r\n", 0, 0, 0, 0, 0);
  122. if (hPr->hDC)
  123. {
  124. // Check if we issued an EndPage() for this page yet.
  125. if (hPr->nLines > 0)
  126. {
  127. if (HA5G.fIsWin30)
  128. iStatus = Escape(hPr->hDC, NEWFRAME, 0, NULL, NULL);
  129. else
  130. iStatus = EndPage(hPr->hDC);
  131. DbgOutStr("EndPage = %d\r\n", iStatus, 0, 0, 0, 0);
  132. PrintTellError(hSession, (HPRINT)hPr, iStatus);
  133. }
  134. if (iStatus >= 0)
  135. {
  136. if (HA5G.fIsWin30)
  137. iStatus = Escape(hPr->hDC, ENDDOC, 0, (LPTSTR)0, NULL);
  138. else
  139. iStatus = EndDoc(hPr->hDC);
  140. DbgOutStr("EndDoc = %d\r\n", iStatus, 0, 0, 0, 0);
  141. PrintTellError(hSession, (HPRINT)hPr, iStatus);
  142. }
  143. if (IsWindow(hPr->hwndPrintAbortDlg))
  144. DestroyWindow(hPr->hwndPrintAbortDlg);
  145. FreeProcInstance((FARPROC)hPr->lpfnPrintAbortDlg);
  146. FreeProcInstance((FARPROC)hPr->lpfnPrintAbortProc);
  147. DeleteDC(hPr->hDC);
  148. }
  149. else
  150. {
  151. nb_close(hPr->hPrn);
  152. }
  153. FreeProcInstance(hPr->lpfnTimerCallback);
  154. hMem = (HANDLE)GlobalHandle(HIWORD(hPr->pach));
  155. GlobalUnlock(hMem);
  156. GlobalFree(hMem);
  157. free(hPr);
  158. hPr = NULL;
  159. mSetPrintHdl(hSession, (HPRINT)0);
  160. return;
  161. }
  162. #endif
  163. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  164. * FUNCTION:
  165. * printAbortProc
  166. *
  167. * DESCRIPTION:
  168. * Enables print-manager to unspool stuff when system is low on disk
  169. * space. Is also called whenever EndPage() is called.
  170. *
  171. * ARGUMENTS:
  172. * HDC hdcPrn - DC of printer
  173. * INT - nCode
  174. *
  175. * RETURNS:
  176. * Stuff
  177. *
  178. */
  179. BOOL CALLBACK printAbortProc(HDC hDC, INT nCode)
  180. {
  181. MSG msg;
  182. //cost HHPRINT hhPrint = printCtrlLookupDC(hDC);
  183. //*HCLOOP hCLoop = sessQueryCLoopHdl(hhPrint->hSession);
  184. DbgOutStr("\r\nprintAbortProc : %d\r\n", nCode, 0, 0, 0, 0);
  185. //*if (hCLoop == 0)
  186. //* {
  187. //* assert(FALSE);
  188. //* return FALSE;
  189. //* }
  190. // Need to quit processing characters to the emulator at this
  191. // point or a recursion condition occurs which results in a
  192. // run-away condtion.
  193. //*CLoopRcvControl(hCLoop, CLOOP_SUSPEND, CLOOP_RB_PRINTING);
  194. //*CLoopSndControl(hCLoop, CLOOP_SUSPEND, CLOOP_SB_PRINTING);
  195. while (PeekMessage((LPMSG)&msg, (HWND)0, 0, 0, PM_REMOVE))
  196. {
  197. TranslateMessage(&msg);
  198. DispatchMessage(&msg);
  199. }
  200. //*CLoopRcvControl(hCLoop, CLOOP_RESUME, CLOOP_RB_PRINTING);
  201. //*CLoopSndControl(hCLoop, CLOOP_RESUME, CLOOP_SB_PRINTING);
  202. DbgOutStr("Exiting printAbortProc", 0, 0, 0, 0, 0);
  203. return TRUE;
  204. }
  205. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  206. * FUNCTION:
  207. * printString
  208. *
  209. * DESCRIPTION:
  210. * Workhorse print-echo function. Takes care of counting lines and
  211. * paginating. Also calls printOpenDC() if necessary to get a printer
  212. * DC.
  213. *
  214. * ARGUMENTS:
  215. * HHPRINT hhPrint - The Internal printer handle
  216. * LPCTSTR pachStr - A pointer to the string to print.
  217. * int iLen - The length of the string to print.
  218. *
  219. * RETURNS:
  220. * TRUE = OK, FALSE = error
  221. *
  222. */
  223. int printString(const HHPRINT hhPrint, LPCTSTR pachStr, int iLen)
  224. {
  225. int nCharCount;
  226. int nIdx;
  227. int iPrintableWidth;
  228. SIZE stStringSize;
  229. LPCTSTR pszTemp;
  230. TCHAR achBuf[512];
  231. RECT stRect;
  232. //
  233. // get a device context if we do not already have one
  234. //
  235. if (hhPrint->hDC == 0)
  236. {
  237. if (printOpenDC(hhPrint) == FALSE)
  238. {
  239. printEchoClose((HPRINT)hhPrint);
  240. return FALSE;
  241. }
  242. }
  243. for (nCharCount = nIdx = 0, pszTemp = pachStr ;
  244. nIdx < iLen ;
  245. ++nCharCount, ++nIdx, pszTemp = StrCharNext(pszTemp))
  246. {
  247. if (IsDBCSLeadByte((BYTE)*pszTemp))
  248. nCharCount++;
  249. switch (*pszTemp)
  250. {
  251. case TEXT('\r'):
  252. if ( nCharCount )
  253. MemCopy(achBuf, pachStr, nCharCount);
  254. achBuf[nCharCount] = TEXT('\0');
  255. GetTextExtentPoint(hhPrint->hDC, achBuf,
  256. StrCharGetByteCount(achBuf), &stStringSize);
  257. if ( nCharCount > 1 )
  258. {
  259. //
  260. // calculate a print rect for the current margins
  261. //
  262. iPrintableWidth = GetDeviceCaps( hhPrint->hDC, HORZRES );
  263. iPrintableWidth -= hhPrint->marginsDC.right;
  264. stRect.left = hhPrint->cx;
  265. stRect.right = iPrintableWidth;
  266. stRect.top = hhPrint->cy;
  267. stRect.bottom = hhPrint->cy + stStringSize.cy;
  268. ExtTextOut( hhPrint->hDC, hhPrint->cx, hhPrint->cy,
  269. ETO_CLIPPED, &stRect, achBuf,
  270. StrCharGetByteCount(achBuf), NULL );
  271. }
  272. TCHAR_Fill(achBuf, TEXT('\0'), sizeof(achBuf)/sizeof(TCHAR));
  273. hhPrint->cx = hhPrint->marginsDC.left;
  274. pachStr = StrCharNext(pszTemp);
  275. nCharCount = 0;
  276. break;
  277. case TEXT('\f'):
  278. hhPrint->nLinesPrinted = hhPrint->nLinesPerPage;
  279. /* --- Fall thru to case '\n' --- */
  280. case TEXT('\n'):
  281. if (nCharCount)
  282. MemCopy(achBuf, pachStr,nCharCount);
  283. achBuf[nCharCount] = TEXT('\0');
  284. GetTextExtentPoint(hhPrint->hDC,
  285. achBuf,
  286. StrCharGetByteCount(achBuf),
  287. &stStringSize);
  288. if ( nCharCount > 1 )
  289. {
  290. iPrintableWidth = GetDeviceCaps( hhPrint->hDC, HORZRES );
  291. iPrintableWidth -= hhPrint->marginsDC.right;
  292. stRect.left = hhPrint->cx;
  293. stRect.right = iPrintableWidth;
  294. stRect.top = hhPrint->cy;
  295. stRect.bottom = hhPrint->cy + stStringSize.cy;
  296. ExtTextOut( hhPrint->hDC, hhPrint->cx, hhPrint->cy,
  297. ETO_CLIPPED, &stRect, achBuf,
  298. StrCharGetByteCount(achBuf), NULL );
  299. }
  300. hhPrint->cy += stStringSize.cy;
  301. pachStr = StrCharNext(pszTemp);
  302. nCharCount = 0;
  303. //
  304. // check if we need a new page
  305. //
  306. hhPrint->nLinesPrinted += 1;
  307. if (hhPrint->nLinesPrinted > hhPrint->nLinesPerPage)
  308. {
  309. if (hhPrint->nFlags & PRNECHO_BY_PAGE)
  310. {
  311. printEchoClose((HPRINT)hhPrint);
  312. hhPrint->nFlags |= PRNECHO_IS_ON;
  313. return TRUE;
  314. }
  315. hhPrint->nStatus = EndPage(hhPrint->hDC);
  316. if (hhPrint->nStatus < 0)
  317. {
  318. printEchoClose((HPRINT)hhPrint);
  319. return FALSE;
  320. }
  321. hhPrint->nStatus = StartPage(hhPrint->hDC);
  322. printSetFont( hhPrint );
  323. if (hhPrint->nStatus <= 0)
  324. {
  325. printEchoClose((HPRINT)hhPrint);
  326. return FALSE;
  327. }
  328. hhPrint->nLinesPrinted = 0;
  329. hhPrint->cx = hhPrint->marginsDC.left;
  330. hhPrint->cy = hhPrint->marginsDC.top;
  331. }
  332. break;
  333. default:
  334. break;
  335. }
  336. }
  337. /* -------------- Left over portion of a line? ------------- */
  338. if ((nCharCount > 0) && (*pachStr != TEXT('\0')))
  339. {
  340. DbgOutStr("o", 0, 0, 0, 0, 0);
  341. MemCopy(achBuf, pachStr,nCharCount);
  342. achBuf[nCharCount] = TEXT('\0');
  343. GetTextExtentPoint(hhPrint->hDC,
  344. achBuf,
  345. StrCharGetByteCount(achBuf),
  346. &stStringSize);
  347. iPrintableWidth = GetDeviceCaps( hhPrint->hDC, HORZRES );
  348. iPrintableWidth -= hhPrint->marginsDC.right;
  349. stRect.left = hhPrint->cx;
  350. stRect.right = iPrintableWidth;
  351. stRect.top = hhPrint->cy;
  352. stRect.bottom = hhPrint->cy + stStringSize.cy;
  353. ExtTextOut( hhPrint->hDC, hhPrint->cx, hhPrint->cy,
  354. ETO_CLIPPED, &stRect, achBuf,
  355. StrCharGetByteCount(achBuf), NULL );
  356. // TextOut(hhPrint->hDC,
  357. // hhPrint->cx,
  358. // hhPrint->cy,
  359. // achBuf, StrCharGetByteCount(achBuf));
  360. TCHAR_Fill(achBuf, TEXT('\0'), sizeof(achBuf)/sizeof(TCHAR));
  361. hhPrint->cx += stStringSize.cx;
  362. }
  363. return TRUE;
  364. }
  365. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  366. * FUNCTION:
  367. * printQueryStatus
  368. *
  369. * DESCRIPTION: This function is used to determine if printing has been
  370. * turned on for the supplied print handle.
  371. *
  372. * ARGUMENTS: hPrint - The external printer handle.
  373. *
  374. * RETURNS: TRUE - If printing is on.
  375. * FALSE - If printing is off.
  376. *
  377. */
  378. int printQueryStatus(const HPRINT hPrint)
  379. {
  380. const HHPRINT hhPrint = (HHPRINT)hPrint;
  381. if (hPrint == 0)
  382. assert(FALSE);
  383. return (bittest(hhPrint->nFlags, PRNECHO_IS_ON));
  384. }
  385. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  386. * FUNCTION:
  387. * printStatusToggle
  388. *
  389. * DESCRIPTION:
  390. * Toggles the status (on/off) of the supplied print handle.
  391. *
  392. * ARGUMENTS: hPrint - The external printer handle.
  393. *
  394. * RETURNS: nothing
  395. *
  396. */
  397. void printStatusToggle(const HPRINT hPrint)
  398. {
  399. const HHPRINT hhPrint = (HHPRINT)hPrint;
  400. if (hPrint == 0)
  401. assert(FALSE);
  402. if (bittest(hhPrint->nFlags, PRNECHO_IS_ON))
  403. {
  404. bitclear(hhPrint->nFlags, PRNECHO_IS_ON);
  405. }
  406. else
  407. {
  408. bitset(hhPrint->nFlags, PRNECHO_IS_ON);
  409. }
  410. return;
  411. }
  412. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  413. * FUNCTION:
  414. * printSetStatus
  415. *
  416. * DESCRIPTION:
  417. * Turns priniting on or off for the supplied handle.
  418. *
  419. * ARGUMENTS: hPrint - The external printer handle.
  420. * fSetting - True or False to turn printing on/off.
  421. *
  422. * RETURNS: nothing
  423. *
  424. *
  425. */
  426. void printSetStatus(const HPRINT hPrint, const int fSetting)
  427. {
  428. const HHPRINT hhPrint = (HHPRINT)hPrint;
  429. if (hPrint == 0)
  430. assert(FALSE);
  431. if (fSetting)
  432. bitset(hhPrint->nFlags, PRNECHO_IS_ON);
  433. else
  434. bitclear(hhPrint->nFlags, PRNECHO_IS_ON);
  435. return;
  436. }
  437. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  438. * FUNCTION:
  439. * printQueryPrinterInfo
  440. *
  441. * DESCRIPTION:
  442. * This function copies five pieces of information (pszPrinter, pDevNames,
  443. * pDevMode, lf, and margins ) from the Session HHPRINT handle, to the supplied
  444. * HHPRINT handle. The objective is to copy the contents of the Session's
  445. * HPRINT handle to another HPRINT handle (from the emulators). Remember that
  446. * the Session's HPRINT handle is the one that contains the stored printer name and
  447. * setup information.
  448. *
  449. * ARGUMENTS:
  450. *
  451. * RETURNS:
  452. *
  453. */
  454. void printQueryPrinterInfo( const HHPRINT hhSessPrint, HHPRINT hhPrint )
  455. {
  456. TCHAR *pTemp;
  457. DWORD dwSize;
  458. if (hhPrint == NULL || hhSessPrint == NULL)
  459. {
  460. return;
  461. }
  462. // Copy the printer name.
  463. //
  464. StrCharCopyN(hhPrint->achPrinterName, hhSessPrint->achPrinterName, PRINTER_NAME_LEN);
  465. // Copy the DEVNAMES structure.
  466. //
  467. if (hhSessPrint->pstDevNames)
  468. {
  469. if (hhPrint->pstDevNames)
  470. {
  471. free(hhPrint->pstDevNames);
  472. hhPrint->pstDevNames = NULL;
  473. }
  474. pTemp = (TCHAR *)hhSessPrint->pstDevNames;
  475. pTemp += hhSessPrint->pstDevNames->wOutputOffset;
  476. pTemp += StrCharGetByteCount(pTemp) + 1;
  477. dwSize = (DWORD)(pTemp - (TCHAR*)hhSessPrint->pstDevNames);
  478. hhPrint->pstDevNames = malloc(dwSize);
  479. if (hhPrint->pstDevNames == 0)
  480. {
  481. assert(FALSE);
  482. return;
  483. }
  484. if (dwSize)
  485. MemCopy(hhPrint->pstDevNames, hhSessPrint->pstDevNames, dwSize);
  486. }
  487. // Copy the DEVMODE structure.
  488. //
  489. if (hhSessPrint->pstDevMode)
  490. {
  491. if (hhPrint->pstDevMode)
  492. {
  493. free(hhPrint->pstDevMode);
  494. hhPrint->pstDevMode = NULL;
  495. }
  496. dwSize = hhSessPrint->pstDevMode->dmSize +
  497. hhSessPrint->pstDevMode->dmDriverExtra;
  498. hhPrint->pstDevMode = malloc(dwSize);
  499. if (hhPrint->pstDevMode == 0)
  500. {
  501. assert(FALSE);
  502. return;
  503. }
  504. if (dwSize)
  505. MemCopy(hhPrint->pstDevMode, hhSessPrint->pstDevMode, dwSize);
  506. }
  507. // Copy the font and margin information
  508. //
  509. MemCopy( &hhPrint->margins, &hhSessPrint->margins, sizeof(RECT) );
  510. MemCopy( &hhPrint->lf, &hhSessPrint->lf, sizeof(LOGFONT) );
  511. hhPrint->iFontPointSize = hhSessPrint->iFontPointSize;
  512. return;
  513. }
  514. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  515. * FUNCTION:
  516. * printVerifyPrinter
  517. *
  518. * DESCRIPTION:
  519. * This routine is used to determine if a printer (any printer) is
  520. * installed.
  521. *
  522. * ARGUMENTS:
  523. * hPrint - An external print handle.
  524. *
  525. * RETURNS:
  526. * 0 if successful, otherwise -1.
  527. *
  528. */
  529. int printVerifyPrinter(const HPRINT hPrint)
  530. {
  531. const HHPRINT hhPrint = (HHPRINT)hPrint;
  532. TCHAR achTitle[256];
  533. TCHAR achBuf[256];
  534. TCHAR *pszString;
  535. HANDLE hPrinter = NULL;
  536. BOOL fRet;
  537. if (hhPrint == NULL)
  538. {
  539. return(-1);
  540. }
  541. // Check to see if the printer that has been saved with the
  542. // session information is still available. If it is, simply
  543. // return a zero, indicating everything is OK.
  544. //
  545. fRet = OpenPrinter((LPTSTR)hhPrint->achPrinterName, &hPrinter, NULL);
  546. if (fRet)
  547. {
  548. ClosePrinter(hPrinter);
  549. return(0);
  550. }
  551. // If we're here, it's time to locate the default printer, whatever
  552. // it is. If the default printer is selected here, the print handle's
  553. // name is initialized to that value.
  554. //
  555. if (GetProfileString("Windows", "Device", ",,,", achBuf,
  556. sizeof(achBuf)) && (pszString = strtok(achBuf, ",")))
  557. {
  558. StrCharCopyN(hhPrint->achPrinterName, pszString, PRINTER_NAME_LEN);
  559. return (0);
  560. }
  561. // A printer is NOT available. Display the text for telling the
  562. // user how to install one. It should be the same as the text that
  563. // appears in the printDlg call when this happens.
  564. //
  565. LoadString(glblQueryDllHinst(),
  566. IDS_PRINT_NO_PRINTER,
  567. achBuf,
  568. sizeof(achBuf) / sizeof(TCHAR));
  569. mscMessageBeep(MB_ICONEXCLAMATION);
  570. achTitle[0] = TEXT('\0');
  571. LoadString(glblQueryDllHinst(),
  572. IDS_PRINT_TITLE,
  573. achTitle,
  574. sizeof(achTitle) / sizeof(TCHAR));
  575. TimedMessageBox(sessQueryHwnd(hhPrint->hSession), achBuf,
  576. achTitle, MB_ICONEXCLAMATION | MB_OK, 0);
  577. return -1;
  578. }
  579. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  580. * FUNCTION:
  581. * printSetFont
  582. *
  583. * DESCRIPTION:
  584. * Sets the terminal font to the given font. If hFont is zero,
  585. * termSetFont() trys to create a default font.
  586. *
  587. * ARGUMENTS:
  588. * hhTerm - internal term handle.
  589. * plf - pointer to logfont
  590. *
  591. * RETURNS:
  592. * BOOL
  593. *
  594. */
  595. BOOL printSetFont(const HHPRINT hhPrint)
  596. {
  597. LOGFONT lf;
  598. lf = hhPrint->lf;
  599. lf.lfHeight = hhPrint->iFontPointSize;
  600. printCreatePointFont( &lf, hhPrint );
  601. SelectObject( hhPrint->hDC, hhPrint->hFont );
  602. return TRUE;
  603. }
  604. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  605. * FUNCTION:
  606. * printCreatePointFont
  607. *
  608. * DESCRIPTION:
  609. * Creates a hFont based on the log font structure given. This function assumes
  610. * the height member of the log font structure to be in 1/10 of a point
  611. * increments. A 12 point font would be represented as 120. The hFont is stored
  612. * in the print handle provided.
  613. *
  614. * ARGUMENTS:
  615. * pLogFont - A pointer to a log font structure.
  616. * hhPrint - A print handle to store the HFONT into.
  617. *
  618. * RETURNS:
  619. * void
  620. *
  621. */
  622. void printCreatePointFont( LOGFONT * pLogFont, HHPRINT hhPrint )
  623. {
  624. POINT pt;
  625. POINT ptOrg = { 0, 0 };
  626. if (hhPrint->hFont)
  627. {
  628. DeleteObject(hhPrint->hFont);
  629. }
  630. pt.y = GetDeviceCaps(hhPrint->hDC, LOGPIXELSY) * pLogFont->lfHeight;
  631. pt.y /= 720;
  632. DPtoLP(hhPrint->hDC, &pt, 1);
  633. DPtoLP(hhPrint->hDC, &ptOrg, 1);
  634. pLogFont->lfHeight = -abs(pt.y - ptOrg.y);
  635. hhPrint->hFont = CreateFontIndirect( pLogFont );
  636. return;
  637. }
  638. /*******************************************************************************
  639. * FUNCTION:
  640. * printSetMargins
  641. *
  642. * DESCRIPTION:
  643. * Sets the margins for the print handle, by converting from the values
  644. * returned by the page setup dialog.
  645. *
  646. * ARGUMENTS:
  647. * aMargins - A RECT structure that contains the margins in inches.
  648. *
  649. * Return:
  650. * void
  651. *
  652. * Author: dmn:02/19/97
  653. *
  654. */
  655. void printSetMargins( HHPRINT hhPrint )
  656. {
  657. int iPixelsPerInchX;
  658. int iPixelsPerInchY;
  659. int iPhysicalOffsetX;
  660. int iPhysicalOffsetY;
  661. if ( hhPrint->hDC )
  662. {
  663. hhPrint->marginsDC = hhPrint->margins;
  664. //
  665. // convert the margins to pixels
  666. //
  667. iPixelsPerInchX = GetDeviceCaps( hhPrint->hDC, LOGPIXELSX );
  668. iPixelsPerInchY = GetDeviceCaps( hhPrint->hDC, LOGPIXELSY );
  669. hhPrint->marginsDC.left = ( hhPrint->marginsDC.left * iPixelsPerInchX ) / 1000;
  670. hhPrint->marginsDC.right = ( hhPrint->margins.right * iPixelsPerInchX ) / 1000;
  671. hhPrint->marginsDC.top = ( hhPrint->marginsDC.top * iPixelsPerInchY ) / 1000;
  672. hhPrint->marginsDC.bottom = ( hhPrint->marginsDC.bottom * iPixelsPerInchY ) / 1000;
  673. iPhysicalOffsetX = GetDeviceCaps( hhPrint->hDC ,PHYSICALOFFSETX );
  674. iPhysicalOffsetY = GetDeviceCaps( hhPrint->hDC, PHYSICALOFFSETY );
  675. hhPrint->marginsDC.left = max( 0, hhPrint->marginsDC.left - iPhysicalOffsetX );
  676. hhPrint->marginsDC.right = max( 0, hhPrint->marginsDC.right - iPhysicalOffsetX );
  677. hhPrint->marginsDC.top = max( 0, hhPrint->marginsDC.top - iPhysicalOffsetY );
  678. hhPrint->marginsDC.bottom = max( 0, hhPrint->marginsDC.bottom - iPhysicalOffsetY );
  679. }
  680. return;
  681. }