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.

517 lines
18 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1990 Microsoft Corporation */
  3. /************************************************************/
  4. /* This file contains the routines for the change printer dialog box. */
  5. #define NOGDICAPMASKS
  6. #define NOVIRTUALKEYCODES
  7. #define NOWINSTYLES
  8. #define NOSYSMETRICS
  9. #define NOMENUS
  10. #define NOCLIPBOARD
  11. #define NOKEYSTATE
  12. #define NOSYSCOMMANDS
  13. #define NORASTEROPS
  14. #define NOSHOWWINDOW
  15. #define NOATOM
  16. #define NOCREATESTRUCT
  17. #define NODRAWTEXT
  18. #define NOMB
  19. #define NOMETAFILE
  20. #define NOWH
  21. #define NOWNDCLASS
  22. #define NOSOUND
  23. #define NOCOLOR
  24. #define NOSCROLL
  25. #define NOCOMM
  26. #include <windows.h>
  27. #ifdef EXTDEVMODESUPPORT
  28. #include <drivinit.h> /* new for win 3.0 and extdevicemode pr.drv. calls */
  29. #endif
  30. #include "mw.h"
  31. #include "dlgdefs.h"
  32. #include "cmddefs.h"
  33. #include "machdefs.h"
  34. #include "docdefs.h"
  35. #include "propdefs.h"
  36. #include "printdef.h"
  37. #include "str.h"
  38. extern CHAR szExtDrv[];
  39. extern CHAR szDeviceMode[];
  40. extern CHAR szNone[];
  41. extern HWND vhWnd;
  42. #ifdef EXTDEVMODESUPPORT
  43. extern CHAR szExtDevMode[];
  44. extern HANDLE hDevmodeData;
  45. #endif
  46. BOOL far PASCAL DialogPrinterSetup( hDlg, message, wParam, lParam )
  47. HWND hDlg;
  48. unsigned message;
  49. WORD wParam;
  50. LONG lParam;
  51. {
  52. extern CHAR *vpDlgBuf;
  53. extern HWND hParentWw;
  54. extern CHAR szDevices[];
  55. extern CHAR stBuf[];
  56. extern HDC vhDCPrinter;
  57. extern CHAR (**hszPrinter)[];
  58. extern CHAR (**hszPrDriver)[];
  59. extern CHAR (**hszPrPort)[];
  60. extern BOOL vfPrinterValid;
  61. extern HANDLE hMmwModInstance;
  62. extern BOOL vfPrDefault;
  63. extern int vfCursorVisible;
  64. extern HCURSOR vhcArrow;
  65. extern HCURSOR vhcIBeam;
  66. extern HWND vhWndMsgBoxParent;
  67. void BuildPrSetupSz(CHAR *, CHAR *, CHAR *);
  68. CHAR (***phszPr)[] = (CHAR (***)[])vpDlgBuf;
  69. BOOL *pfOkEnabled = (BOOL *)(phszPr + 3);
  70. CHAR stKeyName[cchMaxIDSTR];
  71. CHAR szPrinters[cchMaxProfileSz];
  72. CHAR *pchPrinters;
  73. CHAR szDevSpec[cchMaxProfileSz];
  74. CHAR szListEntry[cchMaxProfileSz];
  75. CHAR *pchPort;
  76. CHAR *pchDriver;
  77. CHAR chNull = '\0';
  78. int iPrinter;
  79. BOOL fSingleClick;
  80. switch (message)
  81. {
  82. case WM_INITDIALOG:
  83. /* Disable any modeless dialog boxes. */
  84. EnableOtherModeless(FALSE);
  85. /* Save away the heap strings that describe the current printer. */
  86. *phszPr++ = hszPrinter;
  87. *phszPr++ = hszPrDriver;
  88. *phszPr = hszPrPort;
  89. /* Get a string that holds all of the printer names. */
  90. GetProfileString((LPSTR)szDevices, (LPSTR)NULL, (LPSTR)&chNull,
  91. (LPSTR)szPrinters, cchMaxProfileSz);
  92. /* There must be two nulls at the end of the list. */
  93. szPrinters[cchMaxProfileSz - 1] = szPrinters[cchMaxProfileSz - 2] =
  94. '\0';
  95. /* Parse out the names of the printers. */
  96. pchPrinters = &szPrinters[0];
  97. while (*pchPrinters != '\0')
  98. {
  99. /* Get the corresponding printer driver and port. */
  100. GetProfileString((LPSTR)szDevices, (LPSTR)pchPrinters,
  101. (LPSTR)&chNull, (LPSTR)szDevSpec, cchMaxProfileSz);
  102. szDevSpec[cchMaxProfileSz - 1] = '\0';
  103. /* If there is no driver for this printer, then it cannot be added
  104. to the list. */
  105. if (szDevSpec[0] != '\0')
  106. {
  107. /* Parse the ports and the driver. */
  108. int cPort = ParseDeviceSz(szDevSpec, &pchPort, &pchDriver);
  109. int iPort;
  110. for (iPort = 0; iPort < cPort; iPort++)
  111. {
  112. /* Contruct the list box entry. */
  113. BuildPrSetupSz(szListEntry, pchPrinters, pchPort);
  114. /* Put the string in the list box
  115. provided printer is not on "None" */
  116. if (!FSzSame(pchPort, szNone))
  117. SendDlgItemMessage(hDlg, idiPrterName, LB_ADDSTRING,
  118. 0, (LONG)(LPSTR)szListEntry);
  119. /* Bump the pointer to the next port in the list. */
  120. pchPort += CchSz(pchPort);
  121. }
  122. }
  123. /* Skip to the next printer in the list. */
  124. while (*pchPrinters++) ;
  125. }
  126. /* Select the current printer. */
  127. if (!(*pfOkEnabled = hszPrinter != NULL && hszPrPort != NULL &&
  128. (BuildPrSetupSz(szListEntry, &(**hszPrinter)[0], &(**hszPrPort)[0]),
  129. SendDlgItemMessage(hDlg, idiPrterName, LB_SELECTSTRING, -1,
  130. (LONG)(LPSTR)szListEntry) >= 0)))
  131. {
  132. EnableWindow(GetDlgItem(hDlg, idiOk), FALSE);
  133. }
  134. return(fTrue); /* we processed the message */
  135. case WM_SETVISIBLE:
  136. if (wParam)
  137. {
  138. EndLongOp(vhcArrow);
  139. }
  140. break; /* to return false below */
  141. case WM_ACTIVATE:
  142. if (wParam)
  143. {
  144. vhWndMsgBoxParent = hDlg;
  145. }
  146. if (vfCursorVisible)
  147. {
  148. ShowCursor(wParam);
  149. }
  150. break; /* to return false below */
  151. case WM_COMMAND:
  152. fSingleClick = FALSE;
  153. switch (wParam)
  154. {
  155. case idiPrterName:
  156. if (HIWORD(lParam) == 1) /* remember single mouse clicks */
  157. {
  158. fSingleClick = fTrue;
  159. }
  160. else if (HIWORD(lParam) != 2) /* 2 is a double mouse click */
  161. break; /* LBNmsg (listbox notification) we don't handle */
  162. case idiPrterSetup:
  163. case idiOk:
  164. /* If none of the printers is currently selected... */
  165. if ((iPrinter = SendDlgItemMessage(hDlg, idiPrterName, LB_GETCURSEL,
  166. 0, 0L)) == -1)
  167. {
  168. /* Disable the "OK" button. */
  169. if (*pfOkEnabled)
  170. {
  171. EnableWindow(GetDlgItem(hDlg, idiOk), FALSE);
  172. *pfOkEnabled = FALSE;
  173. }
  174. return(fTrue); /* we processed the message */
  175. }
  176. else
  177. {
  178. CHAR *index(CHAR *, int);
  179. CHAR *bltbyte(CHAR *, CHAR *, int);
  180. CHAR *pch;
  181. CHAR szDriver[cchMaxFile];
  182. HANDLE hDriver;
  183. FARPROC lpfnDevMode;
  184. #ifdef EXTDEVMODESUPPORT
  185. BOOL fExtDevModeSupport = fTrue; /* assume until told otherwise */
  186. #endif
  187. int cwsz;
  188. if (fSingleClick)
  189. {
  190. /* If this is just a single mouse-click, then just update the
  191. status of the "OK" button. */
  192. if (!*pfOkEnabled)
  193. {
  194. EnableWindow(GetDlgItem(hDlg, idiOk), TRUE);
  195. *pfOkEnabled = TRUE;
  196. }
  197. return(fTrue); /* we processed the message */
  198. }
  199. /* Let the user know that this may take a while. */
  200. StartLongOp();
  201. /* Get the printer's name, it's port, and it's driver. */
  202. SendDlgItemMessage(hDlg, idiPrterName, LB_GETTEXT, iPrinter,
  203. (LONG)(LPSTR)szListEntry);
  204. /* Parse the port name out of the list entry. */
  205. pchPort = &szListEntry[0] + CchSz(szListEntry) - 1;
  206. while (*(pchPort - 1) != ' ')
  207. {
  208. pchPort--;
  209. }
  210. /* Parse the name of the printer out of the list entry. */
  211. pch = &szListEntry[0];
  212. FillStId(stBuf, IDSTROn, sizeof(stBuf));
  213. for ( ; ; )
  214. {
  215. if ((pch = index(pch, ' ')) != 0 && FRgchSame(pch,
  216. &stBuf[1], stBuf[0]))
  217. {
  218. *pch = '\0';
  219. break;
  220. }
  221. pch++;
  222. }
  223. /* Get the driver name for this printer. */
  224. GetProfileString((LPSTR)szDevices, (LPSTR)szListEntry,
  225. (LPSTR)&chNull, (LPSTR)szDevSpec, cchMaxProfileSz);
  226. ParseDeviceSz(szDevSpec, &pch, &pchDriver);
  227. /* Update the heap strings describing the printer. */
  228. if (hszPrinter != *phszPr)
  229. {
  230. FreeH(hszPrinter);
  231. }
  232. if (FNoHeap(hszPrinter = (CHAR (**)[])HAllocate(cwsz =
  233. CwFromCch(CchSz(szListEntry)))))
  234. {
  235. hszPrinter = NULL;
  236. Error:
  237. EndLongOp(vhcIBeam);
  238. goto DestroyDlg;
  239. }
  240. blt(szListEntry, *hszPrinter, cwsz);
  241. if (hszPrDriver != *(phszPr + 1))
  242. {
  243. FreeH(hszPrDriver);
  244. }
  245. if (FNoHeap(hszPrDriver = (CHAR (**)[])HAllocate(cwsz =
  246. CwFromCch(CchSz(pchDriver)))))
  247. {
  248. hszPrDriver = NULL;
  249. goto Error;
  250. }
  251. blt(pchDriver, *hszPrDriver, cwsz);
  252. if (hszPrPort != *(phszPr + 2))
  253. {
  254. FreeH(hszPrPort);
  255. }
  256. if (FNoHeap(hszPrPort = (CHAR (**)[])HAllocate(cwsz =
  257. CwFromCch(CchSz(pchPort)))))
  258. {
  259. hszPrPort = NULL;
  260. goto Error;
  261. }
  262. blt(pchPort, *hszPrPort, cwsz);
  263. /* Get the name of the driver, complete with extension. */
  264. bltbyte(szExtDrv,
  265. bltbyte(pchDriver, szDriver, CchSz(pchDriver) - 1),
  266. CchSz(szExtDrv));
  267. /* That's all we need for Setup ..pault */
  268. if (wParam != idiPrterSetup)
  269. goto LSetupDone;
  270. /* The driver is not resident; attempt to load it. */
  271. if ((hDriver = LoadLibrary((LPSTR)szDriver)) <= 32)
  272. {
  273. if (hDriver != 2)
  274. {
  275. /* If hDriver is 2, then the user has cancelled a dialog
  276. box; there's no need to put up another. */
  277. Error(IDPMTBadPrinter);
  278. }
  279. Abort:
  280. EndLongOp(vhcArrow);
  281. return (TRUE); /* True means we processed the message */
  282. }
  283. #ifdef EXTDEVMODESUPPORT
  284. /* First see if ExtDeviceMode is supported (Win 3.0 drivers) */
  285. if ((lpfnDevMode = GetProcAddress(hDriver,
  286. (LPSTR)szExtDevMode)) == NULL)
  287. {
  288. fExtDevModeSupport = fFalse;
  289. #else
  290. {
  291. #endif
  292. /* Otherwise get the driver's DeviceMode() entry. */
  293. if ((lpfnDevMode = GetProcAddress(hDriver,
  294. (LPSTR)szDeviceMode)) == NULL)
  295. {
  296. /* No can do, eh? */
  297. Error(IDPMTBadPrinter);
  298. LUnloadAndAbort:
  299. FreeLibrary(hDriver);
  300. goto Abort;
  301. }
  302. }
  303. #ifdef EXTDEVMODESUPPORT
  304. /* Actual calls to the device modes setup.
  305. Much of this new ExtDevModeSupport stuff
  306. borrowed from MULTIPAD ..pault */
  307. if (fExtDevModeSupport)
  308. {
  309. int cb;
  310. int wId;
  311. HANDLE hT;
  312. LPDEVMODE lpOld, lpNew;
  313. BOOL flag; /* devmode mode param */
  314. /* pop up dialog for user */
  315. flag = DM_PROMPT|DM_COPY;
  316. if (hDevmodeData != NULL)
  317. {
  318. NPDEVMODE npOld;
  319. /* Modify the user's last print settings */
  320. flag |= DM_MODIFY;
  321. lpOld = (LPDEVMODE)(npOld = (NPDEVMODE)LocalLock(hDevmodeData));
  322. /* Check to see if they're using the same printer
  323. driver as last time. If so, let them modify all
  324. of their previous settings. If not, we tell
  325. ExtDevMode to save as many of the hardware-
  326. independent settings as it can (e.g. copies) */
  327. if (!FSzSame(szListEntry, npOld->dmDeviceName))
  328. {
  329. npOld->dmDriverVersion = NULL;
  330. npOld->dmDriverExtra = NULL;
  331. bltsz(szListEntry, npOld->dmDeviceName);
  332. }
  333. }
  334. else
  335. /* We haven't done a printer setup yet this session */
  336. lpOld = NULL;
  337. /* how much space do we need for the data? */
  338. cb = (*lpfnDevMode)(hDlg, hDriver, (LPSTR)NULL,
  339. (LPSTR)szListEntry, (LPSTR)pchPort,
  340. (LPDEVMODE)NULL, (LPSTR)NULL, 0);
  341. if ((hT = LocalAlloc(LHND, cb)) == NULL)
  342. goto LUnloadAndAbort;
  343. lpNew = (LPDEVMODE)LocalLock(hT);
  344. /* post the device mode dialog. 0 flag iff user hits OK button */
  345. wId = (*lpfnDevMode)(hDlg, hDriver, (LPDEVMODE)lpNew,
  346. (LPSTR)szListEntry, (LPSTR)pchPort,
  347. (LPDEVMODE)lpOld, (LPSTR)NULL, flag);
  348. if (wId == IDOK)
  349. flag = 0;
  350. /* unlock the input structures */
  351. LocalUnlock(hT);
  352. if (hDevmodeData != NULL)
  353. LocalUnlock(hDevmodeData);
  354. /* if the user hit OK and everything worked, free the original init
  355. * data and retain the new one. Otherwise, toss the new buffer
  356. */
  357. if (flag != 0)
  358. {
  359. LocalFree(hT);
  360. goto LUnloadAndAbort;
  361. }
  362. else
  363. {
  364. if (hDevmodeData != NULL)
  365. LocalFree(hDevmodeData);
  366. hDevmodeData = hT;
  367. }
  368. }
  369. else /* older Win 2.0 driver, make DeviceMode call */
  370. {
  371. if (hDevmodeData != NULL)
  372. {
  373. /* We'd opened a Win3 printer driver before; now discard */
  374. LocalFree(hDevmodeData);
  375. hDevmodeData = NULL;
  376. }
  377. #else /* ifdef EXTDEVMODESUPPORT */
  378. {
  379. #endif /* else-def-EXTDEVMODESUPPORT */
  380. if (!(*lpfnDevMode)(hDlg, hDriver, (LPSTR)szListEntry,
  381. (LPSTR)pchPort))
  382. goto LUnloadAndAbort;
  383. }
  384. FreeLibrary(hDriver);
  385. LSetupDone:
  386. /* Let the user know the waiting is over. */
  387. EndLongOp(vhcIBeam);
  388. /* Printer setup should take us back to printer choices! */
  389. if (wParam == idiPrterSetup)
  390. {
  391. return (TRUE); /* True means we processed the message */
  392. }
  393. /* Previously we freed these guys before returning
  394. and that fouled up our heap ..pault */
  395. FreeH(*phszPr++);
  396. FreeH(*phszPr++);
  397. FreeH(*phszPr);
  398. vfPrDefault = FALSE;
  399. #ifdef WIN30
  400. /* Need to indicate to FormatLine and Friends here
  401. that we (may) have a different font pool to work
  402. with and we should look at the new ones! Invalidating
  403. the window will cause FormatLine to be called, and
  404. when it hits the null printer dc it'll force a call
  405. to GetPrinterDC ..pault */
  406. FreePrinterDC();
  407. InvalidateRect(vhWnd, (LPRECT) NULL, fFalse);
  408. #endif
  409. goto DestroyDlg;
  410. }
  411. case idiCancel:
  412. hszPrinter = *phszPr++;
  413. hszPrDriver = *phszPr++;
  414. hszPrPort = *phszPr;
  415. DestroyDlg:
  416. /* Close the dialog box and enable any modeless dialog boxes. */
  417. OurEndDialog(hDlg, NULL);
  418. return(fTrue); /* we processed the message */
  419. }
  420. }
  421. return(fFalse); /* if we got here we didn't process the message */
  422. }
  423. void BuildPrSetupSz(szPrSetup, szPrinter, szPort)
  424. CHAR *szPrSetup;
  425. CHAR *szPrinter;
  426. CHAR *szPort;
  427. {
  428. /* This routine pieces together the string for the Change Printers list box.
  429. szPrinter is the name of the printer, and szPort, the name of the port. It
  430. is assumed that the setup string, szPrSetup, is large enough to hold the
  431. string created by this routine. */
  432. extern CHAR stBuf[];
  433. extern CHAR szNul[];
  434. CHAR *bltbyte(CHAR *, CHAR *, int);
  435. CHAR ChUpper(CHAR);
  436. register CHAR *pch;
  437. pch = bltbyte(szPrinter, szPrSetup, CchSz(szPrinter) - 1);
  438. FillStId(stBuf, IDSTROn, sizeof(stBuf));
  439. pch = bltbyte(&stBuf[1], pch, stBuf[0]);
  440. /* If the port name is not "None", then raise the port name to all capitals.
  441. */
  442. bltbyte(szPort, pch, CchSz(szPort));
  443. if (WCompSz(pch, szNul) != 0)
  444. {
  445. while (*pch != '\0')
  446. {
  447. *pch++ = ChUpper(*pch);
  448. }
  449. }
  450. }