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.

1075 lines
33 KiB

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright 1997 - 2003 Microsoft Corporation. All Rights Reserved.
  7. //
  8. // FILE: OEMUI.cpp
  9. //
  10. //
  11. // PURPOSE: Main file for OEM UI test module.
  12. //
  13. //
  14. // Functions:
  15. //
  16. //
  17. //
  18. //
  19. // PLATFORMS: Windows 2000, Windows XP, Windows Server 2003
  20. //
  21. //
  22. #include "precomp.h"
  23. #include "resource.h"
  24. #include "debug.h"
  25. #include "oemui.h"
  26. // StrSafe.h needs to be included last
  27. // to disallow bad string functions.
  28. #include <STRSAFE.H>
  29. ////////////////////////////////////////////////////////
  30. // INTERNAL MACROS and DEFINES
  31. ////////////////////////////////////////////////////////
  32. typedef struct _tagCBUserData
  33. {
  34. HANDLE hComPropSheet;
  35. HANDLE hPropPage;
  36. POEMUIPSPARAM pOEMUIParam;
  37. PFNCOMPROPSHEET pfnComPropSheet;
  38. } CBUSERDATA, *PCBUSERDATA;
  39. ////////////////////////////////////////////////////////
  40. // INTERNAL PROTOTYPES
  41. ////////////////////////////////////////////////////////
  42. static HRESULT hrDocumentPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam);
  43. static HRESULT hrPrinterPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam);
  44. LONG APIENTRY OEMPrinterUICallBack(PCPSUICBPARAM pCallbackParam, POEMCUIPPARAM pOEMUIParam);
  45. LONG APIENTRY OEMDocUICallBack(PCPSUICBPARAM pCallbackParam, POEMCUIPPARAM pOEMUIParam);
  46. LONG APIENTRY OEMDocUICallBack2(PCPSUICBPARAM pCallbackParam);
  47. INT_PTR CALLBACK DevicePropPageProc(HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
  48. void SetOEMUiState (HWND hDlg, POEMSHEETDATA pOEMSheetData);
  49. void SetOEMCommonDataIntoOptItem (POEMSHEETDATA pOEMSheetData, PSTR PName, LONG Sel);
  50. void ChangeOpItem (IPrintOemDriverUI *pIPrintOEMDrvUI, POEMUIOBJ pOEMObj, POPTITEM pOptItem, int iSel);
  51. POPTITEM FindDrvOptItem (POPTITEM pDrvOptItems, DWORD dwItemCount, PSTR pKeyWordName, BYTE dmPubID = DMPUB_NONE);
  52. static POPTITEM CreateOptItems(HANDLE hHeap, DWORD dwOptItems);
  53. static void InitOptItems(POPTITEM pOptItems, DWORD dwOptItems);
  54. static POPTTYPE CreateOptType(HANDLE hHeap, WORD wOptParams);
  55. static PTSTR GetStringResource(HANDLE hHeap, HANDLE hModule, UINT uResource);
  56. ////////////////////////////////////////////////////////////////////////////////
  57. //
  58. // Initializes OptItems to display OEM device or document property UI.
  59. // Called via IOemUI::CommonUIProp
  60. //
  61. HRESULT hrOEMPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam)
  62. {
  63. HRESULT hResult = S_OK;
  64. VERBOSE(DLLTEXT("hrOEMPropertyPage(%d) entry.\r\n"), dwMode);
  65. // Validate parameters.
  66. if( (OEMCUIP_DOCPROP != dwMode)
  67. &&
  68. (OEMCUIP_PRNPROP != dwMode)
  69. )
  70. {
  71. ERR(ERRORTEXT("hrOEMPropertyPage() ERROR_INVALID_PARAMETER.\r\n"));
  72. VERBOSE(DLLTEXT("\tdwMode = %d, pOEMUIParam = %#lx.\r\n"), dwMode, pOEMUIParam);
  73. // Return invalid parameter error.
  74. SetLastError(ERROR_INVALID_PARAMETER);
  75. return E_FAIL;
  76. }
  77. switch(dwMode)
  78. {
  79. case OEMCUIP_DOCPROP:
  80. hResult = hrDocumentPropertyPage(dwMode, pOEMUIParam);
  81. break;
  82. case OEMCUIP_PRNPROP:
  83. hResult = hrPrinterPropertyPage(dwMode, pOEMUIParam);
  84. break;
  85. default:
  86. // Should never reach this!
  87. ERR(ERRORTEXT("hrOEMPropertyPage() Invalid dwMode, %d"), dwMode);
  88. SetLastError(ERROR_INVALID_PARAMETER);
  89. hResult = E_FAIL;
  90. break;
  91. }
  92. return hResult;
  93. }
  94. ////////////////////////////////////////////////////////////////////////////////
  95. //
  96. // Initializes OptItems to display OEM document property UI.
  97. //
  98. static HRESULT hrDocumentPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam)
  99. {
  100. if(NULL == pOEMUIParam->pOEMOptItems)
  101. {
  102. // Fill in the number of OptItems to create for OEM document property UI.
  103. pOEMUIParam->cOEMOptItems = 1;
  104. VERBOSE(DLLTEXT("hrDocumentPropertyPage() requesting %d number of items.\r\n"), pOEMUIParam->cOEMOptItems);
  105. }
  106. else
  107. {
  108. POEMDEV pOEMDev = (POEMDEV) pOEMUIParam->pOEMDM;
  109. VERBOSE(DLLTEXT("hrDocumentPropertyPage() fill out %d items.\r\n"), pOEMUIParam->cOEMOptItems);
  110. // Init UI Callback reference.
  111. pOEMUIParam->OEMCUIPCallback = OEMDocUICallBack;
  112. // Init OEMOptItmes.
  113. InitOptItems(pOEMUIParam->pOEMOptItems, pOEMUIParam->cOEMOptItems);
  114. // Fill out tree view items.
  115. // New section.
  116. pOEMUIParam->pOEMOptItems[0].Level = 1;
  117. pOEMUIParam->pOEMOptItems[0].Flags = OPTIF_COLLAPSE;
  118. pOEMUIParam->pOEMOptItems[0].pName = GetStringResource(pOEMUIParam->hOEMHeap, pOEMUIParam->hModule, IDS_ADV_SECTION);
  119. pOEMUIParam->pOEMOptItems[0].Sel = pOEMDev->dwAdvancedData;
  120. pOEMUIParam->pOEMOptItems[0].pOptType = CreateOptType(pOEMUIParam->hOEMHeap, 2);
  121. //
  122. //Setup the Optional Item
  123. //
  124. pOEMUIParam->pOEMOptItems[0].pOptType->Type = TVOT_UDARROW;
  125. pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].IconID = 0;
  126. pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].lParam = 100;
  127. }
  128. return S_OK;
  129. }
  130. ////////////////////////////////////////////////////////////////////////////////
  131. //
  132. // Initializes OptItems to display OEM printer property UI.
  133. //
  134. static HRESULT hrPrinterPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam)
  135. {
  136. //
  137. //This is null the first time the interface is called.
  138. //
  139. if(NULL == pOEMUIParam->pOEMOptItems)
  140. {
  141. // Fill in the number of OptItems to create for OEM printer property UI.
  142. pOEMUIParam->cOEMOptItems = 1;
  143. VERBOSE(DLLTEXT("hrPrinterPropertyPage() requesting %d number of items.\r\n"), pOEMUIParam->cOEMOptItems);
  144. }
  145. else
  146. {
  147. //
  148. //This is the second time we are called Now setup the optional items.
  149. //
  150. DWORD dwError;
  151. DWORD dwDeviceValue;
  152. DWORD dwType;
  153. DWORD dwNeeded;
  154. VERBOSE(DLLTEXT("hrPrinterPropertyPage() fill out %d items.\r\n"), pOEMUIParam->cOEMOptItems);
  155. //
  156. //Add OEM Optitem to the Device
  157. //
  158. // Get device settings value from printer.
  159. dwError = GetPrinterData(pOEMUIParam->hPrinter, OEMUI_VALUE, &dwType, (PBYTE) &dwDeviceValue,
  160. sizeof(dwDeviceValue), &dwNeeded);
  161. if( (ERROR_SUCCESS != dwError)
  162. ||
  163. (dwDeviceValue > 100)
  164. )
  165. {
  166. // Failed to get the device value or value is invalid, just use the default.
  167. dwDeviceValue = 0;
  168. }
  169. // Init UI Callback reference.
  170. pOEMUIParam->OEMCUIPCallback = OEMPrinterUICallBack;
  171. // Init OEMOptItmes.
  172. InitOptItems(pOEMUIParam->pOEMOptItems, pOEMUIParam->cOEMOptItems);
  173. // Fill out tree view items.
  174. // New section.
  175. pOEMUIParam->pOEMOptItems[0].Level = 1;
  176. pOEMUIParam->pOEMOptItems[0].Flags = OPTIF_COLLAPSE;
  177. pOEMUIParam->pOEMOptItems[0].pName = GetStringResource(pOEMUIParam->hOEMHeap, pOEMUIParam->hModule, IDS_DEV_SECTION);
  178. pOEMUIParam->pOEMOptItems[0].Sel = dwDeviceValue;
  179. pOEMUIParam->pOEMOptItems[0].pOptType = CreateOptType(pOEMUIParam->hOEMHeap, 2);
  180. //
  181. //Setup the Optional Item
  182. //
  183. pOEMUIParam->pOEMOptItems[0].pOptType->Type = TVOT_UDARROW;
  184. pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].IconID = 0;
  185. pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].lParam = 100;
  186. }
  187. return S_OK;
  188. }
  189. ////////////////////////////////////////////////////////////////////////////////
  190. //
  191. // Adds property page to Document property sheet. Called via IOemUI::DocumentPropertySheets
  192. //
  193. HRESULT hrOEMDocumentPropertySheets(PPROPSHEETUI_INFO pPSUIInfo, LPARAM lParam,
  194. IPrintOemDriverUI* pOEMHelp)
  195. {
  196. LONG_PTR lResult;
  197. VERBOSE(DLLTEXT("OEMDocumentPropertySheets() entry.\r\n"));
  198. // Validate parameters.
  199. if( (NULL == pPSUIInfo)
  200. ||
  201. (PROPSHEETUI_INFO_VERSION != pPSUIInfo->Version)
  202. )
  203. {
  204. ERR(ERRORTEXT("OEMDocumentPropertySheets() ERROR_INVALID_PARAMETER.\r\n"));
  205. // Return invalid parameter error.
  206. SetLastError(ERROR_INVALID_PARAMETER);
  207. return E_FAIL;
  208. }
  209. // Do action.
  210. switch(pPSUIInfo->Reason)
  211. {
  212. case PROPSHEETUI_REASON_INIT:
  213. {
  214. DWORD dwSheets = 0;
  215. PCBUSERDATA pUserData;
  216. POEMUIPSPARAM pOEMUIParam = (POEMUIPSPARAM) pPSUIInfo->lParamInit;
  217. HANDLE hHeap = pOEMUIParam->hOEMHeap;
  218. POEMDEV pOEMDev = (POEMDEV) pOEMUIParam->pOEMDM;
  219. COMPROPSHEETUI Sheet;
  220. // Init property page.
  221. memset(&Sheet, 0, sizeof(COMPROPSHEETUI));
  222. Sheet.cbSize = sizeof(COMPROPSHEETUI);
  223. Sheet.Flags = CPSUIF_UPDATE_PERMISSION;
  224. Sheet.hInstCaller = ghInstance;
  225. Sheet.pCallerName = GetStringResource(hHeap, ghInstance, IDS_NAME);
  226. Sheet.pHelpFile = NULL;
  227. Sheet.pfnCallBack = OEMDocUICallBack2;
  228. Sheet.pDlgPage = CPSUI_PDLGPAGE_TREEVIEWONLY;
  229. Sheet.cOptItem = 1;
  230. Sheet.IconID = IDI_CPSUI_PRINTER;
  231. Sheet.pOptItemName = GetStringResource(hHeap, ghInstance, IDS_SECTION);
  232. Sheet.CallerVersion = 0x100;
  233. Sheet.OptItemVersion = 0x100;
  234. // Init user data.
  235. pUserData = (PCBUSERDATA) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(CBUSERDATA));
  236. pUserData->hComPropSheet = pPSUIInfo->hComPropSheet;
  237. pUserData->pfnComPropSheet = pPSUIInfo->pfnComPropSheet;
  238. pUserData->pOEMUIParam = pOEMUIParam;
  239. Sheet.UserData = (ULONG_PTR) pUserData;
  240. // Create OptItems for page.
  241. Sheet.pOptItem = CreateOptItems(hHeap, Sheet.cOptItem);
  242. // Initialize OptItems
  243. Sheet.pOptItem[0].Level = 1;
  244. Sheet.pOptItem[0].Flags = OPTIF_COLLAPSE;
  245. Sheet.pOptItem[0].pName = GetStringResource(hHeap, ghInstance, IDS_SECTION);
  246. Sheet.pOptItem[0].Sel = pOEMDev->dwDriverData;
  247. Sheet.pOptItem[0].pOptType = CreateOptType(hHeap, 2);
  248. //
  249. //Set the UI prop of this OPTYPE item.
  250. //
  251. Sheet.pOptItem[0].pOptType->Type = TVOT_UDARROW;
  252. Sheet.pOptItem[0].pOptType->pOptParam[1].IconID = 0;
  253. Sheet.pOptItem[0].pOptType->pOptParam[1].lParam = 100;
  254. // Adds the property sheets.
  255. lResult = pPSUIInfo->pfnComPropSheet(pPSUIInfo->hComPropSheet, CPSFUNC_ADD_PCOMPROPSHEETUI,
  256. (LPARAM)&Sheet, (LPARAM)&dwSheets);
  257. }
  258. break;
  259. case PROPSHEETUI_REASON_GET_INFO_HEADER:
  260. {
  261. PPROPSHEETUI_INFO_HEADER pHeader = (PPROPSHEETUI_INFO_HEADER) lParam;
  262. pHeader->pTitle = (LPTSTR)PROP_TITLE;
  263. lResult = TRUE;
  264. }
  265. break;
  266. case PROPSHEETUI_REASON_GET_ICON:
  267. // No icon
  268. lResult = 0;
  269. break;
  270. case PROPSHEETUI_REASON_SET_RESULT:
  271. {
  272. PSETRESULT_INFO pInfo = (PSETRESULT_INFO) lParam;
  273. lResult = pInfo->Result;
  274. }
  275. break;
  276. case PROPSHEETUI_REASON_DESTROY:
  277. lResult = TRUE;
  278. break;
  279. }
  280. pPSUIInfo->Result = lResult;
  281. return S_OK;
  282. }
  283. ////////////////////////////////////////////////////////////////////////////////
  284. //
  285. // Adds property page to printer property sheet. Called via IOemUI::DevicePropertySheets
  286. //
  287. HRESULT hrOEMDevicePropertySheets(PPROPSHEETUI_INFO pPSUIInfo, LPARAM lParam, POEMSHEETDATA pOemSheetData)
  288. {
  289. LONG_PTR lResult;
  290. VERBOSE(DLLTEXT("hrOEMDevicePropertySheets(%#x, %#x) entry\r\n"), pPSUIInfo, lParam);
  291. // Validate parameters.
  292. if( (NULL == pPSUIInfo)
  293. ||
  294. (PROPSHEETUI_INFO_VERSION != pPSUIInfo->Version)
  295. )
  296. {
  297. ERR(ERRORTEXT("hrOEMDevicePropertySheets() ERROR_INVALID_PARAMETER.\r\n"));
  298. // Return invalid parameter error.
  299. SetLastError(ERROR_INVALID_PARAMETER);
  300. return E_FAIL;
  301. }
  302. Dump(pPSUIInfo);
  303. // Do action.
  304. switch(pPSUIInfo->Reason)
  305. {
  306. case PROPSHEETUI_REASON_INIT:
  307. {
  308. PROPSHEETPAGE Page;
  309. // Init property page.
  310. memset(&Page, 0, sizeof(PROPSHEETPAGE));
  311. Page.dwSize = sizeof(PROPSHEETPAGE);
  312. Page.dwFlags = PSP_DEFAULT;
  313. Page.hInstance = ghInstance;
  314. Page.pszTemplate = MAKEINTRESOURCE(IDD_DEVICE_PROPPAGE);
  315. Page.pfnDlgProc = DevicePropPageProc;
  316. //
  317. //This is the OEMPlugIN Sheets Shared Data. Use this Pointer to gain access to shared driver data
  318. //
  319. pOemSheetData->hComPropSheet = pPSUIInfo->hComPropSheet;
  320. pOemSheetData->pfnComPropSheet = pPSUIInfo->pfnComPropSheet;
  321. Page.lParam = (LPARAM)pOemSheetData;
  322. // Add property sheets.
  323. pOemSheetData->hmyPlugin = (HANDLE)(pPSUIInfo->pfnComPropSheet(pPSUIInfo->hComPropSheet, CPSFUNC_ADD_PROPSHEETPAGE, (LPARAM)&Page, 0));
  324. VERBOSE(DLLTEXT("hrOEMDevicePropertySheets() pfnComPropSheet returned %d.\r\n"), pOemSheetData->hmyPlugin);
  325. }
  326. break;
  327. case PROPSHEETUI_REASON_GET_INFO_HEADER:
  328. {
  329. PPROPSHEETUI_INFO_HEADER pHeader = (PPROPSHEETUI_INFO_HEADER) lParam;
  330. pHeader->pTitle = (LPTSTR)PROP_TITLE;
  331. lResult = TRUE;
  332. }
  333. break;
  334. case PROPSHEETUI_REASON_GET_ICON:
  335. // No icon
  336. lResult = 0;
  337. break;
  338. case PROPSHEETUI_REASON_SET_RESULT:
  339. {
  340. PSETRESULT_INFO pInfo = (PSETRESULT_INFO) lParam;
  341. lResult = pInfo->Result;
  342. }
  343. break;
  344. case PROPSHEETUI_REASON_DESTROY:
  345. lResult = TRUE;
  346. break;
  347. }
  348. pPSUIInfo->Result = lResult;
  349. return S_OK;
  350. }
  351. ////////////////////////////////////////////////////////////////////////////////
  352. //
  353. // OptItems call back for OEM printer property UI.
  354. //
  355. LONG APIENTRY OEMPrinterUICallBack(PCPSUICBPARAM pCallbackParam, POEMCUIPPARAM pOEMUIParam)
  356. {
  357. LONG lReturn = CPSUICB_ACTION_NONE;
  358. POEMDEV pOEMDev = (POEMDEV) pOEMUIParam->pOEMDM;
  359. VERBOSE(DLLTEXT("OEMPrinterUICallBack() entry, Reason is %d.\r\n"), pCallbackParam->Reason);
  360. switch(pCallbackParam->Reason)
  361. {
  362. case CPSUICB_REASON_APPLYNOW:
  363. {
  364. DWORD dwDriverValue = pOEMUIParam->pOEMOptItems[0].Sel;
  365. //
  366. // Store OptItems state in printer data.
  367. //
  368. SetPrinterData(pOEMUIParam->hPrinter, OEMUI_VALUE, REG_DWORD, (PBYTE) &dwDriverValue, sizeof(DWORD));
  369. }
  370. break;
  371. //
  372. //Because the plugin page is changing items in this CPSUI page we need to rinitalise the data on the page.
  373. //
  374. case CPSUICB_REASON_SETACTIVE:
  375. return CPSUICB_ACTION_OPTIF_CHANGED;
  376. break;
  377. default:
  378. break;
  379. }
  380. return lReturn;
  381. }
  382. ////////////////////////////////////////////////////////////////////////////////
  383. //
  384. // Call back for OEM device property UI.
  385. //
  386. // This OEM plugin page is using the OPTITEMS in the Device tab to store data. (Installabale Options)
  387. // If you hide these option in the device tab and only access them from your UI you dont have to worry about sync the views.
  388. // If you want the Options in both tabs you need to have a CPSUICALLBACK function defined for the Device tab. (OEMPrinterUICallBack)
  389. // OEMPrinterUICallBack will return CPSUICB_ACTION_OPTIF_CHANGED; to indicate that some of the controls have change. Resulting in CPSUI to refresh the view.
  390. //
  391. INT_PTR CALLBACK DevicePropPageProc(HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  392. {
  393. VERBOSE(DLLTEXT("DevicePropPageProc() entry, Reason is %d.\r\n"), uiMsg);
  394. POEMSHEETDATA pOEMSheetData = NULL;
  395. LONG lState = 0;
  396. DWORD fDataValid = 0;
  397. WORD dlgControl = 0;
  398. PSTR pControlName = NULL;
  399. if ( uiMsg != WM_INITDIALOG )
  400. {
  401. //
  402. //Retrieves Application data storded by the call to SetWindowLongPtr.
  403. //
  404. pOEMSheetData = (POEMSHEETDATA)GetWindowLongPtr( hDlg, DWLP_USER);
  405. if (!pOEMSheetData)
  406. {
  407. //
  408. //Failed to get the OEM Prop Page Data Pointer.
  409. //
  410. ERR(ERRORTEXT("DevicePropPageProc : GetWindowLongPtr Failed (%d)\r\n"), GetLastError());
  411. return FALSE;
  412. }
  413. }
  414. switch (uiMsg)
  415. {
  416. case WM_INITDIALOG:
  417. //
  418. //PROPSHEETPAGE structure is passed to the dialog box procedure with a WM_INITDIALOG message.
  419. //The lParam member is provided to allow you to pass application-specific information to the dialog box procedure
  420. //
  421. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR)((LPPROPSHEETPAGE)lParam)->lParam);
  422. break;
  423. case WM_COMMAND:
  424. switch(HIWORD(wParam))
  425. {
  426. case BN_CLICKED:
  427. //
  428. //Change the UI to activate the apply button Send the prop dailog a change message.
  429. //
  430. PropSheet_Changed(GetParent(hDlg), hDlg);
  431. switch(LOWORD(wParam))
  432. {
  433. //
  434. //USER modified OEM Controls on the plugin page.
  435. //
  436. case IDC_CHECK_DUPLPEX:
  437. dlgControl = IDC_CHECK_DUPLPEX;
  438. fDataValid = TRUE;
  439. pControlName = (PSTR)DUPLEXUNIT;
  440. break;
  441. case IDC_CHECK_HDRIVE:
  442. dlgControl = IDC_CHECK_HDRIVE;
  443. fDataValid = TRUE;
  444. pControlName = (PSTR)PRINTERHDISK;
  445. break;
  446. case IDC_CHECK_ENVFEEDER:
  447. dlgControl = IDC_CHECK_ENVFEEDER;
  448. fDataValid = TRUE;
  449. pControlName = (PSTR)ENVFEEDER;
  450. break;
  451. default:
  452. fDataValid = 0;
  453. break;
  454. }
  455. //
  456. //If the Control is valid Get the ctrl state and UPdate the OPTITEM.
  457. //
  458. if ( fDataValid )
  459. {
  460. lState = (LONG)(SendDlgItemMessage (hDlg, dlgControl, BM_GETSTATE, 0, 0) & 0x0003);
  461. VERBOSE(DLLTEXT("DevicePropPageProc : Clicked dlgControl (%d)\r\n"), lState);
  462. //
  463. //Saves the Data to the OPTITEMS in the device settings page.
  464. //
  465. SetOEMCommonDataIntoOptItem (pOEMSheetData, pControlName, lState);
  466. }
  467. break;
  468. default:
  469. return FALSE;
  470. }
  471. return TRUE;
  472. //
  473. //Dailog is going to paint set up the UI controls to match the relavent OPTITEMS Data.
  474. //
  475. case WM_CTLCOLORDLG:
  476. {
  477. VERBOSE(DLLTEXT("DevicePropPageProc : WM_CTLCOLORDLG \r\n"));
  478. SetOEMUiState (hDlg, pOEMSheetData);
  479. }
  480. return TRUE;
  481. case WM_NOTIFY:
  482. {
  483. switch (((LPNMHDR)lParam)->code) // type of notification message
  484. {
  485. case PSN_SETACTIVE:
  486. return TRUE;
  487. break;
  488. case PSN_KILLACTIVE:
  489. return TRUE;
  490. break;
  491. case PSN_APPLY:
  492. //
  493. //Calls ComPropSheet
  494. //causes the ComPropSheet function to pass a specified result value to all PFNPROPSHEETUI-typed functions associated with a specified page and its parents
  495. //
  496. pOEMSheetData->pfnComPropSheet(pOEMSheetData->hComPropSheet,
  497. CPSFUNC_SET_RESULT,
  498. (LPARAM) pOEMSheetData->hmyPlugin,
  499. (LPARAM)CPSUI_OK);
  500. //
  501. //Accept the apply if the data was invalid and you are checking for this set PSNRET_INVALID | PSNRET_INVALID_NOCHANGEPAGE
  502. //Disables the APPLY button and saves the Data.
  503. //
  504. PropSheet_UnChanged(GetParent(hDlg), hDlg);
  505. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,PSNRET_NOERROR);
  506. return TRUE;
  507. break;
  508. //
  509. // Need To undo the changes
  510. //
  511. case PSN_RESET:
  512. break;
  513. }
  514. }
  515. break;
  516. }
  517. return FALSE;
  518. }
  519. ////////////////////////////////////////////////////////////////////////////////
  520. //
  521. // Update the OEM page controls to match the Device settings page
  522. //
  523. void SetOEMUiState (HWND hDlg, POEMSHEETDATA pOEMSheetData)
  524. {
  525. LRESULT lstate = 0;
  526. POEMCUIPPARAM pOEMCUIParam = NULL;
  527. PUSERDATA pUserData = NULL;
  528. POPTITEM pOptItem = NULL;
  529. DWORD cDrvOptItems = 0;
  530. if (pOEMSheetData->pOEMCUIParam)
  531. {
  532. pOEMCUIParam = pOEMSheetData->pOEMCUIParam;
  533. cDrvOptItems = pOEMCUIParam->cDrvOptItems;
  534. }
  535. //
  536. //loop down the OPITEMS and retrieve the data that is needed from the control
  537. //(all Optitesm are ref from DMPubID of the UserData->pKeyWordName)
  538. //
  539. for (DWORD i=0; i < cDrvOptItems; i++)
  540. {
  541. pOptItem = &(pOEMCUIParam->pDrvOptItems[i]);
  542. if (pOptItem->UserData)
  543. {
  544. pUserData = (PUSERDATA)(pOptItem->UserData);
  545. if ( pUserData->pKeyWordName )
  546. {
  547. //
  548. //Get the Selection of the OPITEM
  549. //
  550. if (pOptItem->Sel)
  551. {
  552. lstate = BST_CHECKED;
  553. }
  554. else
  555. {
  556. lstate = BST_UNCHECKED;
  557. }
  558. //
  559. //Update the Data in OEM Page to mactch the data in the Device Settings TAB.
  560. //Send a message to the Cntrol to update its State.
  561. //
  562. //Set the Duplex Option
  563. if ( strcmp(pUserData->pKeyWordName, DUPLEXUNIT ) == 0 )
  564. {
  565. SendDlgItemMessage (hDlg, IDC_CHECK_DUPLPEX, BM_SETCHECK, lstate, 0);
  566. }
  567. //Set HardDrive Option
  568. if ( strcmp (pUserData->pKeyWordName, PRINTERHDISK ) == 0 )
  569. {
  570. SendDlgItemMessage (hDlg, IDC_CHECK_HDRIVE, BM_SETCHECK, lstate, 0);
  571. }
  572. //Set the Env Feeder Option
  573. if ( strcmp (pUserData->pKeyWordName, ENVFEEDER ) == 0 )
  574. {
  575. SendDlgItemMessage (hDlg, IDC_CHECK_ENVFEEDER, BM_SETCHECK, lstate, 0);
  576. }
  577. }
  578. }
  579. }
  580. }
  581. ////////////////////////////////////////////////////////////////////////////////
  582. //
  583. // Save the OEM change into the correct OPTITEM.
  584. // The UI data is been stored in the driver supplied OPTITEM
  585. //
  586. void SetOEMCommonDataIntoOptItem (POEMSHEETDATA pOEMSheetData, PSTR PName, LONG Sel)
  587. {
  588. VERBOSE(DLLTEXT("SetOEMCommonDataIntoOptItem (%S) \r\n"), PName);
  589. POEMCUIPPARAM pOEMCUIParam = pOEMSheetData->pOEMCUIParam;
  590. POPTITEM pOptItem = NULL;
  591. //
  592. //Find the OPTITEM that needs to be Updated.
  593. //
  594. pOptItem = FindDrvOptItem (pOEMCUIParam->pDrvOptItems,
  595. pOEMCUIParam->cDrvOptItems,
  596. PName,
  597. DMPUB_NONE);
  598. if (pOptItem)
  599. {
  600. ChangeOpItem (pOEMSheetData->pOEMHelp,
  601. pOEMCUIParam->poemuiobj,
  602. pOptItem,
  603. Sel);
  604. }
  605. else
  606. {
  607. ERR(ERRORTEXT("SetOEMCommonDataIntoOptItem Item Not Found OPTITEM(%S) \r\n"), PName);
  608. }
  609. }
  610. ////////////////////////////////////////////////////////////////////////////////
  611. //
  612. // Help Change the data set in the OPTITEM
  613. //
  614. void ChangeOpItem (IPrintOemDriverUI *pIPrintOEMDrvUI, POEMUIOBJ pOEMUIObj, POPTITEM pOptItem, int iSel)
  615. {
  616. HRESULT hRestult = S_OK;
  617. //
  618. //Change the Item (Change which OPTPARAM is selected fot the required OPTTYPE)
  619. //
  620. pOptItem->Sel = iSel;
  621. //
  622. //Set the Flag indicating it is changed
  623. //
  624. pOptItem->Flags |= OPTIF_CHANGED;
  625. //
  626. //Update the Driver UI. (this updates the UI but it does not cause CPSUI to update the its pages),
  627. //Look at OEMPrinterUICallBack to see how CPSUI pages are updated
  628. //The IPrintOemDriverUI::DrvUpdateUISetting method is provided by the
  629. //Unidrv and Pscript5 minidrivers so that user interface plug-ins can
  630. //notify the driver of a modified user interface option.
  631. //
  632. hRestult = pIPrintOEMDrvUI->DrvUpdateUISetting((PVOID)pOEMUIObj, (PVOID)pOptItem, 0, OEMCUIP_PRNPROP);
  633. if (hRestult != S_OK)
  634. {
  635. ERR(ERRORTEXT("ChangeOpItem DrvUpdateUISetting FAILED \r\n") );
  636. }
  637. }
  638. ////////////////////////////////////////////////////////////////////////////////
  639. //
  640. // Help Find a OPTITEM from the array based on USERDATA->pKeyWordName or DMPubID
  641. //
  642. POPTITEM FindDrvOptItem (POPTITEM pDrvOptItems, DWORD dwItemCount, PSTR pKeyWordName, BYTE dmPubID )
  643. {
  644. VERBOSE(DLLTEXT("FindDrvOptItem Looking (%S) (%d) \r\n"), pKeyWordName, dmPubID);
  645. POPTITEM pOptItem = NULL;
  646. PUSERDATA pUserData = NULL;
  647. for (DWORD i=0; i < dwItemCount; i++)
  648. {
  649. //
  650. //OPTITEM has valid data compare these now (Search on DMPubID)
  651. //
  652. if (pKeyWordName == NULL)
  653. {
  654. if (dmPubID == pDrvOptItems[i].DMPubID)
  655. {
  656. pOptItem = &(pDrvOptItems[i]);
  657. break;
  658. }
  659. }
  660. else
  661. {
  662. //
  663. //(Search a printer freature pKeyWordName)
  664. //
  665. //For Common Printer Features the key name is set to a common non localised string
  666. //Note the these are only ansi strings ie PSTR
  667. //
  668. if (pDrvOptItems[i].UserData)
  669. {
  670. pUserData = (PUSERDATA)pDrvOptItems[i].UserData;
  671. if (pUserData->pKeyWordName)
  672. {
  673. //
  674. //OPTITEM has valid data compare these now
  675. //
  676. if ( strcmp (pUserData->pKeyWordName, pKeyWordName) == 0)
  677. {
  678. pOptItem = &(pDrvOptItems[i]);
  679. break;
  680. }
  681. }
  682. }
  683. }
  684. }
  685. if (!pOptItem)
  686. {
  687. ERR(ERRORTEXT("FindDrvOptItem OPTITEM NOT Found \r\n") );
  688. }
  689. return pOptItem;
  690. }
  691. ////////////////////////////////////////////////////////////////////////////////
  692. //
  693. // OptItems call back for OEM document property UI.
  694. //
  695. LONG APIENTRY OEMDocUICallBack(PCPSUICBPARAM pCallbackParam, POEMCUIPPARAM pOEMUIParam)
  696. {
  697. LONG lReturn = CPSUICB_ACTION_NONE;
  698. POEMDEV pOEMDev = (POEMDEV) pOEMUIParam->pOEMDM;
  699. VERBOSE(DLLTEXT("OEMDocUICallBack() entry, Reason is %d.\r\n"), pCallbackParam->Reason);
  700. switch(pCallbackParam->Reason)
  701. {
  702. case CPSUICB_REASON_APPLYNOW:
  703. // Store OptItems state in DEVMODE.
  704. pOEMDev->dwAdvancedData = pOEMUIParam->pOEMOptItems[0].Sel;
  705. break;
  706. case CPSUICB_REASON_KILLACTIVE:
  707. pOEMDev->dwAdvancedData = pOEMUIParam->pOEMOptItems[0].Sel;
  708. break;
  709. //
  710. //Refress the Data in the view and tell CPUSI that the data has changed by ret CPSUICB_ACTION_OPTIF_CHANGED
  711. //
  712. case CPSUICB_REASON_SETACTIVE:
  713. if(pOEMUIParam->pOEMOptItems[0].Sel != pOEMDev->dwAdvancedData)
  714. {
  715. pOEMUIParam->pOEMOptItems[0].Sel = pOEMDev->dwAdvancedData;
  716. pOEMUIParam->pOEMOptItems[0].Flags |= OPTIF_CHANGED;
  717. lReturn = CPSUICB_ACTION_OPTIF_CHANGED;
  718. }
  719. break;
  720. default:
  721. break;
  722. }
  723. return lReturn;
  724. }
  725. LONG APIENTRY OEMDocUICallBack2(PCPSUICBPARAM pCallbackParam)
  726. {
  727. LONG lReturn = CPSUICB_ACTION_NONE;
  728. PCBUSERDATA pUserData = (PCBUSERDATA) pCallbackParam->UserData;
  729. POEMDEV pOEMDev = (POEMDEV) pUserData->pOEMUIParam->pOEMDM;
  730. VERBOSE(DLLTEXT("OEMDocUICallBack2() entry, Reason is %d.\r\n"), pCallbackParam->Reason);
  731. switch(pCallbackParam->Reason)
  732. {
  733. case CPSUICB_REASON_APPLYNOW:
  734. pOEMDev->dwDriverData = pCallbackParam->pOptItem[0].Sel;
  735. pUserData->pfnComPropSheet(pUserData->hComPropSheet, CPSFUNC_SET_RESULT,
  736. (LPARAM)pUserData->hPropPage,
  737. (LPARAM)CPSUI_OK);
  738. break;
  739. case CPSUICB_REASON_KILLACTIVE:
  740. pOEMDev->dwDriverData = pCallbackParam->pOptItem[0].Sel;
  741. break;
  742. case CPSUICB_REASON_SETACTIVE:
  743. if(pCallbackParam->pOptItem[0].Sel != pOEMDev->dwDriverData)
  744. {
  745. pCallbackParam->pOptItem[0].Sel = pOEMDev->dwDriverData;
  746. pCallbackParam->pOptItem[0].Flags |= OPTIF_CHANGED;
  747. lReturn = CPSUICB_ACTION_OPTIF_CHANGED;
  748. }
  749. break;
  750. default:
  751. break;
  752. }
  753. return lReturn;
  754. }
  755. ////////////////////////////////////////////////////////////////////////////////
  756. //
  757. // Creates and Initializes OptItems.
  758. //
  759. static POPTITEM CreateOptItems(HANDLE hHeap, DWORD dwOptItems)
  760. {
  761. POPTITEM pOptItems = NULL;
  762. // Allocate memory for OptItems;
  763. pOptItems = (POPTITEM) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(OPTITEM) * dwOptItems);
  764. if(NULL != pOptItems)
  765. {
  766. InitOptItems(pOptItems, dwOptItems);
  767. }
  768. else
  769. {
  770. ERR(ERRORTEXT("CreateOptItems() failed to allocate memory for OPTITEMs!\r\n"));
  771. }
  772. return pOptItems;
  773. }
  774. ////////////////////////////////////////////////////////////////////////////////
  775. //
  776. // Initializes OptItems.
  777. //
  778. static void InitOptItems(POPTITEM pOptItems, DWORD dwOptItems)
  779. {
  780. VERBOSE(DLLTEXT("InitOptItems() entry.\r\n"));
  781. // Zero out memory.
  782. memset(pOptItems, 0, sizeof(OPTITEM) * dwOptItems);
  783. // Set each OptItem's size, and Public DM ID.
  784. for(DWORD dwCount = 0; dwCount < dwOptItems; dwCount++)
  785. {
  786. pOptItems[dwCount].cbSize = sizeof(OPTITEM);
  787. pOptItems[dwCount].DMPubID = DMPUB_NONE;
  788. }
  789. }
  790. ////////////////////////////////////////////////////////////////////////////////
  791. //
  792. // Allocates and initializes OptType for OptItem.
  793. //
  794. static POPTTYPE CreateOptType(HANDLE hHeap, WORD wOptParams)
  795. {
  796. POPTTYPE pOptType = NULL;
  797. VERBOSE(DLLTEXT("CreateOptType() entry.\r\n"));
  798. // Allocate memory from the heap for the OPTTYPE; the driver will take care of clean up.
  799. pOptType = (POPTTYPE) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(OPTTYPE));
  800. if(NULL != pOptType)
  801. {
  802. // Initialize OPTTYPE.
  803. pOptType->cbSize = sizeof(OPTTYPE);
  804. pOptType->Count = wOptParams;
  805. // Allocate memory from the heap for the OPTPARAMs for the OPTTYPE.
  806. pOptType->pOptParam = (POPTPARAM) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, wOptParams * sizeof(OPTPARAM));
  807. if(NULL != pOptType->pOptParam)
  808. {
  809. // Initialize the OPTPARAMs.
  810. for(WORD wCount = 0; wCount < wOptParams; wCount++)
  811. {
  812. pOptType->pOptParam[wCount].cbSize = sizeof(OPTPARAM);
  813. }
  814. }
  815. else
  816. {
  817. ERR(ERRORTEXT("CreateOptType() failed to allocated memory for OPTPARAMs!\r\n"));
  818. // Free allocated memory and return NULL.
  819. HeapFree(hHeap, 0, pOptType);
  820. pOptType = NULL;
  821. }
  822. }
  823. else
  824. {
  825. ERR(ERRORTEXT("CreateOptType() failed to allocated memory for OPTTYPE!\r\n"));
  826. }
  827. return pOptType;
  828. }
  829. ////////////////////////////////////////////////////////////////////////////////////
  830. //
  831. // Retrieves pointer to a String resource.
  832. //
  833. static PTSTR GetStringResource(HANDLE hHeap, HANDLE hModule, UINT uResource)
  834. {
  835. int nResult;
  836. DWORD dwSize = MAX_PATH;
  837. PTSTR pszString = NULL;
  838. VERBOSE(DLLTEXT("GetStringResource(%#x, %#x, %d) entered.\r\n"), hHeap, hModule, uResource);
  839. // Allocate buffer for string resource from heap; let the driver clean it up.
  840. pszString = (PTSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize * sizeof(TCHAR));
  841. if(NULL != pszString)
  842. {
  843. // Load string resource; resize after loading so as not to waste memory.
  844. nResult = LoadString((HMODULE)hModule, uResource, pszString, dwSize);
  845. if(nResult > 0)
  846. {
  847. PTSTR pszTemp;
  848. VERBOSE(DLLTEXT("LoadString() returned %d!\r\n"), nResult);
  849. VERBOSE(DLLTEXT("String load was \"%s\".\r\n"), pszString);
  850. pszTemp = (PTSTR) HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, pszString, (nResult + 1) * sizeof(TCHAR));
  851. if(NULL != pszTemp)
  852. {
  853. pszString = pszTemp;
  854. }
  855. else
  856. {
  857. ERR(ERRORTEXT("GetStringResource() HeapReAlloc() of string retrieved failed! (Last Error was %d)\r\n"), GetLastError());
  858. }
  859. }
  860. else
  861. {
  862. ERR(ERRORTEXT("LoadString() returned %d! (Last Error was %d)\r\n"), nResult, GetLastError());
  863. ERR(ERRORTEXT("GetStringResource() failed to load string resource %d!\r\n"), uResource);
  864. pszString = NULL;
  865. }
  866. }
  867. else
  868. {
  869. ERR(ERRORTEXT("GetStringResource() failed to allocate string buffer!\r\n"));
  870. }
  871. return pszString;
  872. }