Source code of Windows XP (NT5)
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.

676 lines
14 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. docprop.c
  5. Abstract:
  6. Implemetation of DDI entry points:
  7. DrvDocumentPropertySheets
  8. DrvDocumentProperties
  9. DrvAdvancedDocumentProperties
  10. DrvConvertDevMode
  11. Environment:
  12. Fax driver user interface
  13. Revision History:
  14. 01/09/96 -davidx-
  15. Created it.
  16. mm/dd/yy -author-
  17. description
  18. --*/
  19. #include "faxui.h"
  20. #include "forms.h"
  21. #include "libproto.h"
  22. #include "faxhelp.h"
  23. INT_PTR FaxOptionsProc(HWND, UINT, WPARAM, LPARAM);
  24. LONG SimpleDocumentProperties(PDOCUMENTPROPERTYHEADER);
  25. BOOL GenerateFormsList(PUIDATA);
  26. BOOL AddDocPropPages(PUIDATA, LPTSTR);
  27. LPTSTR GetHelpFilename(PUIDATA);
  28. LONG
  29. DrvDocumentPropertySheets(
  30. PPROPSHEETUI_INFO pPSUIInfo,
  31. LPARAM lParam
  32. )
  33. /*++
  34. Routine Description:
  35. Display "Document Properties" property sheets
  36. Arguments:
  37. pPSUIInfo - Pointer to a PROPSHEETUI_INFO structure
  38. lParam - Pointer to a DOCUMENTPROPERTYHEADER structure
  39. Return Value:
  40. > 0 if successful, <= 0 if failed
  41. [Note:]
  42. Please refer to WinNT DDK/SDK documentation for more details.
  43. --*/
  44. {
  45. PDOCUMENTPROPERTYHEADER pDPHdr;
  46. PUIDATA pUiData;
  47. //
  48. // Validate input parameters
  49. // pPSUIInfo = NULL is a special case: don't need to display the dialog
  50. //
  51. if (! (pDPHdr = (PDOCUMENTPROPERTYHEADER) (pPSUIInfo ? pPSUIInfo->lParamInit : lParam))) {
  52. Assert(FALSE);
  53. return -1;
  54. }
  55. if (pPSUIInfo == NULL)
  56. return SimpleDocumentProperties(pDPHdr);
  57. Verbose(("DrvDocumentPropertySheets: %d\n", pPSUIInfo->Reason));
  58. //
  59. // Create a UIDATA structure if necessary
  60. //
  61. pUiData = (pPSUIInfo->Reason == PROPSHEETUI_REASON_INIT) ?
  62. FillUiData(pDPHdr->hPrinter, pDPHdr->pdmIn) :
  63. (PUIDATA) pPSUIInfo->UserData;
  64. if (! ValidUiData(pUiData))
  65. return -1;
  66. //
  67. // Handle various cases for which this function might be called
  68. //
  69. switch (pPSUIInfo->Reason) {
  70. case PROPSHEETUI_REASON_INIT:
  71. pUiData->hasPermission = ((pDPHdr->fMode & DM_NOPERMISSION) == 0);
  72. pUiData->pfnComPropSheet = pPSUIInfo->pfnComPropSheet;
  73. pUiData->hComPropSheet = pPSUIInfo->hComPropSheet;
  74. if (pDPHdr->fMode & DM_USER_DEFAULT)
  75. pUiData->configDefault = TRUE;
  76. //
  77. // Find online help filename
  78. //
  79. GetHelpFilename(pUiData);
  80. //
  81. // Add our pages to the property sheet
  82. //
  83. if (GenerateFormsList(pUiData) && AddDocPropPages(pUiData, pDPHdr->pszPrinterName)) {
  84. pPSUIInfo->UserData = (DWORD_PTR) pUiData;
  85. pPSUIInfo->Result = CPSUI_CANCEL;
  86. return 1;
  87. }
  88. //
  89. // Clean up properly in case of an error
  90. //
  91. HeapDestroy(pUiData->hheap);
  92. break;
  93. case PROPSHEETUI_REASON_GET_INFO_HEADER:
  94. { PPROPSHEETUI_INFO_HEADER pPSUIHdr;
  95. pPSUIHdr = (PPROPSHEETUI_INFO_HEADER) lParam;
  96. pPSUIHdr->Flags = PSUIHDRF_PROPTITLE | PSUIHDRF_NOAPPLYNOW;
  97. pPSUIHdr->pTitle = pDPHdr->pszPrinterName;
  98. pPSUIHdr->hInst = ghInstance;
  99. pPSUIHdr->IconID = IDI_CPSUI_PRINTER2;
  100. }
  101. return 1;
  102. case PROPSHEETUI_REASON_SET_RESULT:
  103. //
  104. // Copy the new devmode back into the output buffer provided by the caller
  105. // Always return the smaller of current and input devmode
  106. //
  107. { PSETRESULT_INFO pSRInfo = (PSETRESULT_INFO) lParam;
  108. Verbose(("Set result: %d\n", pSRInfo->Result));
  109. if (pSRInfo->Result == CPSUI_OK && (pDPHdr->fMode & (DM_COPY|DM_UPDATE))) {
  110. ConvertDevmodeOut((PDEVMODE) &pUiData->devmode,
  111. pDPHdr->pdmIn,
  112. pDPHdr->pdmOut);
  113. }
  114. pPSUIInfo->Result = pSRInfo->Result;
  115. }
  116. return 1;
  117. case PROPSHEETUI_REASON_DESTROY:
  118. //
  119. // Cleanup properly before exiting
  120. //
  121. HeapDestroy(pUiData->hheap);
  122. return 1;
  123. }
  124. return -1;
  125. }
  126. LONG
  127. DoDocumentProperties(
  128. HWND hwnd,
  129. HANDLE hPrinter,
  130. LPTSTR pPrinterName,
  131. PDEVMODE pdmOutput,
  132. PDEVMODE pdmInput,
  133. DWORD fMode
  134. )
  135. /*++
  136. Arguments:
  137. hwnd - Handle to the parent window of the document properties dialog box.
  138. hPrinter - Handle to a printer object.
  139. pPrinterName - Points to a null-terminated string that specifies
  140. the name of the device for which the document properties dialog
  141. box should be displayed.
  142. pdmOutput - Points to a DEVMODE structure that receives the document
  143. properties data specified by the user.
  144. pdmInput - Points to a DEVMODE structure that initializes the dialog
  145. box controls. This parameter can be NULL.
  146. fmode - Specifies a mask of flags that determine which operations
  147. the function performs.
  148. Return Value:
  149. > 0 if successful
  150. = 0 if canceled
  151. < 0 if error
  152. --*/
  153. {
  154. DOCUMENTPROPERTYHEADER docPropHdr;
  155. DWORD result;
  156. //
  157. // Initialize a DOCUMENTPROPERTYHEADER structure
  158. //
  159. memset(&docPropHdr, 0, sizeof(docPropHdr));
  160. docPropHdr.cbSize = sizeof(docPropHdr);
  161. docPropHdr.hPrinter = hPrinter;
  162. docPropHdr.pszPrinterName = pPrinterName;
  163. docPropHdr.pdmIn = pdmInput;
  164. docPropHdr.pdmOut = pdmOutput;
  165. docPropHdr.fMode = fMode;
  166. //
  167. // Don't need to get compstui involved when the dialog is not displayed
  168. //
  169. if ((fMode & DM_PROMPT) == 0)
  170. return SimpleDocumentProperties(&docPropHdr);
  171. CallCompstui(hwnd, DrvDocumentPropertySheets, (LPARAM) &docPropHdr, &result);
  172. return result;
  173. }
  174. LONG
  175. DrvDocumentProperties(
  176. HWND hwnd,
  177. HANDLE hPrinter,
  178. LPTSTR pPrinterName,
  179. PDEVMODE pdmOutput,
  180. PDEVMODE pdmInput,
  181. DWORD fMode
  182. )
  183. /*++
  184. Routine Description:
  185. Set the public members of a DEVMODE structure for a print document
  186. [Note:]
  187. Please refer to WinNT DDK/SDK documentation for more details.
  188. This is the old entry point for the spooler. Even though
  189. no one should be using this, do it for compatibility.
  190. --*/
  191. {
  192. LONG result;
  193. Verbose(("Entering DrvDocumentProperties: fMode = %x...\n", fMode));
  194. //
  195. // Check if caller is asking querying for size
  196. //
  197. if (fMode == 0 || pdmOutput == NULL)
  198. return sizeof(DRVDEVMODE);
  199. //
  200. // Call the common routine shared with DrvAdvancedDocumentProperties
  201. //
  202. result = DoDocumentProperties(hwnd, hPrinter, pPrinterName, pdmOutput, pdmInput, fMode);
  203. return (result > 0) ? IDOK : (result == 0) ? IDCANCEL : result;
  204. }
  205. LONG
  206. DrvAdvancedDocumentProperties(
  207. HWND hwnd,
  208. HANDLE hPrinter,
  209. LPTSTR pPrinterName,
  210. PDEVMODE pdmOutput,
  211. PDEVMODE pdmInput
  212. )
  213. /*++
  214. Routine Description:
  215. Set the private members of a DEVMODE structure.
  216. In this release, this function is almost identical to
  217. DrvDocumentProperties above with a few minor exceptions
  218. [Note:]
  219. Please refer to WinNT DDK/SDK documentation for more details.
  220. This is the old entry point for the spooler. Even though
  221. no one should be using this, do it for compatibility.
  222. --*/
  223. {
  224. Verbose(("Entering DrvAdvancedDocumentProperties...\n"));
  225. //
  226. // Return the number of bytes required if pdmOutput is NULL
  227. //
  228. if (pdmOutput == NULL)
  229. return sizeof(DRVDEVMODE);
  230. //
  231. // Otherwise, call the common routine shared with DrvDocumentProperties
  232. //
  233. return DoDocumentProperties(hwnd,
  234. hPrinter,
  235. pPrinterName,
  236. pdmOutput,
  237. pdmInput,
  238. DM_COPY|DM_PROMPT|DM_ADVANCED) > 0;
  239. }
  240. BOOL
  241. DrvConvertDevMode(
  242. LPTSTR pPrinterName,
  243. PDEVMODE pdmIn,
  244. PDEVMODE pdmOut,
  245. PLONG pcbNeeded,
  246. DWORD fMode
  247. )
  248. /*++
  249. Routine Description:
  250. Use by SetPrinter and GetPrinter to convert devmodes
  251. Arguments:
  252. pPrinterName - Points to printer name string
  253. pdmIn - Points to the input devmode
  254. pdmOut - Points to the output devmode buffer
  255. pcbNeeded - Specifies the size of output buffer on input
  256. On output, this is the size of output devmode
  257. fMode - Specifies what function to perform
  258. Return Value:
  259. TRUE if successful
  260. FALSE otherwise and an error code is logged
  261. --*/
  262. {
  263. static DRIVER_VERSION_INFO versionInfo = {
  264. // Current driver version number and private devmode size
  265. DRIVER_VERSION, sizeof(DMPRIVATE),
  266. // 3.51 driver version number and private devmode size
  267. // NOTE: We don't have a 3.51 driver - use current version number and devmode size.
  268. DRIVER_VERSION, sizeof(DMPRIVATE)
  269. };
  270. INT result;
  271. HANDLE hPrinter;
  272. Verbose(("Entering DrvConvertDevMode: %x...\n", fMode));
  273. //
  274. // Call a library routine to handle the common cases
  275. //
  276. result = CommonDrvConvertDevmode(pPrinterName, pdmIn, pdmOut, pcbNeeded, fMode, &versionInfo);
  277. //
  278. // If not handled by the library routine, we only need to worry
  279. // about the case when fMode is CDM_DRIVER_DEFAULT
  280. //
  281. if (result == CDM_RESULT_NOT_HANDLED && fMode == CDM_DRIVER_DEFAULT) {
  282. //
  283. // Return driver default devmode
  284. //
  285. if (OpenPrinter(pPrinterName, &hPrinter, NULL)) {
  286. PDRVDEVMODE pdmDefault = (PDRVDEVMODE) pdmOut;
  287. DriverDefaultDevmode(pdmDefault, pPrinterName, hPrinter);
  288. pdmDefault->dmPrivate.flags |= FAXDM_DRIVER_DEFAULT;
  289. result = CDM_RESULT_TRUE;
  290. ClosePrinter(hPrinter);
  291. } else
  292. Error(("OpenPrinter failed: %d\n", GetLastError()));
  293. }
  294. return (result == CDM_RESULT_TRUE);
  295. }
  296. LONG
  297. SimpleDocumentProperties(
  298. PDOCUMENTPROPERTYHEADER pDPHdr
  299. )
  300. /*++
  301. Routine Description:
  302. Handle simple "Document Properties" where we don't need to display
  303. a dialog and therefore don't have to have common UI library involved
  304. Arguments:
  305. pDPHdr - Points to a DOCUMENTPROPERTYHEADER structure
  306. Return Value:
  307. > 0 if successful, <= 0 otherwise
  308. --*/
  309. {
  310. PUIDATA pUiData;
  311. //
  312. // Check if the caller is interested in the size only
  313. //
  314. pDPHdr->cbOut = sizeof(DRVDEVMODE);
  315. if (pDPHdr->fMode == 0 || pDPHdr->pdmOut == NULL)
  316. return pDPHdr->cbOut;
  317. //
  318. // Create a UIDATA structure
  319. //
  320. if (! (pUiData = FillUiData(pDPHdr->hPrinter, pDPHdr->pdmIn)))
  321. return -1;
  322. //
  323. // Copy the devmode back into the output buffer provided by the caller
  324. // Always return the smaller of current and input devmode
  325. //
  326. if (pDPHdr->fMode & (DM_COPY | DM_UPDATE))
  327. ConvertDevmodeOut((PDEVMODE) &pUiData->devmode, pDPHdr->pdmIn, pDPHdr->pdmOut);
  328. HeapDestroy(pUiData->hheap);
  329. return 1;
  330. }
  331. BOOL
  332. AddDocPropPages(
  333. PUIDATA pUiData,
  334. LPTSTR pPrinterName
  335. )
  336. /*++
  337. Routine Description:
  338. Add our "Document Properties" pages to the property sheet
  339. Arguments:
  340. pUiData - Points to our UIDATA structure
  341. pPrinterName - Specifies the printer name
  342. Return Value:
  343. TRUE if successful, FALSE otherwise
  344. --*/
  345. {
  346. PROPSHEETPAGE psp;
  347. //
  348. // "Document Properties" dialog only has one tab - "Fax Options"
  349. //
  350. memset(&psp, 0, sizeof(psp));
  351. psp.dwSize = sizeof(PROPSHEETPAGE);
  352. psp.dwFlags = 0;
  353. psp.hInstance = ghInstance;
  354. if (pUiData->configDefault) {
  355. psp.lParam = 0;
  356. psp.pszTemplate = MAKEINTRESOURCE(IDD_USER_INFO);
  357. psp.pfnDlgProc = UserInfoDlgProc;
  358. } else {
  359. psp.lParam = (LPARAM) pUiData;
  360. psp.pszTemplate = MAKEINTRESOURCE(IDD_DOCPROP);
  361. psp.pfnDlgProc = FaxOptionsProc;
  362. }
  363. pUiData->hFaxOptsPage = (HANDLE)
  364. pUiData->pfnComPropSheet(pUiData->hComPropSheet,
  365. CPSFUNC_ADD_PROPSHEETPAGE,
  366. (LPARAM) &psp,
  367. 0);
  368. return (pUiData->hFaxOptsPage != NULL);
  369. }
  370. BOOL
  371. GenerateFormsList(
  372. PUIDATA pUiData
  373. )
  374. /*++
  375. Routine Description:
  376. Generate the list of forms supported by the fax driver
  377. Arguments:
  378. pUiData - Points to our UIDATA structure
  379. Return Value:
  380. TRUE if successful, FALSE if there is an error
  381. --*/
  382. {
  383. PFORM_INFO_1 pFormsDB;
  384. DWORD cForms, count;
  385. //
  386. // Get a list of forms in the forms database
  387. //
  388. pFormsDB = GetFormsDatabase(pUiData->hPrinter, &cForms);
  389. if (pFormsDB == NULL || cForms == 0) {
  390. Error(("Couldn't get system forms\n"));
  391. return FALSE;
  392. }
  393. //
  394. // Enumerate the list of supported forms
  395. //
  396. pUiData->cForms = count = EnumPaperSizes(NULL, pFormsDB, cForms, DC_PAPERS);
  397. Assert(count != GDI_ERROR);
  398. pUiData->pFormNames = HeapAlloc(pUiData->hheap, 0, sizeof(TCHAR) * count * CCHPAPERNAME);
  399. pUiData->pPapers = HeapAlloc(pUiData->hheap, 0, sizeof(WORD) * count);
  400. if (!pUiData->pFormNames || !pUiData->pPapers) {
  401. MemFree(pFormsDB);
  402. return FALSE;
  403. }
  404. EnumPaperSizes(pUiData->pFormNames, pFormsDB, cForms, DC_PAPERNAMES);
  405. EnumPaperSizes(pUiData->pPapers, pFormsDB, cForms, DC_PAPERS);
  406. MemFree(pFormsDB);
  407. return TRUE;
  408. }
  409. LPTSTR
  410. GetHelpFilename(
  411. PUIDATA pUiData
  412. )
  413. /*++
  414. Routine Description:
  415. Return the driver's help filename string
  416. Arguments:
  417. pUiData - Points to our UIDATA structure
  418. Return Value:
  419. Pointer to the driver help filename, NULL if error
  420. --*/
  421. {
  422. PDRIVER_INFO_3 pDriverInfo3 = NULL;
  423. PVOID pHelpFile = NULL;
  424. //
  425. // Attempt to get help file name using the new DRIVER_INFO_3
  426. //
  427. if (pDriverInfo3 = MyGetPrinterDriver(pUiData->hPrinter, 3)) {
  428. if ((pDriverInfo3->pHelpFile != NULL) &&
  429. (pHelpFile = HeapAlloc(pUiData->hheap, 0, SizeOfString(pDriverInfo3->pHelpFile))))
  430. {
  431. _tcscpy(pHelpFile, pDriverInfo3->pHelpFile);
  432. }
  433. MemFree(pDriverInfo3);
  434. }
  435. //
  436. // If DRIVER_INFO_3 isn't supported, get help file name the old fashion way
  437. //
  438. if (pHelpFile == NULL) {
  439. if (!(pHelpFile = HeapAlloc(pUiData->hheap, 0, SizeOfString(FAXCFG_HELP_FILENAME))) )
  440. {
  441. pHelpFile = NULL;
  442. } else {
  443. _tcscpy(pHelpFile, FAXCFG_HELP_FILENAME);
  444. }
  445. }
  446. Verbose(("Driver help filename: %ws\n", pHelpFile));
  447. return (pUiData->pHelpFile = pHelpFile);
  448. }