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.

651 lines
14 KiB

  1. /*++
  2. Copyright (c) 1990-1998 Microsoft Corporation
  3. All Rights Reserved
  4. Module Name:
  5. cpsuisam.c
  6. Abstract:
  7. This module contrains sample prototype for the NT 5.0 common Property
  8. Sheet user interface
  9. --*/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #define DBG_CPSUIFILENAME DbgCPSUISam
  13. #define DBG_WINMAINPROC 0x00000001
  14. DEFINE_DBGVAR(0);
  15. #define HAS_TVTEST_PAGES 0x01
  16. #define HAS_DOCPROP_PAGES 0x02
  17. extern HINSTANCE hInstApp;
  18. extern TCHAR TitleName[];
  19. extern TCHAR ClassName[];
  20. extern TCHAR MenuName[];
  21. extern TCHAR szWinSpool[];
  22. extern CHAR szDocPropSheets[];
  23. extern BOOL UpdatePermission;
  24. extern BOOL UseStdAbout;
  25. HWND hWndApp = NULL;
  26. typedef struct _CPSUISAMPLE
  27. {
  28. HANDLE hParent;
  29. HANDLE hCPSUI;
  30. HANDLE hDocProp;
  31. PFNCOMPROPSHEET pfnCPS;
  32. COMPROPSHEETUI CPSUI;
  33. DOCUMENTPROPERTYHEADER DPHdr;
  34. HGLOBAL hDevMode;
  35. HGLOBAL hDevNames;
  36. } CPSUISAMPLE, *PCPSUISAMPLE;
  37. BOOL
  38. GetDefPrinter
  39. (
  40. PCPSUISAMPLE pCPSUISample
  41. )
  42. {
  43. HGLOBAL h;
  44. LPTSTR pszPrinterName;
  45. DEVMODE *pDM;
  46. DEVNAMES *pDN;
  47. HANDLE hPrinter = NULL;
  48. PAGESETUPDLG PSD;
  49. BOOL Ok = FALSE;
  50. ZeroMemory(&PSD, sizeof(PSD));
  51. PSD.lStructSize = sizeof(PSD);
  52. PSD.Flags = PSD_RETURNDEFAULT;
  53. if (PageSetupDlg(&PSD))
  54. {
  55. if ( (h = PSD.hDevMode)
  56. && (pDM = (DEVMODE *)GlobalLock(h))
  57. && (h = PSD.hDevNames)
  58. && (pDN = (DEVNAMES *)GlobalLock(h))
  59. && (pszPrinterName = (LPTSTR)((LPBYTE)pDN + pDN->wDeviceOffset))
  60. && (OpenPrinter(pszPrinterName, &hPrinter, NULL))
  61. )
  62. {
  63. Ok = TRUE;
  64. }
  65. if (Ok)
  66. {
  67. if (h = pCPSUISample->hDevMode)
  68. {
  69. GlobalUnlock(h);
  70. GlobalFree(h);
  71. }
  72. if (h = pCPSUISample->hDevNames)
  73. {
  74. GlobalUnlock(h);
  75. GlobalFree(h);
  76. }
  77. if (pCPSUISample->DPHdr.hPrinter)
  78. {
  79. ClosePrinter(pCPSUISample->DPHdr.hPrinter);
  80. }
  81. pCPSUISample->hDevMode = PSD.hDevMode;
  82. pCPSUISample->hDevNames = PSD.hDevNames;
  83. pCPSUISample->DPHdr.cbSize = sizeof(DOCUMENTPROPERTYHEADER);
  84. pCPSUISample->DPHdr.hPrinter = hPrinter;
  85. pCPSUISample->DPHdr.pszPrinterName = pszPrinterName;
  86. pCPSUISample->DPHdr.pdmIn =
  87. pCPSUISample->DPHdr.pdmOut = pDM;
  88. pCPSUISample->DPHdr.fMode = (DM_IN_BUFFER | DM_IN_PROMPT | DM_OUT_BUFFER);
  89. if (!UpdatePermission)
  90. {
  91. pCPSUISample->DPHdr.fMode |= DM_NOPERMISSION;
  92. }
  93. }
  94. else
  95. {
  96. if (h = PSD.hDevMode)
  97. {
  98. GlobalUnlock(h);
  99. GlobalFree(h);
  100. }
  101. if (h = PSD.hDevNames)
  102. {
  103. GlobalUnlock(h);
  104. GlobalFree(h);
  105. }
  106. if (hPrinter)
  107. {
  108. ClosePrinter(hPrinter);
  109. }
  110. }
  111. }
  112. return Ok;
  113. }
  114. LONG
  115. CALLBACK
  116. CPSUIFunc
  117. (
  118. PPROPSHEETUI_INFO pPSUIInfo,
  119. LPARAM lParam
  120. )
  121. {
  122. PPROPSHEETUI_INFO_HEADER pPSUIInfoHdr;
  123. PCPSUISAMPLE pCPSUISample;
  124. HANDLE h;
  125. INSERTPSUIPAGE_INFO InsPI;
  126. if (!pPSUIInfo)
  127. {
  128. return FALSE;
  129. }
  130. switch (pPSUIInfo->Reason)
  131. {
  132. case PROPSHEETUI_REASON_INIT:
  133. if (!(pCPSUISample = (PCPSUISAMPLE)LocalAlloc(LPTR, sizeof(CPSUISAMPLE))))
  134. {
  135. return(-1);
  136. }
  137. pPSUIInfo->UserData = (ULONG_PTR)pCPSUISample;
  138. pCPSUISample->hParent = pPSUIInfo->hComPropSheet;
  139. pCPSUISample->pfnCPS = pPSUIInfo->pfnComPropSheet;
  140. //
  141. // Add Document Property Sheet for current default Printer
  142. //
  143. switch (pPSUIInfo->lParamInit)
  144. {
  145. case IDM_DOCPROP:
  146. case IDM_DOCPROP_TVTEST:
  147. if (GetDefPrinter(pCPSUISample))
  148. {
  149. InsPI.cbSize = sizeof(INSERTPSUIPAGE_INFO);
  150. InsPI.Type = PSUIPAGEINSERT_DLL;
  151. InsPI.Mode = INSPSUIPAGE_MODE_FIRST_CHILD;
  152. InsPI.dwData1 = (ULONG_PTR)szWinSpool;
  153. InsPI.dwData2 = (ULONG_PTR)szDocPropSheets;
  154. InsPI.dwData3 = (ULONG_PTR)&(pCPSUISample->DPHdr);
  155. pCPSUISample->hDocProp =
  156. (HANDLE)pCPSUISample->pfnCPS( pCPSUISample->hParent,
  157. CPSFUNC_INSERT_PSUIPAGE,
  158. (LPARAM)0,
  159. (LPARAM)&InsPI
  160. );
  161. }
  162. break;
  163. }
  164. //
  165. // Add TreeView Page
  166. //
  167. switch (pPSUIInfo->lParamInit)
  168. {
  169. case IDM_TVTEST:
  170. case IDM_DOCPROP_TVTEST:
  171. if (SetupComPropSheetUI(&(pCPSUISample->CPSUI)))
  172. {
  173. InsPI.cbSize = sizeof(INSERTPSUIPAGE_INFO);
  174. InsPI.Type = PSUIPAGEINSERT_PCOMPROPSHEETUI;
  175. InsPI.Mode = INSPSUIPAGE_MODE_FIRST_CHILD;
  176. InsPI.dwData1 = (ULONG_PTR)&(pCPSUISample->CPSUI);
  177. InsPI.dwData2 =
  178. InsPI.dwData3 = 0;
  179. pCPSUISample->hCPSUI =
  180. (HANDLE)pCPSUISample->pfnCPS( pCPSUISample->hParent,
  181. CPSFUNC_INSERT_PSUIPAGE,
  182. (LPARAM)0,
  183. (LPARAM)&InsPI
  184. );
  185. }
  186. break;
  187. }
  188. if ( (pCPSUISample->hCPSUI)
  189. || (pCPSUISample->hDocProp)
  190. )
  191. {
  192. return 1;
  193. }
  194. break;
  195. case PROPSHEETUI_REASON_GET_INFO_HEADER:
  196. if (pPSUIInfoHdr = (PPROPSHEETUI_INFO_HEADER)lParam)
  197. {
  198. pPSUIInfoHdr->pTitle = (LPTSTR)TitleName;
  199. switch (pPSUIInfo->lParamInit)
  200. {
  201. case IDM_DOCPROP:
  202. pPSUIInfoHdr->IconID = IDI_CPSUI_PRINTER2;
  203. break;
  204. case IDM_TVTEST:
  205. pPSUIInfoHdr->IconID = IDI_CPSUI_OPTION2;
  206. break;
  207. case IDM_DOCPROP_TVTEST:
  208. pPSUIInfoHdr->IconID = IDI_CPSUI_RUN_DIALOG;
  209. break;
  210. }
  211. pPSUIInfoHdr->Flags = PSUIHDRF_PROPTITLE | PSUIHDRF_NOAPPLYNOW;
  212. pPSUIInfoHdr->hWndParent = hWndApp;
  213. pPSUIInfoHdr->hInst = hInstApp;
  214. return 1;
  215. }
  216. break;
  217. case PROPSHEETUI_REASON_SET_RESULT:
  218. if ( (pCPSUISample = (PCPSUISAMPLE)pPSUIInfo->UserData)
  219. && (pCPSUISample->hCPSUI == ((PSETRESULT_INFO)lParam)->hSetResult)
  220. )
  221. {
  222. //
  223. // Save the result and propagate to its owner
  224. //
  225. pPSUIInfo->Result = ((PSETRESULT_INFO)lParam)->Result;
  226. return 1;
  227. }
  228. break;
  229. case PROPSHEETUI_REASON_DESTROY:
  230. if (pCPSUISample = (PCPSUISAMPLE)pPSUIInfo->UserData)
  231. {
  232. if (h = pCPSUISample->hDevMode)
  233. {
  234. GlobalUnlock(h);
  235. GlobalFree(h);
  236. }
  237. if (h = pCPSUISample->hDevNames)
  238. {
  239. GlobalUnlock(h);
  240. GlobalFree(h);
  241. }
  242. if (pCPSUISample->DPHdr.hPrinter)
  243. {
  244. ClosePrinter(pCPSUISample->DPHdr.hPrinter);
  245. }
  246. LocalFree((HLOCAL)pCPSUISample);
  247. pPSUIInfo->UserData = 0;
  248. }
  249. return 1;
  250. }
  251. return -1;
  252. }
  253. LRESULT
  254. APIENTRY
  255. MainWndProc
  256. (
  257. HWND hWnd,
  258. UINT Msg,
  259. UINT wParam,
  260. LONG lParam
  261. )
  262. /*++
  263. Routine Description:
  264. This is the main window procedure to the testing program
  265. Arguments:
  266. See SDK
  267. Return Value:
  268. See SDK
  269. --*/
  270. {
  271. LONG Result;
  272. LONG Ret;
  273. switch (Msg)
  274. {
  275. case WM_INITMENUPOPUP:
  276. if (!HIWORD(lParam))
  277. {
  278. CheckMenuItem( (HMENU)UIntToPtr(wParam),
  279. IDM_PERMISSION,
  280. MF_BYCOMMAND | ((UpdatePermission) ? MF_CHECKED : MF_UNCHECKED)
  281. );
  282. CheckMenuItem( (HMENU)UIntToPtr(wParam),
  283. IDM_USESTDABOUT,
  284. MF_BYCOMMAND | ((UseStdAbout) ? MF_CHECKED : MF_UNCHECKED)
  285. );
  286. }
  287. break;
  288. case WM_COMMAND:
  289. switch (wParam)
  290. {
  291. case IDM_USESTDABOUT:
  292. UseStdAbout = !UseStdAbout;
  293. break;
  294. case IDM_PERMISSION:
  295. UpdatePermission = !UpdatePermission;
  296. break;
  297. case IDM_DOCPROP:
  298. case IDM_TVTEST:
  299. case IDM_DOCPROP_TVTEST:
  300. Ret = CommonPropertySheetUI( hWnd,
  301. (PFNPROPSHEETUI)CPSUIFunc,
  302. (LPARAM)LOWORD(wParam),
  303. &Result
  304. );
  305. CPSUIDBG( DBG_WINMAINPROC,
  306. ("CommonPropertySheetUI()=%ld, Result=%ld", Ret, Result)
  307. );
  308. break;
  309. default:
  310. break;
  311. }
  312. break;
  313. case WM_DESTROY:
  314. PostQuitMessage(0);
  315. break;
  316. default:
  317. return (DefWindowProc(hWnd, Msg, wParam, lParam));
  318. }
  319. return 0L;
  320. }
  321. BOOL
  322. InitInstance
  323. (
  324. HANDLE hInstance,
  325. INT nCmdShow
  326. )
  327. /*++
  328. Routine Description:
  329. Saves instance handle and creates main window
  330. This function is called at initialization time for every instance of
  331. this application. This function performs initialization tasks that
  332. cannot be shared by multiple instances.
  333. In this case, we save the instance handle in a static variable and
  334. create and display the main program window.
  335. Arguments:
  336. hInstance - Current instance identifier
  337. nComShow - Param for first ShowWindow() call.
  338. Return Value:
  339. TRUE/FALSE
  340. --*/
  341. {
  342. //
  343. // Save the instance handle in static variable, which will be used in
  344. // many subsequence calls from this application to Windows.
  345. //
  346. hInstApp = hInstance;
  347. //
  348. // Create a main window for this application instance.
  349. //
  350. if (hWndApp = CreateWindow( ClassName,
  351. TitleName,
  352. WS_OVERLAPPEDWINDOW,
  353. CW_USEDEFAULT,
  354. CW_USEDEFAULT,
  355. CW_USEDEFAULT,
  356. CW_USEDEFAULT,
  357. NULL,
  358. NULL,
  359. hInstance,
  360. NULL
  361. )
  362. )
  363. {
  364. //
  365. // Make the window visible; update its client area;
  366. // and send WM_PAINT message
  367. //
  368. ShowWindow(hWndApp, nCmdShow);
  369. UpdateWindow(hWndApp);
  370. }
  371. return ((hWndApp) ? TRUE : FALSE);
  372. }
  373. BOOL
  374. InitApplication
  375. (
  376. HANDLE hInstance
  377. )
  378. /*++
  379. Routine Description:
  380. Initializes window data and registers window class
  381. This function is called at initialization time only if no other
  382. instances of the application are running. This function performs
  383. initialization tasks that can be done once for any number of running
  384. instances.
  385. In this case, we initialize a window class by filling out a data
  386. structure of type WNDCLASS and calling the Windows RegisterClass()
  387. function. Since all instances of this application use the same window
  388. class, we only need to do this when the first instance is initialized.
  389. Arguments:
  390. hInstance - current instance
  391. Return Value:
  392. BOOLEAN
  393. --*/
  394. {
  395. WNDCLASS wc;
  396. //
  397. // Fill in window class structure with parameters that describe the
  398. // main window.
  399. //
  400. wc.style = 0L;
  401. wc.lpfnWndProc = (WNDPROC)MainWndProc;
  402. wc.cbClsExtra = 0;
  403. wc.cbWndExtra = 0;
  404. wc.hInstance = hInstance;
  405. wc.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_CPSUISAMPLE);
  406. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  407. wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  408. wc.lpszMenuName = MenuName;
  409. wc.lpszClassName = ClassName;
  410. //
  411. // Register the window class and return success/failure code.
  412. //
  413. return RegisterClass(&wc);
  414. }
  415. INT
  416. APIENTRY
  417. WinMain
  418. (
  419. HINSTANCE hInstance,
  420. HINSTANCE hPrevInstance,
  421. LPSTR lpCmdLine,
  422. INT nCmdShow
  423. )
  424. /*++
  425. Routine Description:
  426. calls initialization function, processes message loop
  427. Windows recognizes this function by name as the initial entry point
  428. for the program. This function calls the application initialization
  429. routine, if no other instance of the program is running, and always
  430. calls the instance initialization routine. It then executes a message
  431. retrieval and dispatch loop that is the top-level control structure
  432. for the remainder of execution. The loop is terminated when a WM_QUIT
  433. message is received, at which time this function exits the application
  434. instance by returning the value passed by PostQuitMessage().
  435. If this function must abort before entering the message loop, it
  436. returns the conventional value NULL.
  437. Arguments:
  438. Return Value:
  439. Integer
  440. --*/
  441. {
  442. MSG Msg;
  443. UNREFERENCED_PARAMETER(lpCmdLine);
  444. //
  445. // Other instances of app running?
  446. //
  447. if (!hPrevInstance)
  448. {
  449. if (!InitApplication(hInstance))
  450. {
  451. //
  452. // Initialize shared things, Exits if unable to initialize
  453. //
  454. return FALSE;
  455. }
  456. }
  457. //
  458. // Perform initializations that apply to a specific instance
  459. //
  460. if (!InitInstance(hInstance, nCmdShow))
  461. {
  462. return FALSE;
  463. }
  464. //
  465. // Acquire and dispatch messages until a WM_QUIT message is received.
  466. //
  467. while (GetMessage(&Msg, NULL, 0L, 0L))
  468. {
  469. //
  470. // Translates virtual key codes and Dispatches message to window
  471. //
  472. TranslateMessage(&Msg);
  473. DispatchMessage(&Msg);
  474. }
  475. //
  476. // Returns the value from PostQuitMessage
  477. //
  478. return((INT)Msg.wParam);
  479. }