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.

859 lines
27 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. /* This routine sets up the screen position used by Word relative to the
  5. current device. */
  6. #define NOGDICAPMASKS
  7. #define NOVIRTUALKEYCODES
  8. #define NOWINSTYLES
  9. #define NOCLIPBOARD
  10. #define NOCTLMGR
  11. #define NOMENUS
  12. #define NOICON
  13. #define NOKEYSTATE
  14. #define NOSYSCOMMANDS
  15. #define NOSHOWWINDOW
  16. #define NOATOM
  17. #define NODRAWTEXT
  18. #define NOMSG
  19. #define NOOPENFILE
  20. #define NOSCROLL
  21. #define NOSOUND
  22. /*#define NOTEXTMETRIC*/
  23. #define NOWH
  24. #define NOWINOFFSETS
  25. #define NOCOMM
  26. #include <windows.h>
  27. #include "mw.h"
  28. #include "ch.h"
  29. #include "cmddefs.h"
  30. #include "scrndefs.h"
  31. #include "dispdefs.h"
  32. #include "wwdefs.h"
  33. #include "printdef.h"
  34. #include "str.h"
  35. #include "docdefs.h"
  36. #include "propdefs.h"
  37. #include "machdefs.h"
  38. #include "fontdefs.h"
  39. #include "commdlg.h"
  40. #ifdef DBCS
  41. #include "kanji.h"
  42. #endif
  43. unsigned dxaPrOffset;
  44. unsigned dyaPrOffset;
  45. extern HCURSOR vhcIBeam;
  46. BOOL FSetWindowColors()
  47. {
  48. /* This routine sets up the global variables rgbBkgrnd, rgbText, hbrBkgrnd,
  49. and ropErase, depending on what the current system colors are. hWnd is a
  50. handle to a window on top. */
  51. extern long ropErase;
  52. extern long rgbBkgrnd;
  53. extern long rgbText;
  54. extern HBRUSH hbrBkgrnd;
  55. long rgbWindow;
  56. long rgbWindowText;
  57. HDC hDC;
  58. /* Get the color of the background and the text. */
  59. rgbWindow = GetSysColor(COLOR_WINDOW);
  60. rgbWindowText = GetSysColor(COLOR_WINDOWTEXT);
  61. /* If the colors haven't changed, then there is nothing to do. */
  62. if (rgbWindow == rgbBkgrnd && rgbWindowText == rgbText)
  63. {
  64. return (FALSE);
  65. }
  66. /* Convert the window colors into "pure" colors. */
  67. if ((hDC = GetDC(NULL)) == NULL)
  68. {
  69. return (FALSE);
  70. }
  71. rgbBkgrnd = GetNearestColor(hDC, rgbWindow);
  72. rgbText = GetNearestColor(hDC, rgbWindowText);
  73. ReleaseDC(NULL, hDC);
  74. Assert((rgbBkgrnd & 0xFF000000) == 0 && (rgbText & 0xFF000000) == 0);
  75. /* Set up the brush for the background. */
  76. if ((hbrBkgrnd = CreateSolidBrush(rgbBkgrnd)) == NULL)
  77. {
  78. /* Can't make the background brush; use the white brush. */
  79. hbrBkgrnd = GetStockObject(WHITE_BRUSH);
  80. rgbBkgrnd = RGB(0xff, 0xff, 0xff);
  81. }
  82. /* Compute the raster op to erase the screen. */
  83. if (rgbBkgrnd == RGB(0xff, 0xff, 0xff))
  84. {
  85. /* WHITENESS is faster than copying a white brush. */
  86. ropErase = WHITENESS;
  87. }
  88. else if (rgbBkgrnd == RGB(0, 0, 0))
  89. {
  90. /* BLACKNESS is faster than copying a black brush. */
  91. ropErase = BLACKNESS;
  92. }
  93. else
  94. {
  95. /* For everything else, we have to copy the brush. */
  96. ropErase = PATCOPY;
  97. }
  98. return (TRUE);
  99. }
  100. int FSetScreenConstants()
  101. {
  102. /* This routine sets the value of a variety of global variables that used to
  103. be constants in Mac Word, but are now varibles because screen resolution can
  104. only be determined at run time. */
  105. extern HWND hParentWw;
  106. extern HDC vhDCPrinter;
  107. extern HBITMAP hbmNull;
  108. extern int dxpLogInch;
  109. extern int dypLogInch;
  110. extern int dxpLogCm;
  111. extern int dypLogCm;
  112. extern int dypMax;
  113. extern int xpRightMax;
  114. extern int xpSelBar;
  115. extern int xpMinScroll;
  116. extern int xpRightLim;
  117. extern int dxpInfoSize;
  118. extern int ypMaxWwInit;
  119. extern int ypMaxAll;
  120. extern int dypMax;
  121. extern int dypAveInit;
  122. extern int dypWwInit;
  123. extern int dypBand;
  124. extern int ypSubSuper;
  125. #ifdef KINTL
  126. extern int dxaAdjustPerCm;
  127. #endif /* ifdef KINTL */
  128. HDC hDC;
  129. #ifdef KINTL
  130. int xaIn16CmFromA, xaIn16CmFromP;
  131. #endif /* ifdef KINTL */
  132. /* First, let's create and save an empty bitmap. */
  133. if ((hbmNull = CreateBitmap(1, 1, 1, 1, (LPSTR)NULL)) == NULL)
  134. {
  135. return (FALSE);
  136. }
  137. /* Get the DC of the parent window to play with. */
  138. if ((hDC = GetDC(hParentWw)) == NULL)
  139. {
  140. return (FALSE);
  141. }
  142. /* Save away the height of the screen. */
  143. dypMax = GetDeviceCaps(hDC, VERTRES);
  144. /* determine screen pixel dimensions */
  145. dxpLogInch = GetDeviceCaps(hDC, LOGPIXELSX);
  146. dypLogInch = GetDeviceCaps(hDC, LOGPIXELSY);
  147. /* convert above to centimeters */
  148. dxpLogCm = MultDiv(dxpLogInch, czaCm, czaInch);
  149. dypLogCm = MultDiv(dypLogInch, czaCm, czaInch);
  150. #ifdef KINTL
  151. /* Now, calculate the kick back amount of xa per cm. */
  152. xaIn16CmFromA = 16 * czaCm;
  153. xaIn16CmFromP = MultDiv(16 * dxpLogCm, czaInch, dxpLogInch);
  154. dxaAdjustPerCm = (xaIn16CmFromP - xaIn16CmFromA) / 16;
  155. #endif /* ifdef KINTL */
  156. #ifdef SYSENDMARK
  157. {
  158. extern HFONT vhfSystem;
  159. extern struct FMI vfmiSysScreen;
  160. extern int vrgdxpSysScreen[];
  161. TEXTMETRIC tm;
  162. /* The use of height below is OK, because we are
  163. just trying to get the reference height. */
  164. GetTextMetrics(hDC, (LPTEXTMETRIC) &tm);
  165. /* Set up the fields in vfmiSysScreen for the later use. */
  166. vfmiSysScreen.dxpOverhang = tm.tmOverhang;
  167. #if defined(KOREA)
  168. if ((tm.tmPitchAndFamily & 1) == 0)
  169. vfmiSysScreen.dxpSpace = tm.tmAveCharWidth;
  170. else
  171. #endif
  172. vfmiSysScreen.dxpSpace = LOWORD(GetTextExtent(hDC,
  173. (LPSTR)" ", 1)) - tm.tmOverhang;
  174. vfmiSysScreen.dypAscent = tm.tmAscent;
  175. vfmiSysScreen.dypDescent = tm.tmDescent;
  176. vfmiSysScreen.dypBaseline = tm.tmAscent;
  177. vfmiSysScreen.dypLeading = tm.tmExternalLeading;
  178. #ifdef DBCS /* KenjiK '90-10-29 */
  179. /* We must setup appended members of structure. */
  180. vfmiSysScreen.dxpDBCS = dxpNil;
  181. #endif /* DBCS */
  182. bltc(vrgdxpSysScreen, dxpNil, chFmiMax - chFmiMin);
  183. vfmiSysScreen.mpchdxp = vrgdxpSysScreen - chFmiMin;
  184. /* This is as good a place to get a handle to the system font as
  185. any other for LoadFont().....? */
  186. /* Throw away the old one first, if applicable. */
  187. if (vhfSystem != NULL) {
  188. DeleteObject((HANDLE) vhfSystem);
  189. }
  190. vhfSystem = GetStockObject(SYSTEM_FONT);
  191. Assert(vhfSystem != NULL);
  192. }
  193. #endif /* SYSENDMARK */
  194. /* We don't need the DC any more. */
  195. ReleaseDC(hParentWw, hDC);
  196. /* Calculate the positions. */
  197. xpSelBar = MultDiv(xaSelBar, dxpLogInch, czaInch);
  198. xpRightMax = MultDiv(xaRightMax, dxpLogInch, czaInch);
  199. xpRightLim = xpRightMax - (GetSystemMetrics(SM_CXFULLSCREEN) - xpSelBar -
  200. GetSystemMetrics(SM_CXVSCROLL) + GetSystemMetrics(SM_CXBORDER));
  201. xpMinScroll = ((MultDiv(xaMinScroll, dxpLogInch, czaInch)+7)/8)*8;
  202. dxpInfoSize = MultDiv(dxaInfoSize, dxpLogInch, czaInch);
  203. ypMaxWwInit = MultDiv(yaMaxWwInit, dypLogInch, czaInch);
  204. ypMaxAll = MultDiv(yaMaxAll, dypLogInch, czaInch);
  205. dypWwInit = MultDiv(dyaWwInit, dypLogInch, czaInch);
  206. dypBand = MultDiv(dyaBand, dypLogInch, czaInch);
  207. ypSubSuper = MultDiv(yaSubSuper, dypLogInch, czaInch);
  208. /* dypAveInit is a very rough guess as to the height + leading of a 12 point
  209. font. */
  210. dypAveInit = MultDiv(cya12pt, dypLogInch, czaInch);
  211. /* Time to search the user profile to find a printer. */
  212. if (!FGetPrinterFromProfile())
  213. {
  214. return (FALSE);
  215. }
  216. GetPrinterDC(FALSE);
  217. return (TRUE);
  218. }
  219. BOOL FGetPrinterFromProfile()
  220. {
  221. /* This routine searches the user profile for the name of a printer to use
  222. and records the name in the printer heap strings. FALSE is returned iff a
  223. memory error is encountered. */
  224. extern HWND hParentWw;
  225. extern CHAR szWindows[];
  226. extern CHAR szDevice[];
  227. extern CHAR szDevices[];
  228. extern BOOL vfPrDefault;
  229. extern CHAR (**hszPrinter)[];
  230. extern CHAR (**hszPrDriver)[];
  231. extern CHAR (**hszPrPort)[];
  232. CHAR *index(CHAR *, int);
  233. CHAR *bltbyte(CHAR *, CHAR *, int);
  234. CHAR szPrinter[cchMaxProfileSz];
  235. CHAR szDevSpec[cchMaxProfileSz];
  236. CHAR chNull = '\0';
  237. CHAR *pch;
  238. CHAR *pchDriver;
  239. CHAR *pchPort;
  240. int cwsz;
  241. if (!vfPrDefault && hszPrinter != NULL && hszPrPort != NULL)
  242. {
  243. /* If the user has selected a printer, then look for that printer in the
  244. user profile. */
  245. int cPort;
  246. int iPort;
  247. bltsz(&(**hszPrinter)[0], szPrinter);
  248. GetProfileString((LPSTR)szDevices, (LPSTR)szPrinter, (LPSTR)&chNull,
  249. (LPSTR)szDevSpec, cchMaxProfileSz);
  250. cPort = ParseDeviceSz(szDevSpec, &pchPort, &pchDriver);
  251. /* See if we can find the old port in the list. */
  252. for (iPort = 0, pch = pchPort; iPort < cPort; iPort++)
  253. {
  254. if (WCompSz(&(**hszPrPort)[0], pch) == 0)
  255. {
  256. pchPort = pch;
  257. goto GotPrinter;
  258. }
  259. pch += CchSz(pch);
  260. }
  261. /* If the port for the current printer has changed, then it must have
  262. been done by the control panel and we haven't the foggiest idea what
  263. it is, so grab the first port. */
  264. goto UnknownPort;
  265. }
  266. /* Is there a default Windows printer? */
  267. GetProfileString((LPSTR)szWindows, (LPSTR)szDevice, (LPSTR)&chNull,
  268. (LPSTR)szPrinter, cchMaxProfileSz);
  269. #ifdef WIN30
  270. /* Don't make the assumption like Write 2 did and just grab ANY printer.
  271. I know, I know -- there's unnecessary code left down below but didn't
  272. want to mess any special case code up ..pault */
  273. if ((pch = index(szPrinter, ',')) == 0)
  274. goto BailOut;
  275. #endif
  276. /* Does this entry contain the port and driver information. */
  277. if ((pch = index(szPrinter, ',')) != 0)
  278. {
  279. /* Remove any trailing spaces from the printer name. */
  280. CHAR *pchT;
  281. for (pchT = pch; *pchT == ' ' && pchT > &szPrinter[0]; pchT--);
  282. *pchT = '\0';
  283. /* Parse out the port and the driver names. */
  284. ParseDeviceSz(pch + 1, &pchPort, &pchDriver);
  285. }
  286. else
  287. {
  288. if (szPrinter[0] == '\0')
  289. {
  290. /* No default printer; grab the first one in the list. */
  291. GetProfileString((LPSTR)szDevices, (LPSTR)NULL, (LPSTR)&chNull,
  292. (LPSTR)szPrinter, cchMaxProfileSz);
  293. if (szPrinter[0] == '\0')
  294. {
  295. BailOut:
  296. hszPrinter = hszPrDriver = hszPrPort = NULL;
  297. return (TRUE);
  298. }
  299. }
  300. UnknownPort:
  301. /* Find the device driver and the port of the printer. */
  302. GetProfileString((LPSTR)szDevices, (LPSTR)szPrinter, (LPSTR)&chNull,
  303. (LPSTR)szDevSpec, cchMaxProfileSz);
  304. if (szPrinter[0] == '\0')
  305. {
  306. goto BailOut;
  307. }
  308. ParseDeviceSz(szDevSpec, &pchPort, &pchDriver);
  309. }
  310. GotPrinter:
  311. /* Save the names of the printer, printer driver, and the port. */
  312. if (FNoHeap(hszPrinter = (CHAR (**)[])HAllocate(cwsz =
  313. CwFromCch(CchSz(szPrinter)))))
  314. {
  315. goto NoHszPrinter;
  316. }
  317. blt(szPrinter, &(**hszPrinter)[0], cwsz);
  318. if (FNoHeap(hszPrDriver = (CHAR (**)[])HAllocate(cwsz =
  319. CwFromCch(CchSz(pchDriver)))))
  320. {
  321. goto NoHszPrDriver;
  322. }
  323. blt(pchDriver, &(**hszPrDriver)[0], cwsz);
  324. if (FNoHeap(hszPrPort = (CHAR (**)[])HAllocate(cwsz =
  325. CwFromCch(CchSz(pchPort)))))
  326. {
  327. FreeH(hszPrDriver);
  328. NoHszPrDriver:
  329. FreeH(hszPrinter);
  330. NoHszPrinter:
  331. hszPrinter = hszPrDriver = hszPrPort = NULL;
  332. return (FALSE);
  333. }
  334. blt(pchPort, &(**hszPrPort)[0], cwsz);
  335. return (TRUE);
  336. }
  337. int ParseDeviceSz(sz, ppchPort, ppchDriver)
  338. CHAR sz[];
  339. CHAR **ppchPort;
  340. CHAR **ppchDriver;
  341. {
  342. /* This routine takes a string that came from the "device" entry in the user
  343. profile and returns in *ppchPort and *ppchDriver pointers to the port and
  344. driver sutible for a CreateDC() call. If no port is found in the string,
  345. *ppchPort will point to a string containing the name of the null device.
  346. This routine returns the number of ports for this printer (separated by null
  347. characters in the string pointed at by *ppchPort). NOTE: sz may be modified
  348. by this routine, and the string at *ppchPort may not be a substring of sz
  349. and should not be modified by the caller. */
  350. extern CHAR stBuf[];
  351. extern CHAR szNul[];
  352. CHAR *index(CHAR *, int);
  353. CHAR *bltbyte(CHAR *, CHAR *, int);
  354. register CHAR *pch;
  355. int cPort = 0;
  356. /* Remove any leading spaces from the string. */
  357. for (pch = &sz[0]; *pch == ' '; pch++);
  358. /* The string starts with the driver name. */
  359. *ppchDriver = pch;
  360. /* The next space or comma terminates the driver name. */
  361. for ( ; *pch != ' ' && *pch != ',' && *pch != '\0'; pch++);
  362. /* If the string does not have a port associated with it, then the port
  363. must be the null device. */
  364. if (*pch == '\0')
  365. {
  366. /* Set the port name to "None". */
  367. *ppchPort = &szNul[0];
  368. cPort = 1;
  369. }
  370. else
  371. {
  372. /* As far as we can tell, the port name is valid; parse it from the
  373. driver name. */
  374. if (*pch == ',')
  375. {
  376. *pch++ = '\0';
  377. }
  378. else
  379. {
  380. /* Find that comma separating the driver and the port. */
  381. *pch++ = '\0';
  382. for ( ; *pch != ',' && *pch != '\0'; pch++);
  383. if (*pch == ',')
  384. {
  385. pch++;
  386. }
  387. }
  388. /* Remove any leading spaces from the port name. */
  389. for ( ; *pch == ' '; pch++);
  390. /* Check to see if there is really a port name. */
  391. if (*pch == '\0')
  392. {
  393. /* Set the port name to "None". */
  394. *ppchPort = &szNul[0];
  395. cPort = 1;
  396. }
  397. else
  398. {
  399. /* Set the pointer to the port name. */
  400. *ppchPort = pch;
  401. while (*pch != '\0')
  402. {
  403. register CHAR *pchT = pch;
  404. /* Increment the number of ports found for this printer. */
  405. cPort++;
  406. /* Remove any trailing spaces from the port name. */
  407. for ( ; *pchT != ' ' && *pchT != ','; pchT++)
  408. {
  409. if (*pchT == '\0')
  410. {
  411. goto EndFound;
  412. }
  413. }
  414. *pchT++ = '\0';
  415. pch = pchT;
  416. /* Remove any leading spaces in the next port name. */
  417. for ( ; *pchT == ' '; pchT++);
  418. /* Throw out the leading spaces. */
  419. bltbyte(pchT, pch, CchSz(pchT));
  420. }
  421. EndFound:;
  422. }
  423. }
  424. /* Parse the ".drv" out of the driver. */
  425. {
  426. extern CHAR szExtDrv[];
  427. if ((pch = index(*ppchDriver, '.')) != 0
  428. && FRgchSame(pch, szExtDrv, CchSz (szExtDrv) - 1))
  429. {
  430. *pch = '\0';
  431. }
  432. }
  433. return (cPort);
  434. }
  435. SetPrintConstants()
  436. {
  437. /* This routine sets the scaling/aspect constants for the printer described
  438. in vhDCPrinter. */
  439. extern HDC vhDCPrinter;
  440. extern BOOL vfPrinterValid;
  441. extern int dxpPrPage;
  442. extern int dypPrPage;
  443. extern int dxaPrPage;
  444. extern int dyaPrPage;
  445. extern int dxpLogInch;
  446. extern int dypLogInch;
  447. extern int ypSubSuperPr;
  448. if (vfPrinterValid && vhDCPrinter != NULL)
  449. {
  450. POINT rgpt[2];
  451. /* Get the dimensions of the printer in pixels. */
  452. dxpPrPage = rgpt[1].x = GetDeviceCaps(vhDCPrinter, HORZRES);
  453. dypPrPage = rgpt[1].y = GetDeviceCaps(vhDCPrinter, VERTRES);
  454. /* Put the printer in twips mode to find the dimensions in twips. */
  455. SetMapMode(vhDCPrinter, MM_TWIPS);
  456. rgpt[0].x = rgpt[0].y = 0;
  457. DPtoLP(vhDCPrinter, (LPPOINT)rgpt, 2);
  458. #if WINVER >= 0x300
  459. /* Weird Win bug that we can't decide on the corrective action -- sometimes
  460. DPtoLP returns x8000 here! What's that mean? Well it's SUPPOSED to be
  461. a large negative number ..pault */
  462. if (rgpt[1].x == 0x8000)
  463. rgpt[1].x = -(0x7fff);
  464. if (rgpt[1].y == 0x8000)
  465. rgpt[1].y = -(0x7fff);
  466. #endif
  467. if ((dxaPrPage = rgpt[1].x - rgpt[0].x) < 0)
  468. {
  469. dxaPrPage = -dxaPrPage;
  470. }
  471. if ((dyaPrPage = rgpt[0].y - rgpt[1].y) < 0)
  472. {
  473. dyaPrPage = -dyaPrPage;
  474. }
  475. SetMapMode(vhDCPrinter, MM_TEXT);
  476. }
  477. else
  478. {
  479. /* Pretend the printer is just like the screen. */
  480. dxaPrPage = dyaPrPage = czaInch;
  481. dxpPrPage = dxpLogInch;
  482. dypPrPage = dypLogInch;
  483. }
  484. /* ypSubSuperPr is the offset for subscript and supercript font on the
  485. printer. */
  486. ypSubSuperPr = MultDiv(yaSubSuper, dypPrPage, dyaPrPage);
  487. }
  488. GetPrinterDC(fDC)
  489. BOOL fDC;
  490. {
  491. /* This routine sets vhDCPrinter to a new printer DC or IC. If fDC is TRUE,
  492. a new DC is created; otherwise, a new IC is created. In addition, all
  493. global variables dependent on the printer DC are changed. */
  494. extern HDC vhDCPrinter;
  495. extern BOOL vfPrinterValid;
  496. extern CHAR (**hszPrinter)[];
  497. extern CHAR (**hszPrDriver)[];
  498. extern CHAR (**hszPrPort)[];
  499. extern HWND hParentWw;
  500. extern int docCur;
  501. extern struct DOD (**hpdocdod)[];
  502. extern BOOL vfWarnMargins;
  503. extern BOOL vfInitializing;
  504. extern PRINTDLG PD;
  505. BOOL fCreateError = FALSE;
  506. /* We now pass the local PrinterSetup settings to CreateDC/CreateIC
  507. since Write's settings can differ from the global ones ..pault */
  508. LPSTR lpDevmodeData=NULL;
  509. Assert(vhDCPrinter == NULL);
  510. /* Get a new printer DC. */
  511. #ifdef WIN30
  512. if (hszPrinter != NULL && hszPrDriver != NULL && hszPrPort != NULL)
  513. /* We used to only do this check if vfPrinterValid -- don't
  514. now because otherwise one has no way to get Write to believe
  515. it has a valid printer! ..pt */
  516. #else
  517. if (vfPrinterValid && hszPrinter != NULL && hszPrDriver != NULL &&
  518. hszPrPort != NULL)
  519. #endif
  520. {
  521. HDC (far PASCAL *fnCreate)() = fDC ? CreateDC : CreateIC;
  522. StartLongOp();
  523. if (PD.hDevMode == NULL)
  524. fnPrGetDevmode(); // get PD.hDevMode
  525. lpDevmodeData = MAKELP(PD.hDevMode,0);
  526. if ((vhDCPrinter = (*fnCreate)((LPSTR)&(**hszPrDriver)[0],
  527. (LPSTR)&(**hszPrinter)[0], (LPSTR)&(**hszPrPort)[0], lpDevmodeData)) !=
  528. NULL)
  529. {
  530. EndLongOp(vhcIBeam);
  531. vfPrinterValid = TRUE;
  532. }
  533. else
  534. {
  535. /* If we thought the DC was valid, then we better tell the user it
  536. is not. */
  537. EndLongOp(vhcIBeam);
  538. fCreateError = TRUE;
  539. goto NoDC;
  540. }
  541. }
  542. else
  543. {
  544. NoDC:
  545. /* We don't have a printer DC, so use the DC for the screen. */
  546. vhDCPrinter = GetDC(hParentWw);
  547. vfPrinterValid = FALSE;
  548. /* Warn the user if necessary. This is done after creating the printer
  549. DC because Error() may force the DC to be created if we had not already
  550. done so. */
  551. if (fCreateError)
  552. {
  553. BOOL fInit = vfInitializing;
  554. vfInitializing = FALSE;
  555. #ifdef DBCS /* was in JAPAN */
  556. /* We have to answer to WM_WININICHANGE immidiately to ReleaseDC with
  557. ** 'dispatch' printer driver.
  558. ** So It's possible for us opening MessageBox deep in SendMessage
  559. ** call. This code avoid that.. Yutakan.
  560. */
  561. if( !InSendMessage() )
  562. #endif
  563. Error(IDPMTCantPrint);
  564. vfInitializing = fInit;
  565. }
  566. }
  567. /* Set new values for the "constants" used by this printer. */
  568. SetPrintConstants();
  569. /* Set the size of the paper for this printer. */
  570. SetPageSize();
  571. vfWarnMargins = FALSE;
  572. /* The printer may have changed in such a way that it's fonts have changed
  573. (i.e. portrait to landscape). We must re-initialize our list of fonts. */
  574. ResetDefaultFonts(TRUE);
  575. if (hpdocdod != NULL)
  576. {
  577. Assert((**hpdocdod)[docCur].hffntb != NULL);
  578. (*(**hpdocdod)[docCur].hffntb)->fFontMenuValid = FALSE;
  579. }
  580. }
  581. SetPageSize()
  582. {
  583. /* Change the size of the paper to the printer described by vhDCPrinter. */
  584. extern HDC vhDCPrinter;
  585. extern HWND vhWndMsgBoxParent;
  586. extern BOOL vfPrinterValid;
  587. extern typeCP cpMinHeader;
  588. extern typeCP cpMacHeader;
  589. extern typeCP cpMinFooter;
  590. extern typeCP cpMacFooter;
  591. extern int dxpPrPage;
  592. extern int dypPrPage;
  593. extern int dxaPrPage;
  594. extern int dyaPrPage;
  595. extern HWND hParentWw;
  596. extern struct SEP vsepNormal;
  597. extern struct DOD (**hpdocdod)[];
  598. extern int docMac;
  599. extern int docScrap;
  600. extern int docUndo;
  601. extern BOOL vfWarnMargins;
  602. unsigned xaMac;
  603. unsigned yaMac;
  604. unsigned dxaRight;
  605. unsigned dyaBottom;
  606. unsigned dyaRH2;
  607. unsigned dxaPrRight = 0;
  608. unsigned dyaPrBottom = 0;
  609. BOOL fRH;
  610. register struct DOD *pdod;
  611. int doc;
  612. HWND hWnd;
  613. if (hpdocdod == NULL || docMac == 0)
  614. {
  615. /* Nothing to do if there are no documents. */
  616. return;
  617. }
  618. Assert(vhDCPrinter);
  619. if (vfPrinterValid && vhDCPrinter != NULL)
  620. {
  621. POINT pt;
  622. /* Get the page size of the printer. */
  623. if (Escape(vhDCPrinter, GETPHYSPAGESIZE, 0, (LPSTR)NULL, (LPSTR)&pt))
  624. {
  625. xaMac = MultDiv(pt.x, dxaPrPage, dxpPrPage);
  626. yaMac = MultDiv(pt.y, dyaPrPage, dypPrPage);
  627. }
  628. else
  629. {
  630. /* The printer won't tell us it page size; we'll have to settle
  631. for the printable area. */
  632. xaMac = ZaFromMm(GetDeviceCaps(vhDCPrinter, HORZSIZE));
  633. yaMac = ZaFromMm(GetDeviceCaps(vhDCPrinter, VERTSIZE));
  634. }
  635. /* The page size cannot be smaller than the printable area. */
  636. if (xaMac < dxaPrPage)
  637. {
  638. xaMac = dxaPrPage;
  639. }
  640. if (yaMac < dyaPrPage)
  641. {
  642. yaMac = dyaPrPage;
  643. }
  644. /* Determine the offset of the printable area on the page. */
  645. if (Escape(vhDCPrinter, GETPRINTINGOFFSET, 0, (LPSTR)NULL, (LPSTR)&pt))
  646. {
  647. dxaPrOffset = MultDiv(pt.x, dxaPrPage, dxpPrPage);
  648. dyaPrOffset = MultDiv(pt.y, dyaPrPage, dypPrPage);
  649. }
  650. else
  651. {
  652. /* The printer won't tell us what the offset is; assume the
  653. printable area is centered on the page. */
  654. dxaPrOffset = (xaMac - dxaPrPage) >> 1;
  655. dyaPrOffset = (yaMac - dyaPrPage) >> 1;
  656. }
  657. }
  658. else
  659. {
  660. /* Assume standard page size for now. */
  661. xaMac = cxaInch * 8 + cxaInch / 2;
  662. yaMac = cyaInch * 11;
  663. dxaPrOffset = dyaPrOffset = 0;
  664. }
  665. /* Determine the right and bottom margins for the "normal" page. */
  666. dxaRight = vsepNormal.xaMac - vsepNormal.xaLeft - vsepNormal.dxaText;
  667. dyaBottom = vsepNormal.yaMac - vsepNormal.yaTop - vsepNormal.dyaText;
  668. dyaRH2 = vsepNormal.yaMac - vsepNormal.yaRH2;
  669. /* Determine the minimum dimensions of the printed page. */
  670. if (vfPrinterValid)
  671. {
  672. dxaPrRight = imax(0, xaMac - dxaPrOffset - dxaPrPage);
  673. dyaPrBottom = imax(0, yaMac - dyaPrOffset - dyaPrPage);
  674. hWnd = vhWndMsgBoxParent == NULL ? hParentWw : vhWndMsgBoxParent;
  675. #ifdef BOGUS
  676. /* Check the margins of the "normal" page. */
  677. fRH = cpMacHeader - cpMacHeader > ccpEol || cpMacFooter - cpMinFooter >
  678. ccpEol;
  679. if (vfWarnMargins && (FUserZaLessThanZa(vsepNormal.xaLeft, dxaPrOffset)
  680. || FUserZaLessThanZa(dxaRight, dxaPrRight) ||
  681. FUserZaLessThanZa(vsepNormal.yaTop, dyaPrOffset) ||
  682. FUserZaLessThanZa(dyaBottom, dyaPrBottom) || (fRH &&
  683. (FUserZaLessThanZa(vsepNormal.yaRH1, dyaPrOffset) ||
  684. FUserZaLessThanZa(dyaRH2, dyaPrBottom)))))
  685. {
  686. /* One of the margins is bad, tell the user about it. */
  687. ErrorBadMargins(hWnd, dxaPrOffset, dxaPrRight, dyaPrOffset,
  688. dyaPrBottom);
  689. vfWarnMargins = FALSE;
  690. }
  691. #endif /* BOGUS */
  692. }
  693. /* Reset the dimensions of the "normal" page. */
  694. vsepNormal.xaMac = xaMac;
  695. vsepNormal.dxaText = xaMac - vsepNormal.xaLeft - umax(dxaRight, dxaPrRight);
  696. vsepNormal.yaMac = yaMac;
  697. vsepNormal.dyaText = yaMac - vsepNormal.yaTop - umax(dyaBottom,
  698. dyaPrBottom);
  699. vsepNormal.yaRH2 = yaMac - umax(dyaRH2, dyaPrBottom);
  700. /* Reset the page dimensions for all documents. */
  701. for (doc = 0, pdod = &(**hpdocdod)[0]; doc < docMac; doc++, pdod++)
  702. {
  703. if (pdod->hpctb != NULL && pdod->hsep != NULL)
  704. {
  705. /* Reset the existing section properties. */
  706. register struct SEP *psep = *(pdod->hsep);
  707. /* Determine the right and bottom margins for this page. */
  708. dxaRight = psep->xaMac - psep->xaLeft - psep->dxaText;
  709. dyaBottom = psep->yaMac - psep->yaTop - psep->dyaText;
  710. dyaRH2 = psep->yaMac - psep->yaRH2;
  711. /* Check the margins for this document. */
  712. if (vfWarnMargins && vfPrinterValid && doc != docScrap && doc !=
  713. docUndo && (FUserZaLessThanZa(psep->xaLeft, dxaPrOffset) ||
  714. FUserZaLessThanZa(dxaRight, dxaPrRight) ||
  715. FUserZaLessThanZa(psep->yaTop, dyaPrOffset) ||
  716. FUserZaLessThanZa(dyaBottom, dyaPrBottom) || (fRH &&
  717. (FUserZaLessThanZa(psep->yaRH1, dyaPrOffset) ||
  718. FUserZaLessThanZa(dyaRH2, dyaPrBottom)))))
  719. {
  720. ErrorBadMargins(hWnd, dxaPrOffset, dxaPrRight, dyaPrOffset,
  721. dyaPrBottom);
  722. vfWarnMargins = FALSE;
  723. pdod = &(**hpdocdod)[doc];
  724. psep = *(pdod->hsep);
  725. }
  726. /* Set the dimensions of this page. */
  727. psep->xaMac = xaMac;
  728. psep->dxaText = xaMac - psep->xaLeft - dxaRight;
  729. psep->yaMac = yaMac;
  730. psep->dyaText = yaMac - psep->yaTop - dyaBottom;
  731. psep->yaRH2 = yaMac - dyaRH2;
  732. }
  733. /* Invalidate any caches for this document. */
  734. InvalidateCaches(doc);
  735. }
  736. }
  737. 
  738. 
  739.