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.

2827 lines
72 KiB

  1. /* Copyright (c) 1995, Microsoft Corporation, all rights reserved
  2. **
  3. ** pref.c
  4. ** Remote Access Common Dialog APIs
  5. ** User Preferences property sheet
  6. **
  7. ** 08/22/95 Steve Cobb
  8. */
  9. #include "rasdlgp.h"
  10. #include <commdlg.h> // FileOpen dialog
  11. /* Page definitions.
  12. */
  13. //#define UP_AdPage 0
  14. //#define UP_CbPage 1
  15. //#define UP_GpPage 2
  16. //#define UP_PlPage 3
  17. #define UP_PageCount 2
  18. //
  19. // Defines flags the modify the behavior of the user preferences
  20. // dialog
  21. //
  22. #define UP_F_AutodialMode 0x1 // Come up with focus on autodial page
  23. /*----------------------------------------------------------------------------
  24. ** Help maps
  25. **----------------------------------------------------------------------------
  26. */
  27. static DWORD g_adwAdHelp[] =
  28. {
  29. CID_AD_ST_Enable, HID_AD_LV_Enable,
  30. CID_AD_LV_Enable, HID_AD_LV_Enable,
  31. CID_AD_ST_Attempts, HID_AD_EB_Attempts,
  32. CID_AD_EB_Attempts, HID_AD_EB_Attempts,
  33. CID_AD_ST_Seconds, HID_AD_EB_Seconds,
  34. CID_AD_EB_Seconds, HID_AD_EB_Seconds,
  35. CID_AD_ST_Idle, HID_AD_EB_Idle,
  36. CID_AD_EB_Idle, HID_AD_EB_Idle,
  37. CID_AD_CB_AskBeforeAutodial, HID_AD_CB_AskBeforeAutodial,
  38. CID_AD_CB_AskBeforeAutodial, HID_AD_CB_AskBeforeAutodial,
  39. CID_AD_CB_DisableThisSession, HID_AD_CB_DisableThisSession,
  40. 0, 0
  41. };
  42. static DWORD g_adwCbHelp[] =
  43. {
  44. CID_CB_RB_No, HID_CB_RB_No,
  45. CID_CB_RB_Maybe, HID_CB_RB_Maybe,
  46. CID_CB_RB_Yes, HID_CB_RB_Yes,
  47. CID_CB_LV_Numbers, HID_CB_LV_Numbers,
  48. CID_CB_PB_Edit, HID_CB_PB_Edit,
  49. CID_CB_PB_Delete, HID_CB_PB_Delete,
  50. 0, 0
  51. };
  52. static DWORD g_adwGpHelp[] =
  53. {
  54. CID_GP_CB_Preview, HID_GP_CB_Preview,
  55. CID_GP_CB_Location, HID_GP_CB_Location,
  56. CID_GP_CB_Lights, HID_GP_CB_Lights,
  57. CID_GP_CB_Progress, HID_GP_CB_Progress,
  58. CID_GP_CB_CloseOnDial, HID_GP_CB_CloseOnDial,
  59. CID_GP_CB_UseWizard, HID_GP_CB_UseWizard,
  60. CID_GP_CB_AutodialPrompt, HID_GP_CB_AutodialPrompt,
  61. CID_GP_CB_PhonebookEdits, HID_GP_CB_PhonebookEdits,
  62. CID_GP_CB_LocationEdits, HID_GP_CB_LocationEdits,
  63. 0, 0
  64. };
  65. static DWORD g_adwCoHelp[] =
  66. {
  67. CID_CO_GB_LogonPrivileges, HID_CO_GB_LogonPrivileges,
  68. CID_CO_ST_AllowConnectionModification, HID_CO_CB_AllowConnectionModification,
  69. CID_CO_CB_AllowConnectionModification, HID_CO_CB_AllowConnectionModification,
  70. 0, 0
  71. };
  72. static DWORD g_adwPlHelp[] =
  73. {
  74. CID_PL_ST_Open, HID_PL_ST_Open,
  75. CID_PL_RB_SystemList, HID_PL_RB_SystemList,
  76. CID_PL_RB_PersonalList, HID_PL_RB_PersonalList,
  77. CID_PL_RB_AlternateList, HID_PL_RB_AlternateList,
  78. CID_PL_CL_Lists, HID_PL_CL_Lists,
  79. CID_PL_PB_Browse, HID_PL_PB_Browse,
  80. 0, 0
  81. };
  82. /*----------------------------------------------------------------------------
  83. ** Local datatypes (alphabetically)
  84. **----------------------------------------------------------------------------
  85. */
  86. /* User Preferences property sheet argument block.
  87. */
  88. #define UPARGS struct tagUPARGS
  89. UPARGS
  90. {
  91. /* Caller's arguments to the stub API.
  92. */
  93. HLINEAPP hlineapp;
  94. BOOL fNoUser;
  95. BOOL fIsUserAdmin;
  96. PBUSER* pUser;
  97. PBFILE** ppFile;
  98. /* Stub API return value.
  99. */
  100. BOOL fResult;
  101. /* Flags that provide more info see UP_F_* values
  102. */
  103. DWORD dwFlags;
  104. };
  105. /* User Preferences property sheet context block. All property pages refer to
  106. ** the single context block associated with the sheet.
  107. */
  108. #define UPINFO struct tagUPINFO
  109. UPINFO
  110. {
  111. /* Stub API arguments from UpPropertySheet.
  112. */
  113. UPARGS* pArgs;
  114. /* TAPI session handle. Should always be addressed thru the pointer since
  115. ** the handle passed down from caller, if any, will be used instead of
  116. ** 'hlineapp'.
  117. */
  118. HLINEAPP hlineapp;
  119. HLINEAPP* pHlineapp;
  120. /* Property sheet dialog and property page handles. 'hwndFirstPage' is
  121. ** the handle of the first property page initialized. This is the page
  122. ** that allocates and frees the context block.
  123. */
  124. HWND hwndDlg;
  125. HWND hwndFirstPage;
  126. HWND hwndCo;
  127. HWND hwndGp;
  128. HWND hwndAd;
  129. HWND hwndCb;
  130. HWND hwndPl;
  131. /* Auto-dial page.
  132. */
  133. HWND hwndLvEnable;
  134. HWND hwndEbAttempts;
  135. HWND hwndEbSeconds;
  136. HWND hwndEbIdle;
  137. BOOL fChecksInstalled;
  138. /* Callback page.
  139. */
  140. HWND hwndRbNo;
  141. HWND hwndRbMaybe;
  142. HWND hwndRbYes;
  143. HWND hwndLvNumbers;
  144. HWND hwndPbEdit;
  145. HWND hwndPbDelete;
  146. /* Phone list page.
  147. */
  148. HWND hwndRbSystem;
  149. HWND hwndRbPersonal;
  150. HWND hwndRbAlternate;
  151. HWND hwndClbAlternates;
  152. HWND hwndPbBrowse;
  153. /* Working data read from and written to registry with phonebook library.
  154. */
  155. PBUSER user; // Current user
  156. PBUSER userLogon; // Logon preferences
  157. };
  158. /*----------------------------------------------------------------------------
  159. ** Local prototypes (alphabetically)
  160. **----------------------------------------------------------------------------
  161. */
  162. VOID
  163. AdApply(
  164. IN UPINFO* pInfo );
  165. INT_PTR CALLBACK
  166. AdDlgProc(
  167. IN HWND hwnd,
  168. IN UINT unMsg,
  169. IN WPARAM wparam,
  170. IN LPARAM lparam );
  171. BOOL
  172. AdFillLvEnable(
  173. IN UPINFO* pInfo );
  174. BOOL
  175. AdInit(
  176. IN HWND hwndPage,
  177. IN OUT UPARGS* pArgs );
  178. LVXDRAWINFO*
  179. AdLvEnableCallback(
  180. IN HWND hwndLv,
  181. IN DWORD dwItem );
  182. VOID
  183. CbApply(
  184. IN UPINFO* pInfo );
  185. BOOL
  186. CbCommand(
  187. IN UPINFO* pInfo,
  188. IN WORD wNotification,
  189. IN WORD wId,
  190. IN HWND hwndCtrl );
  191. INT_PTR CALLBACK
  192. CbDlgProc(
  193. IN HWND hwnd,
  194. IN UINT unMsg,
  195. IN WPARAM wparam,
  196. IN LPARAM lparam );
  197. BOOL
  198. CbInit(
  199. IN HWND hwndPage );
  200. VOID
  201. CbUpdateLvAndPbState(
  202. IN UPINFO* pInfo );
  203. BOOL
  204. CoApply(
  205. IN UPINFO* pInfo );
  206. INT_PTR CALLBACK
  207. CoDlgProc(
  208. IN HWND hwnd,
  209. IN UINT unMsg,
  210. IN WPARAM wparam,
  211. IN LPARAM lparam );
  212. BOOL
  213. CoInit(
  214. IN HWND hwndPage,
  215. IN OUT UPARGS* pArgs );
  216. VOID
  217. GpApply(
  218. IN UPINFO* pInfo );
  219. BOOL
  220. GpCommand(
  221. IN UPINFO* pInfo,
  222. IN WORD wNotification,
  223. IN WORD wId,
  224. IN HWND hwndCtrl );
  225. INT_PTR CALLBACK
  226. GpDlgProc(
  227. IN HWND hwnd,
  228. IN UINT unMsg,
  229. IN WPARAM wparam,
  230. IN LPARAM lparam );
  231. BOOL
  232. GpInit(
  233. IN HWND hwndPage );
  234. VOID
  235. GpUpdateCbStates(
  236. IN UPINFO* pInfo );
  237. BOOL
  238. PlApply(
  239. IN UPINFO* pInfo );
  240. VOID
  241. PlBrowse(
  242. IN UPINFO* pInfo );
  243. BOOL
  244. PlCommand(
  245. IN UPINFO* pInfo,
  246. IN WORD wNotification,
  247. IN WORD wId,
  248. IN HWND hwndCtrl );
  249. INT_PTR CALLBACK
  250. PlDlgProc(
  251. IN HWND hwnd,
  252. IN UINT unMsg,
  253. IN WPARAM wparam,
  254. IN LPARAM lparam );
  255. BOOL
  256. PlInit(
  257. IN HWND hwndPage );
  258. BOOL
  259. UpApply(
  260. IN HWND hwndPage );
  261. VOID
  262. UpCancel(
  263. IN HWND hwndPage );
  264. UPINFO*
  265. UpContext(
  266. IN HWND hwndPage );
  267. VOID
  268. UpExit(
  269. IN UPINFO* pInfo );
  270. VOID
  271. UpExitInit(
  272. IN HWND hwndDlg );
  273. UPINFO*
  274. UpInit(
  275. IN HWND hwndFirstPage,
  276. IN UPARGS* pArgs );
  277. VOID
  278. UpTerm(
  279. IN HWND hwndPage );
  280. /*----------------------------------------------------------------------------
  281. ** User Preferences property sheet entry point
  282. **----------------------------------------------------------------------------
  283. */
  284. BOOL
  285. UserPreferencesDlg(
  286. IN HLINEAPP hlineapp,
  287. IN HWND hwndOwner,
  288. IN BOOL fNoUser,
  289. IN DWORD dwFlags,
  290. OUT PBUSER* pUser,
  291. OUT PBFILE** ppFile )
  292. /* Pops up the User Preferences property sheet, reading and storing the
  293. ** result in the USER registry. 'HwndOwner' is the handle of the owning
  294. ** window. 'FNoUser' indicates logon preferences, rather than user
  295. ** preferences should be edited. 'Hlineapp' is an open TAPI session
  296. ** handle or NULL if none. 'Puser' is caller's buffer to receive the
  297. ** result. 'PpFile' is address of caller's file block which is filled in,
  298. ** if user chooses to open a new phonebook file, with the information
  299. ** about the newly open file. It is caller's responsibility to
  300. ** ClosePhonebookFile and Free the returned block.
  301. **
  302. ** Returns true if user pressed OK and settings were saved successfully,
  303. ** or false if user pressed Cancel or an error occurred. The routine
  304. ** handles the display of an appropriate error popup.
  305. */
  306. {
  307. PROPSHEETHEADER header;
  308. PROPSHEETPAGE* apage;
  309. PROPSHEETPAGE* ppage;
  310. TCHAR* pszTitle;
  311. UPARGS args;
  312. BOOL bIsAdmin;
  313. DWORD dwPageCount, i;
  314. TRACE("UpPropertySheet");
  315. // If the user doesn't have administrative priveleges, then
  316. // we don't allow the Connections tab to show.
  317. ZeroMemory(&args, sizeof(args));
  318. args.fIsUserAdmin = FIsUserAdminOrPowerUser();
  319. dwPageCount = UP_PageCount;
  320. // Initialize the array of pages
  321. apage = Malloc (dwPageCount * sizeof (PROPSHEETPAGE));
  322. if (!apage)
  323. return FALSE;
  324. /* Initialize OUT parameter and property sheet argument block.
  325. */
  326. ZeroMemory( pUser, sizeof(*pUser) );
  327. args.pUser = pUser;
  328. args.fNoUser = fNoUser;
  329. args.ppFile = ppFile;
  330. args.hlineapp = hlineapp;
  331. args.fResult = FALSE;
  332. args.dwFlags = dwFlags;
  333. if (ppFile)
  334. *ppFile = NULL;
  335. pszTitle = PszFromId(
  336. g_hinstDll, (fNoUser) ? SID_UpLogonTitle : SID_UpTitle );
  337. ZeroMemory( &header, sizeof(header) );
  338. header.dwSize = sizeof(PROPSHEETHEADER);
  339. header.dwFlags = PSH_PROPSHEETPAGE + PSH_NOAPPLYNOW;
  340. header.hwndParent = hwndOwner;
  341. header.hInstance = g_hinstDll;
  342. header.pszCaption = (pszTitle) ? pszTitle : TEXT("");
  343. header.nPages = dwPageCount;
  344. header.ppsp = apage;
  345. ZeroMemory( apage, dwPageCount * sizeof (PROPSHEETPAGE) );
  346. i = 0;
  347. // Add the autodial page
  348. ppage = &apage[ i ];
  349. ppage->dwSize = sizeof(PROPSHEETPAGE);
  350. ppage->hInstance = g_hinstDll;
  351. ppage->pszTemplate =
  352. (fNoUser)
  353. ? MAKEINTRESOURCE( PID_AD_AutoDialLogon )
  354. : MAKEINTRESOURCE( PID_AD_AutoDial ),
  355. ppage->pfnDlgProc = AdDlgProc;
  356. ppage->lParam = (LPARAM )&args;
  357. i++;
  358. ppage = &apage[ i ];
  359. ppage->dwSize = sizeof(PROPSHEETPAGE);
  360. ppage->hInstance = g_hinstDll;
  361. ppage->pszTemplate = MAKEINTRESOURCE( PID_CB_CallbackSettings );
  362. ppage->pfnDlgProc = CbDlgProc;
  363. i++;
  364. #if 0
  365. ppage = &apage[ UP_GpPage ];
  366. ppage->dwSize = sizeof(PROPSHEETPAGE);
  367. ppage->hInstance = g_hinstDll;
  368. ppage->pszTemplate =
  369. (fNoUser)
  370. ? MAKEINTRESOURCE( PID_GP_GeneralPrefLogon )
  371. : MAKEINTRESOURCE( PID_GP_GeneralPreferences ),
  372. ppage->pfnDlgProc = GpDlgProc;
  373. ppage = &apage[ UP_PlPage ];
  374. ppage->dwSize = sizeof(PROPSHEETPAGE);
  375. ppage->hInstance = g_hinstDll;
  376. ppage->pszTemplate =
  377. (fNoUser)
  378. ? MAKEINTRESOURCE( PID_PL_PhoneListLogon )
  379. : MAKEINTRESOURCE( PID_PL_PhoneList ),
  380. ppage->pfnDlgProc = PlDlgProc;
  381. #endif
  382. if (PropertySheet( &header ) == -1)
  383. {
  384. TRACE("PropertySheet failed");
  385. ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  386. }
  387. Free0( pszTitle );
  388. return args.fResult;
  389. }
  390. // Allows the editing of ras user preferences
  391. DWORD
  392. APIENTRY
  393. RasUserPrefsDlgInternal (
  394. HWND hwndParent,
  395. DWORD dwFlags)
  396. {
  397. BOOL bCommit = FALSE;
  398. PBFILE * pPbFile = NULL;
  399. PBUSER pbuser;
  400. DWORD dwErr;
  401. // Load ras if neccessary
  402. dwErr = LoadRas( g_hinstDll, hwndParent );
  403. if (dwErr != 0)
  404. {
  405. ErrorDlg( hwndParent, SID_OP_LoadRas, dwErr, NULL );
  406. return dwErr;
  407. }
  408. // Launch the user preferences dialog
  409. bCommit = UserPreferencesDlg(
  410. 0,
  411. hwndParent,
  412. FALSE,
  413. dwFlags,
  414. &pbuser,
  415. &pPbFile );
  416. // Commit any neccessary changes
  417. if (bCommit)
  418. {
  419. }
  420. return NO_ERROR;
  421. }
  422. DWORD
  423. APIENTRY
  424. RasUserPrefsDlgAutodial (
  425. HWND hwndParent)
  426. {
  427. return RasUserPrefsDlgInternal(hwndParent, UP_F_AutodialMode);
  428. }
  429. DWORD
  430. APIENTRY
  431. RasUserPrefsDlg (
  432. HWND hwndParent)
  433. {
  434. return RasUserPrefsDlgInternal(hwndParent, 0);
  435. }
  436. DWORD
  437. APIENTRY
  438. RasUserEnableManualDial (
  439. IN HWND hwndParent,
  440. IN BOOL bLogon,
  441. IN BOOL bEnable )
  442. /* Called when the "operator dial" menu item is checked.
  443. */
  444. {
  445. return SetUserManualDialEnabling (
  446. bEnable,
  447. (bLogon) ? UPM_Logon : UPM_Normal);
  448. }
  449. DWORD
  450. APIENTRY
  451. RasUserGetManualDial (
  452. IN HWND hwndParent, // parent for error dialogs
  453. IN BOOL bLogon, // whether a user is logged in
  454. IN PBOOL pbEnabled ) // whether to enable or not
  455. /* Called when the "operator dial" menu item is checked.
  456. */
  457. {
  458. return GetUserManualDialEnabling (
  459. pbEnabled,
  460. (bLogon) ? UPM_Logon : UPM_Normal );
  461. }
  462. /*----------------------------------------------------------------------------
  463. ** User Preferences property sheet
  464. ** Listed alphabetically
  465. **----------------------------------------------------------------------------
  466. */
  467. BOOL
  468. UpApply(
  469. IN HWND hwndPage )
  470. /* Saves the contents of the property sheet. 'hwndPage' is the property
  471. ** sheet page. Pops up any errors that occur.
  472. **
  473. ** Returns false if invalid, true otherwise.
  474. */
  475. {
  476. DWORD dwErr;
  477. UPINFO* pInfo;
  478. TRACE("UpApply");
  479. pInfo = UpContext( hwndPage );
  480. if (!pInfo)
  481. return TRUE;
  482. if ( pInfo->hwndAd )
  483. AdApply( pInfo );
  484. if (pInfo->hwndCb)
  485. CbApply( pInfo );
  486. #if 0
  487. if (pInfo->hwndGp)
  488. GpApply( pInfo );
  489. #endif
  490. if (pInfo->hwndCo)
  491. CoApply ( pInfo );
  492. #if 0
  493. if (pInfo->hwndPl)
  494. {
  495. if (!PlApply( pInfo ))
  496. return FALSE;
  497. }
  498. #endif
  499. pInfo->user.fDirty = TRUE;
  500. // Save off the user preferences
  501. //
  502. dwErr = g_pSetUserPreferences(
  503. NULL,
  504. &pInfo->user,
  505. pInfo->pArgs->fNoUser ? UPM_Logon : UPM_Normal );
  506. if (dwErr != 0)
  507. {
  508. if (*pInfo->pArgs->ppFile)
  509. {
  510. ClosePhonebookFile( *pInfo->pArgs->ppFile );
  511. *pInfo->pArgs->ppFile = NULL;
  512. }
  513. ErrorDlg( pInfo->hwndDlg, SID_OP_WritePrefs, dwErr, NULL );
  514. UpExit( pInfo );
  515. return TRUE;
  516. }
  517. // Save off the logon preferences if we loaded them.
  518. //
  519. if (! pInfo->pArgs->fNoUser )
  520. {
  521. dwErr = g_pSetUserPreferences(
  522. NULL,
  523. &pInfo->userLogon,
  524. UPM_Logon );
  525. if (dwErr != 0)
  526. {
  527. ErrorDlg( pInfo->hwndDlg, SID_OP_WritePrefs, dwErr, NULL );
  528. UpExit( pInfo );
  529. return TRUE;
  530. }
  531. }
  532. CopyMemory( pInfo->pArgs->pUser, &pInfo->user, sizeof(PBUSER) );
  533. pInfo->pArgs->fResult = TRUE;
  534. return TRUE;
  535. }
  536. VOID
  537. UpCancel(
  538. IN HWND hwndPage )
  539. /* Cancel was pressed. 'HwndPage' is the handle of a property page.
  540. */
  541. {
  542. TRACE("UpCancel");
  543. }
  544. UPINFO*
  545. UpContext(
  546. IN HWND hwndPage )
  547. /* Retrieve the property sheet context from a property page handle.
  548. */
  549. {
  550. return (UPINFO* )GetProp( GetParent( hwndPage ), g_contextId );
  551. }
  552. VOID
  553. UpExit(
  554. IN UPINFO* pInfo )
  555. /* Forces an exit from the dialog. 'PInfo' is the property sheet context.
  556. **
  557. ** Note: This cannot be called during initialization of the first page.
  558. ** See UpExitInit.
  559. */
  560. {
  561. TRACE("UpExit");
  562. PropSheet_PressButton( pInfo->hwndDlg, PSBTN_CANCEL );
  563. }
  564. VOID
  565. UpExitInit(
  566. IN HWND hwndDlg )
  567. /* Utility to report errors within UpInit and other first page
  568. ** initialization. 'HwndDlg' is the dialog window.
  569. */
  570. {
  571. SetOffDesktop( hwndDlg, SOD_MoveOff, NULL );
  572. SetOffDesktop( hwndDlg, SOD_Free, NULL );
  573. PostMessage( hwndDlg, WM_COMMAND,
  574. MAKEWPARAM( IDCANCEL , BN_CLICKED ),
  575. (LPARAM )GetDlgItem( hwndDlg, IDCANCEL ) );
  576. }
  577. UPINFO*
  578. UpInit(
  579. IN HWND hwndFirstPage,
  580. IN UPARGS* pArgs )
  581. /* Property sheet level initialization. 'HwndPage' is the handle of the
  582. ** first page. 'PArgs' is the API argument block.
  583. **
  584. ** Returns address of the context block if successful, NULL otherwise. If
  585. ** NULL is returned, an appropriate message has been displayed, and the
  586. ** property sheet has been cancelled.
  587. */
  588. {
  589. UPINFO* pInfo;
  590. DWORD dwErr;
  591. HWND hwndDlg;
  592. TRACE("UpInit");
  593. hwndDlg = GetParent( hwndFirstPage );
  594. ASSERT(hwndDlg);
  595. /* Allocate the context information block.
  596. */
  597. pInfo = Malloc( sizeof(*pInfo) );
  598. if (!pInfo)
  599. {
  600. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  601. UpExitInit( hwndDlg );
  602. return NULL;
  603. }
  604. /* Initialize the context block.
  605. */
  606. ZeroMemory( pInfo, sizeof(*pInfo) );
  607. pInfo->hwndDlg = hwndDlg;
  608. pInfo->pArgs = pArgs;
  609. pInfo->hwndFirstPage = hwndFirstPage;
  610. /* Read in the user preferences
  611. */
  612. dwErr = g_pGetUserPreferences(
  613. NULL,
  614. &pInfo->user,
  615. pArgs->fNoUser ? UPM_Logon : UPM_Normal);
  616. if (dwErr != 0)
  617. {
  618. Free( pInfo );
  619. ErrorDlg( hwndDlg, SID_OP_LoadPrefs, dwErr, NULL );
  620. UpExitInit( hwndDlg );
  621. return NULL;
  622. }
  623. /* If the fNoUser option was not selected, then load in the
  624. logon preferences separately, since we allow them to be
  625. modificed in this UI
  626. */
  627. if (! pArgs->fNoUser )
  628. {
  629. dwErr = g_pGetUserPreferences(
  630. NULL,
  631. &pInfo->userLogon,
  632. UPM_Logon);
  633. if (dwErr != 0)
  634. {
  635. Free( pInfo );
  636. ErrorDlg( hwndDlg, SID_OP_LoadPrefs, dwErr, NULL );
  637. UpExitInit( hwndDlg );
  638. return NULL;
  639. }
  640. }
  641. /* Associate the context with the property sheet window.
  642. */
  643. if (!SetProp( hwndDlg, g_contextId, pInfo ))
  644. {
  645. Free( pInfo );
  646. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  647. UpExitInit( hwndDlg );
  648. return NULL;
  649. }
  650. /* Use caller's TAPI session handle, if any.
  651. */
  652. if (pArgs->hlineapp)
  653. pInfo->pHlineapp = &pArgs->hlineapp;
  654. else
  655. pInfo->pHlineapp = &pInfo->hlineapp;
  656. TRACE("Context set");
  657. /* Set even fixed tab widths, per spec.
  658. */
  659. // SetEvenTabWidths( hwndDlg, UP_PageCount );
  660. /* Position property sheet at standard offset from parent.
  661. {
  662. RECT rect;
  663. GetWindowRect( GetParent( hwndDlg ), &rect );
  664. SetWindowPos( hwndDlg, NULL,
  665. rect.left + DXSHEET, rect.top + DYSHEET, 0, 0,
  666. SWP_NOZORDER + SWP_NOSIZE );
  667. UnclipWindow( hwndDlg );
  668. }
  669. */
  670. CenterWindow ( hwndDlg, GetParent ( hwndDlg ) );
  671. //
  672. // pmay: 292069
  673. //
  674. // If the autodialer dialog has called into us, set focus to the
  675. // autodial tab.
  676. //
  677. if (pArgs->dwFlags & UP_F_AutodialMode)
  678. {
  679. PostMessage(
  680. hwndDlg,
  681. PSM_SETCURSELID,
  682. 0,
  683. (LPARAM)(INT)PID_AD_AutoDial);
  684. }
  685. return pInfo;
  686. }
  687. VOID
  688. UpTerm(
  689. IN HWND hwndPage )
  690. /* Property sheet level termination. Releases the context block.
  691. ** 'HwndPage' is the handle of a property page.
  692. */
  693. {
  694. UPINFO* pInfo;
  695. TRACE("UpTerm");
  696. pInfo = UpContext( hwndPage );
  697. // Only terminate for once by making sure that we
  698. // only terminate if this is the first page.
  699. if ( (pInfo) && (pInfo->hwndFirstPage == hwndPage) )
  700. {
  701. // Cleanup the list view
  702. if ( pInfo->hwndLvNumbers )
  703. {
  704. CbutilLvNumbersCleanup( pInfo->hwndLvNumbers );
  705. }
  706. if (pInfo->fChecksInstalled)
  707. {
  708. ListView_UninstallChecks( pInfo->hwndLvEnable );
  709. }
  710. if (pInfo->pHlineapp && *pInfo->pHlineapp != pInfo->pArgs->hlineapp)
  711. {
  712. TapiShutdown( *pInfo->pHlineapp );
  713. }
  714. Free( pInfo );
  715. TRACE("Context freed");
  716. }
  717. RemoveProp( GetParent( hwndPage ), g_contextId );
  718. }
  719. /*----------------------------------------------------------------------------
  720. ** Auto Dial property page
  721. ** Listed alphabetically following dialog proc
  722. **----------------------------------------------------------------------------
  723. */
  724. INT_PTR CALLBACK
  725. AdDlgProc(
  726. IN HWND hwnd,
  727. IN UINT unMsg,
  728. IN WPARAM wparam,
  729. IN LPARAM lparam )
  730. /* DialogProc callback for the Auto Dial page of the User Preferences
  731. ** property sheet. Parameters and return value are as described for
  732. ** standard windows 'DialogProc's.
  733. */
  734. {
  735. #if 0
  736. TRACE4("AdDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  737. (DWORD)hwnd,(DWORD)unMsg,(DWORD)wparam,(DWORD)lparam);
  738. #endif
  739. if (ListView_OwnerHandler(
  740. hwnd, unMsg, wparam, lparam, AdLvEnableCallback ))
  741. {
  742. return TRUE;
  743. }
  744. switch (unMsg)
  745. {
  746. case WM_INITDIALOG:
  747. return
  748. AdInit( hwnd, (UPARGS* )(((PROPSHEETPAGE* )lparam)->lParam) );
  749. case WM_HELP:
  750. case WM_CONTEXTMENU:
  751. ContextHelp( g_adwAdHelp, hwnd, unMsg, wparam, lparam );
  752. break;
  753. case WM_NOTIFY:
  754. {
  755. switch (((NMHDR* )lparam)->code)
  756. {
  757. case PSN_APPLY:
  758. {
  759. BOOL fValid;
  760. UPINFO* pInfo = UpContext ( hwnd );
  761. TRACE("AdAPPLY");
  762. // We have to apply if we are the first page...
  763. if (pInfo->hwndFirstPage == hwnd)
  764. {
  765. /* Call UpApply only on first page.
  766. */
  767. fValid = UpApply( hwnd );
  768. SetWindowLong(
  769. hwnd, DWLP_MSGRESULT,
  770. (fValid)
  771. ? PSNRET_NOERROR
  772. : PSNRET_INVALID_NOCHANGEPAGE );
  773. return TRUE;
  774. }
  775. }
  776. case PSN_RESET:
  777. {
  778. /* Call UpCancel only on first page.
  779. */
  780. TRACE("AdRESET");
  781. UpCancel( hwnd );
  782. SetWindowLong( hwnd, DWLP_MSGRESULT, FALSE );
  783. break;
  784. }
  785. }
  786. }
  787. break;
  788. case WM_DESTROY:
  789. {
  790. /* UpTerm will handle making sure it only does its
  791. ** thing once
  792. */
  793. UpTerm( hwnd );
  794. break;
  795. }
  796. }
  797. return FALSE;
  798. }
  799. VOID
  800. AdApply(
  801. IN UPINFO* pInfo )
  802. /* Saves the contents of the property page. 'PInfo' is the property sheet
  803. ** context.
  804. */
  805. {
  806. DWORD dwErr, dwFlag;
  807. UINT unValue;
  808. LV_ITEM item;
  809. INT i, iCount;
  810. BOOL f;
  811. TRACE("AdApply");
  812. if (!pInfo->pArgs->fNoUser)
  813. {
  814. ZeroMemory( &item, sizeof(item) );
  815. item.mask = LVIF_PARAM + LVIF_STATE;
  816. iCount = ListView_GetItemCount( pInfo->hwndLvEnable );
  817. for (i = 0; i < iCount; ++i)
  818. {
  819. BOOL fCheck;
  820. item.iItem = i;
  821. if (!ListView_GetItem( pInfo->hwndLvEnable, &item ))
  822. break;
  823. fCheck = ListView_GetCheck( pInfo->hwndLvEnable, i );
  824. ASSERT(g_pRasSetAutodialEnable);
  825. dwErr = g_pRasSetAutodialEnable( (DWORD )item.lParam, fCheck );
  826. if (dwErr != 0)
  827. ErrorDlg( pInfo->hwndDlg, SID_OP_SetADialInfo, dwErr, NULL );
  828. }
  829. /* Set the autodial prompt information.
  830. * Flip it because the API wants true to mean "disable".
  831. */
  832. dwFlag = (DWORD )!IsDlgButtonChecked(
  833. pInfo->hwndAd, CID_AD_CB_AskBeforeAutodial );
  834. TRACE1("RasSetAutodialParam(%d)",dwFlag);
  835. dwErr = g_pRasSetAutodialParam( RASADP_DisableConnectionQuery,
  836. &dwFlag, sizeof(dwFlag) );
  837. TRACE1("RasSetAutodialParam=%d",dwErr);
  838. //
  839. // pmay: 209762
  840. //
  841. // Save the "disable current session" checkbox
  842. //
  843. dwFlag = (DWORD )
  844. IsDlgButtonChecked(pInfo->hwndAd, CID_AD_CB_DisableThisSession );
  845. dwErr = g_pRasSetAutodialParam(
  846. RASADP_LoginSessionDisable,
  847. &dwFlag,
  848. sizeof(dwFlag) );
  849. }
  850. }
  851. BOOL
  852. AdFillLvEnable(
  853. IN UPINFO* pInfo )
  854. /* Initialize the listview of checkboxes. 'PInfo' is the property sheet
  855. ** context.
  856. **
  857. ** Note: This routine must only be called once.
  858. **
  859. ** Returns true if focus is set, false otherwise.
  860. */
  861. {
  862. DWORD dwErr;
  863. LOCATION* pLocations;
  864. DWORD cLocations;
  865. DWORD dwCurLocation;
  866. BOOL fFocusSet;
  867. fFocusSet = FALSE;
  868. ListView_DeleteAllItems( pInfo->hwndLvEnable );
  869. /* Install "listview of check boxes" handling.
  870. */
  871. pInfo->fChecksInstalled =
  872. ListView_InstallChecks( pInfo->hwndLvEnable, g_hinstDll );
  873. if (!pInfo->fChecksInstalled)
  874. return FALSE;
  875. /* Insert an item for each location.
  876. */
  877. pLocations = NULL;
  878. cLocations = 0;
  879. dwCurLocation = 0xFFFFFFFF;
  880. dwErr = GetLocationInfo( g_hinstDll, pInfo->pHlineapp,
  881. &pLocations, &cLocations, &dwCurLocation );
  882. if (dwErr != 0)
  883. ErrorDlg( pInfo->hwndDlg, SID_OP_LoadTapiInfo, dwErr, NULL );
  884. else
  885. {
  886. LV_ITEM item;
  887. LOCATION* pLocation;
  888. TCHAR* pszCurLoc;
  889. DWORD i;
  890. pszCurLoc = PszFromId( g_hinstDll, SID_IsCurLoc );
  891. ZeroMemory( &item, sizeof(item) );
  892. item.mask = LVIF_TEXT + LVIF_PARAM;
  893. for (i = 0, pLocation = pLocations;
  894. i < cLocations;
  895. ++i, ++pLocation)
  896. {
  897. TCHAR* psz;
  898. TCHAR* pszText;
  899. DWORD cb;
  900. pszText = NULL;
  901. psz = StrDup( pLocation->pszName );
  902. if (psz)
  903. {
  904. if (dwCurLocation == pLocation->dwId && pszCurLoc)
  905. {
  906. /* This is the current globally selected location. Append
  907. ** the " (the current location)" text.
  908. */
  909. cb = lstrlen( psz ) + lstrlen(pszCurLoc) + 1;
  910. pszText = Malloc( cb * sizeof(TCHAR) );
  911. if (pszText)
  912. {
  913. // Whistler bug 224074 use only lstrcpyn's to prevent
  914. // maliciousness
  915. //
  916. lstrcpyn(
  917. pszText,
  918. psz,
  919. cb );
  920. lstrcat( pszText, pszCurLoc );
  921. }
  922. Free( psz );
  923. }
  924. else
  925. pszText = psz;
  926. }
  927. if (pszText)
  928. {
  929. BOOL fCheck;
  930. /* Get the initial check value for this location.
  931. */
  932. ASSERT(g_pRasGetAutodialEnable);
  933. dwErr = g_pRasGetAutodialEnable( pLocation->dwId, &fCheck );
  934. if (dwErr != 0)
  935. {
  936. ErrorDlg( pInfo->hwndDlg, SID_OP_GetADialInfo,
  937. dwErr, NULL );
  938. fCheck = FALSE;
  939. }
  940. item.iItem = i;
  941. item.lParam = pLocation->dwId;
  942. item.pszText = pszText;
  943. ListView_InsertItem( pInfo->hwndLvEnable, &item );
  944. ListView_SetCheck( pInfo->hwndLvEnable, i, fCheck );
  945. if (dwCurLocation == pLocation->dwId)
  946. {
  947. /* Initial selection is the current location.
  948. */
  949. ListView_SetItemState( pInfo->hwndLvEnable, i,
  950. LVIS_SELECTED + LVIS_FOCUSED,
  951. LVIS_SELECTED + LVIS_FOCUSED );
  952. fFocusSet = TRUE;
  953. }
  954. Free( pszText );
  955. }
  956. }
  957. Free0( pszCurLoc );
  958. FreeLocationInfo( pLocations, cLocations );
  959. /* Add a single column exactly wide enough to fully display the widest
  960. ** member of the list.
  961. */
  962. {
  963. LV_COLUMN col;
  964. ZeroMemory( &col, sizeof(col) );
  965. col.mask = LVCF_FMT;
  966. col.fmt = LVCFMT_LEFT;
  967. ListView_InsertColumn( pInfo->hwndLvEnable, 0, &col );
  968. ListView_SetColumnWidth(
  969. pInfo->hwndLvEnable, 0, LVSCW_AUTOSIZE_USEHEADER );
  970. }
  971. }
  972. return fFocusSet;
  973. }
  974. BOOL
  975. AdInit(
  976. IN HWND hwndPage,
  977. IN OUT UPARGS* pArgs )
  978. /* Called on WM_INITDIALOG. 'hwndPage' is the handle of the property
  979. ** page. 'PArgs' is the arguments from the PropertySheet caller.
  980. **
  981. ** Return false if focus was set, true otherwise.
  982. */
  983. {
  984. UPINFO* pInfo;
  985. BOOL fFocusSet;
  986. HWND hwndUdAttempts;
  987. HWND hwndUdSeconds;
  988. HWND hwndUdIdle;
  989. DWORD dwErr;
  990. TRACE("AdInit");
  991. /* We're first page, if the user isn't
  992. * an admin.
  993. */
  994. pInfo = UpInit( hwndPage, pArgs );
  995. if (!pInfo)
  996. return TRUE;
  997. // Make sure that a default location is created if there isn't one. bug
  998. // 168631
  999. //
  1000. dwErr = TapiNoLocationDlg( g_hinstDll, &(pInfo->pArgs->hlineapp), hwndPage );
  1001. if (dwErr != 0)
  1002. {
  1003. // Error here is treated as a "cancel" per bug 288385.
  1004. //
  1005. return TRUE;
  1006. }
  1007. /* Initialize page-specific context information.
  1008. */
  1009. pInfo->hwndAd = hwndPage;
  1010. if (!pArgs->fNoUser)
  1011. {
  1012. pInfo->hwndLvEnable = GetDlgItem( hwndPage, CID_AD_LV_Enable );
  1013. ASSERT(pInfo->hwndLvEnable);
  1014. }
  1015. if (!pArgs->fNoUser)
  1016. {
  1017. DWORD dwFlag, dwErr;
  1018. DWORD cb;
  1019. /* Initialize the listview.
  1020. */
  1021. fFocusSet = AdFillLvEnable( pInfo );
  1022. /* Initialize autodial parameters.
  1023. */
  1024. dwFlag = FALSE;
  1025. cb = sizeof(dwFlag);
  1026. TRACE("RasGetAutodialParam(DCQ)");
  1027. dwErr = g_pRasGetAutodialParam(
  1028. RASADP_DisableConnectionQuery, &dwFlag, &cb );
  1029. TRACE1("RasGetAutodialParam=%d",dwErr);
  1030. /* Flip it because the API wants true to mean "disable".
  1031. */
  1032. CheckDlgButton( hwndPage, CID_AD_CB_AskBeforeAutodial, (BOOL )!dwFlag );
  1033. //
  1034. // pmay: 209762
  1035. //
  1036. // Initialize the "disable current session" checkbox
  1037. //
  1038. dwFlag = FALSE;
  1039. cb = sizeof(dwFlag);
  1040. dwErr = g_pRasGetAutodialParam(
  1041. RASADP_LoginSessionDisable, &dwFlag, &cb );
  1042. CheckDlgButton(
  1043. hwndPage,
  1044. CID_AD_CB_DisableThisSession,
  1045. (BOOL )dwFlag );
  1046. }
  1047. return !fFocusSet;
  1048. }
  1049. LVXDRAWINFO*
  1050. AdLvEnableCallback(
  1051. IN HWND hwndLv,
  1052. IN DWORD dwItem )
  1053. /* Enhanced list view callback to report drawing information. 'HwndLv' is
  1054. ** the handle of the list view control. 'DwItem' is the index of the item
  1055. ** being drawn.
  1056. **
  1057. ** Returns the address of the draw information.
  1058. */
  1059. {
  1060. /* The enhanced list view is used only to get the "wide selection bar"
  1061. ** feature so our option list is not very interesting.
  1062. **
  1063. ** Fields are 'nCols', 'dxIndent', 'dwFlags', 'adwFlags[]'.
  1064. */
  1065. static LVXDRAWINFO info = { 1, 0, 0, { 0 } };
  1066. return &info;
  1067. }
  1068. /*----------------------------------------------------------------------------
  1069. ** Callback property page
  1070. ** Listed alphabetically following dialog proc
  1071. **----------------------------------------------------------------------------
  1072. */
  1073. INT_PTR CALLBACK
  1074. CbDlgProc(
  1075. IN HWND hwnd,
  1076. IN UINT unMsg,
  1077. IN WPARAM wparam,
  1078. IN LPARAM lparam )
  1079. /* DialogProc callback for the Callback page of the User Preferences
  1080. ** property sheet. Parameters and return value are as described for
  1081. ** standard windows 'DialogProc's.
  1082. */
  1083. {
  1084. #if 0
  1085. TRACE4("CbDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  1086. (DWORD)hwnd,(DWORD)unMsg,(DWORD)wparam,(DWORD)lparam);
  1087. #endif
  1088. if (ListView_OwnerHandler(
  1089. hwnd, unMsg, wparam, lparam, CbutilLvNumbersCallback ))
  1090. {
  1091. return TRUE;
  1092. }
  1093. switch (unMsg)
  1094. {
  1095. case WM_INITDIALOG:
  1096. return CbInit( hwnd );
  1097. case WM_HELP:
  1098. case WM_CONTEXTMENU:
  1099. ContextHelp( g_adwCbHelp, hwnd, unMsg, wparam, lparam );
  1100. break;
  1101. case WM_NOTIFY:
  1102. {
  1103. switch (((NMHDR* )lparam)->code)
  1104. {
  1105. case NM_DBLCLK:
  1106. {
  1107. UPINFO* pInfo = UpContext( hwnd );
  1108. ASSERT(pInfo);
  1109. SendMessage( pInfo->hwndPbEdit, BM_CLICK, 0, 0 );
  1110. return TRUE;
  1111. }
  1112. case LVN_ITEMCHANGED:
  1113. {
  1114. UPINFO* pInfo = UpContext( hwnd );
  1115. ASSERT(pInfo);
  1116. CbUpdateLvAndPbState( pInfo );
  1117. return TRUE;
  1118. }
  1119. }
  1120. break;
  1121. }
  1122. case WM_COMMAND:
  1123. {
  1124. UPINFO* pInfo = UpContext( hwnd );
  1125. ASSERT(pInfo);
  1126. return CbCommand(
  1127. pInfo, HIWORD( wparam ), LOWORD( wparam ),(HWND )lparam );
  1128. }
  1129. }
  1130. return FALSE;
  1131. }
  1132. VOID
  1133. CbApply(
  1134. IN UPINFO* pInfo )
  1135. /* Saves the contents of the property page. 'PInfo' is the property sheet
  1136. ** context.
  1137. */
  1138. {
  1139. TRACE("CbApply");
  1140. if (IsDlgButtonChecked( pInfo->hwndCb, CID_CB_RB_No ))
  1141. pInfo->user.dwCallbackMode = CBM_No;
  1142. else if (IsDlgButtonChecked( pInfo->hwndCb, CID_CB_RB_Maybe ))
  1143. pInfo->user.dwCallbackMode = CBM_Maybe;
  1144. else
  1145. pInfo->user.dwCallbackMode = CBM_Yes;
  1146. CbutilSaveLv( pInfo->hwndLvNumbers, pInfo->user.pdtllistCallback );
  1147. }
  1148. BOOL
  1149. CbCommand(
  1150. IN UPINFO* pInfo,
  1151. IN WORD wNotification,
  1152. IN WORD wId,
  1153. IN HWND hwndCtrl )
  1154. /* Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
  1155. ** is the notification code of the command. 'wId' is the control/menu
  1156. ** identifier of the command. 'HwndCtrl' is the control window handle of
  1157. ** the command.
  1158. **
  1159. ** Returns true if processed message, false otherwise.
  1160. */
  1161. {
  1162. TRACE3("CbCommand(n=%d,i=%d,c=$%x)",
  1163. (DWORD)wNotification,(DWORD)wId,(ULONG_PTR )hwndCtrl);
  1164. switch (wId)
  1165. {
  1166. case CID_CB_RB_No:
  1167. case CID_CB_RB_Maybe:
  1168. case CID_CB_RB_Yes:
  1169. {
  1170. if (wNotification == BN_CLICKED)
  1171. {
  1172. CbUpdateLvAndPbState( pInfo );
  1173. if (wId == CID_CB_RB_Yes
  1174. && ListView_GetSelectedCount( pInfo->hwndLvNumbers ) == 0)
  1175. {
  1176. /* Nothing's selected, so select the first item, if any.
  1177. */
  1178. ListView_SetItemState( pInfo->hwndLvNumbers, 0,
  1179. LVIS_SELECTED, LVIS_SELECTED );
  1180. }
  1181. }
  1182. break;
  1183. }
  1184. case CID_CB_PB_Edit:
  1185. {
  1186. if (wNotification == BN_CLICKED)
  1187. CbutilEdit( pInfo->hwndCb, pInfo->hwndLvNumbers );
  1188. break;
  1189. }
  1190. case CID_CB_PB_Delete:
  1191. {
  1192. if (wNotification == BN_CLICKED)
  1193. CbutilDelete( pInfo->hwndCb, pInfo->hwndLvNumbers );
  1194. break;
  1195. }
  1196. }
  1197. return FALSE;
  1198. }
  1199. BOOL
  1200. CbInit(
  1201. IN HWND hwndPage )
  1202. /* Called on WM_INITDIALOG. 'hwndPage' is the handle of the property
  1203. ** page.
  1204. **
  1205. ** Return false if focus was set, true otherwise.
  1206. */
  1207. {
  1208. UPINFO* pInfo;
  1209. TRACE("CbInit");
  1210. pInfo = UpContext( hwndPage );
  1211. if (!pInfo)
  1212. return TRUE;
  1213. /* Initialize page-specific context information.
  1214. */
  1215. pInfo->hwndCb = hwndPage;
  1216. pInfo->hwndRbNo = GetDlgItem( hwndPage, CID_CB_RB_No );
  1217. ASSERT(pInfo->hwndRbNo);
  1218. pInfo->hwndRbMaybe = GetDlgItem( hwndPage, CID_CB_RB_Maybe );
  1219. ASSERT(pInfo->hwndRbMaybe);
  1220. pInfo->hwndRbYes = GetDlgItem( hwndPage, CID_CB_RB_Yes );
  1221. ASSERT(pInfo->hwndRbYes);
  1222. pInfo->hwndLvNumbers = GetDlgItem( hwndPage, CID_CB_LV_Numbers );
  1223. ASSERT(pInfo->hwndLvNumbers);
  1224. pInfo->hwndPbEdit = GetDlgItem( hwndPage, CID_CB_PB_Edit );
  1225. ASSERT(pInfo->hwndPbEdit);
  1226. pInfo->hwndPbDelete = GetDlgItem( hwndPage, CID_CB_PB_Delete );
  1227. ASSERT(pInfo->hwndPbDelete);
  1228. /* Initialize the listview.
  1229. */
  1230. CbutilFillLvNumbers(
  1231. pInfo->hwndCb, pInfo->hwndLvNumbers,
  1232. pInfo->user.pdtllistCallback, FALSE );
  1233. /* Set the radio button selection, which triggers appropriate
  1234. ** enabling/disabling.
  1235. */
  1236. {
  1237. HWND hwndRb;
  1238. if (pInfo->user.dwCallbackMode == CBM_No)
  1239. hwndRb = pInfo->hwndRbNo;
  1240. else if (pInfo->user.dwCallbackMode == CBM_Maybe)
  1241. hwndRb = pInfo->hwndRbMaybe;
  1242. else
  1243. {
  1244. ASSERT(pInfo->user.dwCallbackMode==CBM_Yes);
  1245. hwndRb = pInfo->hwndRbYes;
  1246. }
  1247. SendMessage( hwndRb, BM_CLICK, 0, 0 );
  1248. }
  1249. // pmay: If there are no devices available for callback,
  1250. // add some explanatory text and disable appropriate
  1251. // controls. Bug 168830
  1252. if (ListView_GetItemCount(pInfo->hwndLvNumbers) == 0)
  1253. {
  1254. // Uncheck if needed
  1255. if (Button_GetCheck(pInfo->hwndRbYes))
  1256. {
  1257. Button_SetCheck(pInfo->hwndRbMaybe, TRUE);
  1258. }
  1259. // Disable the windows.
  1260. EnableWindow(pInfo->hwndRbYes, FALSE);
  1261. EnableWindow(pInfo->hwndLvNumbers, FALSE);
  1262. }
  1263. return TRUE;
  1264. }
  1265. VOID
  1266. CbUpdateLvAndPbState(
  1267. IN UPINFO* pInfo )
  1268. /* Enables/disables the list view and associated buttons. ListView is
  1269. ** gray unless auto-callback is selected. Buttons gray unless
  1270. ** auto-callback selected and there is an item selected.
  1271. */
  1272. {
  1273. BOOL fEnableList;
  1274. BOOL fEnableEditButton, fEnableDeleteButton;
  1275. INT iSel;
  1276. HWND hwndLv;
  1277. // By default, we don't enable any buttons
  1278. fEnableDeleteButton = FALSE;
  1279. fEnableEditButton = FALSE;
  1280. // Only enable the list view if Yes is selected
  1281. //
  1282. fEnableList = Button_GetCheck( pInfo->hwndRbYes );
  1283. if (fEnableList)
  1284. {
  1285. hwndLv = pInfo->hwndLvNumbers;
  1286. if ( ListView_GetSelectedCount( hwndLv ) )
  1287. {
  1288. // The edit button should only be enabled if the
  1289. // listview is enabled and if one or more
  1290. // items is selected.
  1291. fEnableEditButton = TRUE;
  1292. //
  1293. // pmay: 213060
  1294. //
  1295. // The delete button is only enabled if all of the selected
  1296. // devices are not configured on the system. (since only
  1297. // non-installed devices can be removed from the list).
  1298. //
  1299. fEnableDeleteButton = TRUE;
  1300. for (iSel = ListView_GetNextItem( hwndLv, -1, LVNI_SELECTED );
  1301. iSel >= 0;
  1302. iSel = ListView_GetNextItem( hwndLv, iSel, LVNI_SELECTED )
  1303. )
  1304. {
  1305. LV_ITEM item;
  1306. ZeroMemory(&item, sizeof(item));
  1307. item.iItem = iSel;
  1308. item.mask = LVIF_PARAM;
  1309. if ( ListView_GetItem(hwndLv, &item) )
  1310. {
  1311. if (((CBCONTEXT*)item.lParam)->fConfigured)
  1312. {
  1313. fEnableDeleteButton = FALSE;
  1314. }
  1315. }
  1316. }
  1317. }
  1318. }
  1319. EnableWindow( pInfo->hwndLvNumbers, fEnableList );
  1320. EnableWindow( pInfo->hwndPbEdit, fEnableEditButton );
  1321. EnableWindow( pInfo->hwndPbDelete, fEnableDeleteButton );
  1322. }
  1323. /*-----------------------------------------------------
  1324. ** Utilities shared with router version of the listview
  1325. **-----------------------------------------------------
  1326. */
  1327. VOID
  1328. CbutilDelete(
  1329. IN HWND hwndDlg,
  1330. IN HWND hwndLvNumbers )
  1331. /* Called when the Delete button is pressed. 'PInfo' is the dialog
  1332. ** context.
  1333. */
  1334. {
  1335. MSGARGS msgargs;
  1336. INT nResponse;
  1337. TRACE("CbDelete");
  1338. ZeroMemory( &msgargs, sizeof(msgargs) );
  1339. msgargs.dwFlags = MB_YESNO + MB_ICONEXCLAMATION;
  1340. nResponse = MsgDlg( hwndDlg, SID_ConfirmDelDevice, &msgargs );
  1341. if (nResponse == IDYES)
  1342. {
  1343. INT iSel;
  1344. /* User has confirmed deletion of selected devices, so do it.
  1345. */
  1346. while ((iSel = ListView_GetNextItem(
  1347. hwndLvNumbers, -1, LVNI_SELECTED )) >= 0)
  1348. {
  1349. ListView_DeleteItem( hwndLvNumbers, iSel );
  1350. }
  1351. }
  1352. }
  1353. VOID
  1354. CbutilEdit(
  1355. IN HWND hwndDlg,
  1356. IN HWND hwndLvNumbers )
  1357. /* Called when the Edit button is pressed. 'HwndDlg' is the page/dialog
  1358. ** window. 'HwndLvNumbers' is the callback number listview window.
  1359. */
  1360. {
  1361. INT iSel;
  1362. TCHAR szBuf[ RAS_MaxCallbackNumber + 1 ];
  1363. TCHAR* pszNumber;
  1364. TRACE("CbutilEdit");
  1365. /* Load 'szBuf' with the current phone number of the first selected item.
  1366. */
  1367. iSel = ListView_GetNextItem( hwndLvNumbers, -1, LVNI_SELECTED );
  1368. if (iSel < 0)
  1369. return;
  1370. szBuf[ 0 ] = TEXT('\0');
  1371. ListView_GetItemText( hwndLvNumbers, iSel, 1,
  1372. szBuf, RAS_MaxCallbackNumber + 1 );
  1373. /* Popup dialog to edit the number.
  1374. */
  1375. pszNumber = NULL;
  1376. if (StringEditorDlg( hwndDlg, szBuf,
  1377. SID_EcbnTitle, SID_EcbnLabel, RAS_MaxCallbackNumber,
  1378. HID_ZE_ST_CallbackNumber, &pszNumber ))
  1379. {
  1380. /* OK pressed, so change the number on all selected items.
  1381. */
  1382. ASSERT(pszNumber);
  1383. do
  1384. {
  1385. ListView_SetItemText( hwndLvNumbers, iSel, 1, pszNumber );
  1386. }
  1387. while ((iSel = ListView_GetNextItem(
  1388. hwndLvNumbers, iSel, LVNI_SELECTED )) >= 0);
  1389. }
  1390. }
  1391. VOID
  1392. CbutilFillLvNumbers(
  1393. IN HWND hwndDlg,
  1394. IN HWND hwndLvNumbers,
  1395. IN DTLLIST* pListCallback,
  1396. IN BOOL fRouter )
  1397. /* Fill the listview with devices and phone numbers. 'HwndDlg' is the
  1398. ** page/dialog window. 'HwndLvNumbers' is the callback listview.
  1399. ** 'PListCallback' is the list of CALLBACKINFO. 'FRouter' is true if the
  1400. ** router ports should be enumerated, or false for regular dial-out ports.
  1401. **
  1402. ** Note: This routine should be called only once.
  1403. */
  1404. {
  1405. DWORD dwErr;
  1406. DTLLIST* pListPorts;
  1407. DTLNODE* pNodeCbi;
  1408. DTLNODE* pNodePort;
  1409. INT iItem;
  1410. TCHAR* psz;
  1411. TRACE("CbutilFillLvNumbers");
  1412. ListView_DeleteAllItems( hwndLvNumbers );
  1413. /* Add columns.
  1414. */
  1415. {
  1416. LV_COLUMN col;
  1417. TCHAR* pszHeader0;
  1418. TCHAR* pszHeader1;
  1419. pszHeader0 = PszFromId( g_hinstDll, SID_DeviceColHead );
  1420. pszHeader1 = PszFromId( g_hinstDll, SID_PhoneNumberColHead );
  1421. ZeroMemory( &col, sizeof(col) );
  1422. col.mask = LVCF_FMT + LVCF_TEXT;
  1423. col.fmt = LVCFMT_LEFT;
  1424. col.pszText = (pszHeader0) ? pszHeader0 : TEXT("");
  1425. ListView_InsertColumn( hwndLvNumbers, 0, &col );
  1426. ZeroMemory( &col, sizeof(col) );
  1427. col.mask = LVCF_FMT + LVCF_SUBITEM + LVCF_TEXT;
  1428. col.fmt = LVCFMT_LEFT;
  1429. col.pszText = (pszHeader1) ? pszHeader1 : TEXT("");
  1430. col.iSubItem = 1;
  1431. ListView_InsertColumn( hwndLvNumbers, 1, &col );
  1432. Free0( pszHeader0 );
  1433. Free0( pszHeader1 );
  1434. }
  1435. /* Add the modem and adapter images.
  1436. */
  1437. ListView_SetDeviceImageList( hwndLvNumbers, g_hinstDll );
  1438. /* Load listview with callback device/number pairs saved as user
  1439. ** preferences.
  1440. */
  1441. iItem = 0;
  1442. ASSERT(pListCallback);
  1443. for (pNodeCbi = DtlGetFirstNode( pListCallback );
  1444. pNodeCbi;
  1445. pNodeCbi = DtlGetNextNode( pNodeCbi ), ++iItem)
  1446. {
  1447. CALLBACKINFO* pCbi;
  1448. LV_ITEM item;
  1449. pCbi = (CALLBACKINFO* )DtlGetData( pNodeCbi );
  1450. ASSERT(pCbi);
  1451. ASSERT(pCbi->pszPortName);
  1452. ASSERT(pCbi->pszDeviceName);
  1453. ASSERT(pCbi->pszNumber);
  1454. if (pCbi->dwDeviceType != RASET_Vpn) {
  1455. psz = PszFromDeviceAndPort( pCbi->pszDeviceName, pCbi->pszPortName );
  1456. if (psz)
  1457. {
  1458. // pmay: 213060
  1459. //
  1460. // Allocate and initialize the context.
  1461. //
  1462. CBCONTEXT * pCbCtx;
  1463. pCbCtx = (CBCONTEXT*) Malloc (sizeof(CBCONTEXT));
  1464. if (pCbCtx == NULL)
  1465. {
  1466. continue;
  1467. }
  1468. pCbCtx->pszPortName = pCbi->pszPortName;
  1469. pCbCtx->pszDeviceName = pCbi->pszDeviceName;
  1470. pCbCtx->dwDeviceType = pCbi->dwDeviceType;
  1471. pCbCtx->fConfigured = FALSE;
  1472. ZeroMemory( &item, sizeof(item) );
  1473. item.mask = LVIF_TEXT + LVIF_IMAGE + LVIF_PARAM;
  1474. item.iItem = iItem;
  1475. item.pszText = psz;
  1476. item.iImage =
  1477. ((PBDEVICETYPE )pCbi->dwDeviceType == PBDT_Modem)
  1478. ? DI_Modem : DI_Adapter;
  1479. item.lParam = (LPARAM )pCbCtx;
  1480. ListView_InsertItem( hwndLvNumbers, &item );
  1481. ListView_SetItemText( hwndLvNumbers, iItem, 1, pCbi->pszNumber );
  1482. Free( psz );
  1483. }
  1484. }
  1485. }
  1486. /* Add any devices installed but not already in the list.
  1487. */
  1488. dwErr = LoadPortsList2( NULL, &pListPorts, fRouter );
  1489. if (dwErr != 0)
  1490. {
  1491. ErrorDlg( hwndDlg, SID_OP_LoadPortInfo, dwErr, NULL );
  1492. }
  1493. else
  1494. {
  1495. for (pNodePort = DtlGetFirstNode( pListPorts );
  1496. pNodePort;
  1497. pNodePort = DtlGetNextNode( pNodePort ))
  1498. {
  1499. PBPORT* pPort = (PBPORT* )DtlGetData( pNodePort );
  1500. INT i = -1;
  1501. BOOL bPortAlreadyInLv = FALSE;
  1502. ASSERT(pPort);
  1503. // pmay: 213060
  1504. //
  1505. // Search for the configured item in the list view
  1506. //
  1507. while ((i = ListView_GetNextItem(
  1508. hwndLvNumbers,
  1509. i,
  1510. LVNI_ALL )) >= 0)
  1511. {
  1512. LV_ITEM item;
  1513. CBCONTEXT * pCbCtx;
  1514. ZeroMemory( &item, sizeof(item) );
  1515. item.mask = LVIF_PARAM;
  1516. item.iItem = i;
  1517. if (!ListView_GetItem( hwndLvNumbers, &item ))
  1518. {
  1519. continue;
  1520. }
  1521. // Get the context
  1522. //
  1523. pCbCtx = (CBCONTEXT*)item.lParam;
  1524. if (! pCbCtx)
  1525. {
  1526. continue;
  1527. }
  1528. // If the current item in the list view matches the
  1529. // current port, then we know that the current item
  1530. // is configured on the system.
  1531. if ((lstrcmpi( pPort->pszPort, pCbCtx->pszPortName ) == 0) &&
  1532. (lstrcmpi( pPort->pszDevice, pCbCtx->pszDeviceName ) == 0)
  1533. )
  1534. {
  1535. bPortAlreadyInLv = TRUE;
  1536. pCbCtx->fConfigured = TRUE;
  1537. break;
  1538. }
  1539. }
  1540. if (! bPortAlreadyInLv)
  1541. {
  1542. LV_ITEM item;
  1543. PBDEVICETYPE pbdt;
  1544. /* The device/port was not in the callback list. Append it
  1545. ** to the listview with empty phone number.
  1546. */
  1547. if ((pPort->dwType != RASET_Vpn) &&
  1548. (pPort->dwType != RASET_Direct) &&
  1549. (pPort->dwType != RASET_Broadband)
  1550. )
  1551. {
  1552. psz = PszFromDeviceAndPort(
  1553. pPort->pszDevice,
  1554. pPort->pszPort );
  1555. if (psz)
  1556. {
  1557. // pmay: 213060
  1558. //
  1559. // Allocate and initialize the context.
  1560. //
  1561. CBCONTEXT * pCbCtx;
  1562. pCbCtx = (CBCONTEXT*) Malloc (sizeof(CBCONTEXT));
  1563. if (pCbCtx == NULL)
  1564. {
  1565. continue;
  1566. }
  1567. pCbCtx->pszPortName = pPort->pszPort;
  1568. pCbCtx->pszDeviceName = pPort->pszDevice;
  1569. pCbCtx->dwDeviceType = (DWORD) pPort->pbdevicetype;
  1570. pCbCtx->fConfigured = TRUE;
  1571. ZeroMemory( &item, sizeof(item) );
  1572. item.mask = LVIF_TEXT + LVIF_IMAGE + LVIF_PARAM;
  1573. item.iItem = iItem;
  1574. item.pszText = psz;
  1575. item.iImage =
  1576. (pPort->pbdevicetype == PBDT_Modem)
  1577. ? DI_Modem : DI_Adapter;
  1578. item.lParam = (LPARAM ) pCbCtx;
  1579. ListView_InsertItem( hwndLvNumbers, &item );
  1580. ListView_SetItemText(
  1581. hwndLvNumbers,
  1582. iItem,
  1583. 1,
  1584. TEXT(""));
  1585. ++iItem;
  1586. Free( psz );
  1587. }
  1588. }
  1589. }
  1590. }
  1591. DtlDestroyList( pListPorts, DestroyPortNode );
  1592. }
  1593. /* Auto-size columns to look good with the text they contain.
  1594. */
  1595. ListView_SetColumnWidth( hwndLvNumbers, 0, LVSCW_AUTOSIZE_USEHEADER );
  1596. ListView_SetColumnWidth( hwndLvNumbers, 1, LVSCW_AUTOSIZE_USEHEADER );
  1597. }
  1598. VOID
  1599. CbutilLvNumbersCleanup(
  1600. IN HWND hwndLvNumbers )
  1601. /* Cleans up after CbutilFillLvNumbers.
  1602. */
  1603. {
  1604. INT i;
  1605. i = -1;
  1606. while ((i = ListView_GetNextItem( hwndLvNumbers, i, LVNI_ALL )) >= 0)
  1607. {
  1608. LV_ITEM item;
  1609. ZeroMemory( &item, sizeof(item) );
  1610. item.mask = LVIF_PARAM;
  1611. item.iItem = i;
  1612. if (!ListView_GetItem( hwndLvNumbers, &item ))
  1613. continue;
  1614. // Free the context
  1615. Free0( (PVOID) item.lParam );
  1616. }
  1617. }
  1618. LVXDRAWINFO*
  1619. CbutilLvNumbersCallback(
  1620. IN HWND hwndLv,
  1621. IN DWORD dwItem )
  1622. /* Enhanced list view callback to report drawing information. 'HwndLv' is
  1623. ** the handle of the list view control. 'DwItem' is the index of the item
  1624. ** being drawn.
  1625. **
  1626. ** Returns the address of the column information.
  1627. */
  1628. {
  1629. /* Use "wide selection bar" feature and the other recommended options.
  1630. **
  1631. ** Fields are 'nCols', 'dxIndent', 'dwFlags', 'adwFlags[]'.
  1632. */
  1633. static LVXDRAWINFO info =
  1634. { 2, 0, LVXDI_Blend50Dis + LVXDI_DxFill, { 0, 0 } };
  1635. return &info;
  1636. }
  1637. VOID
  1638. CbutilSaveLv(
  1639. IN HWND hwndLvNumbers,
  1640. OUT DTLLIST* pListCallback )
  1641. /* Replace list 'pListCallback' contents with that of the listview
  1642. ** 'hwndLvNumbers'.
  1643. */
  1644. {
  1645. DTLNODE* pNode;
  1646. INT i;
  1647. TRACE("CbutilSaveLv");
  1648. /* Empty the list of callback info, then re-populate from the listview.
  1649. */
  1650. while (pNode = DtlGetFirstNode( pListCallback ))
  1651. {
  1652. DtlRemoveNode( pListCallback, pNode );
  1653. DestroyCallbackNode( pNode );
  1654. }
  1655. i = -1;
  1656. while ((i = ListView_GetNextItem( hwndLvNumbers, i, LVNI_ALL )) >= 0)
  1657. {
  1658. LV_ITEM item;
  1659. TCHAR* pszDevice;
  1660. TCHAR* pszPort;
  1661. TCHAR szDP[ RAS_MaxDeviceName + 2 + MAX_PORT_NAME + 1 + 1 ];
  1662. TCHAR szNumber[ RAS_MaxCallbackNumber + 1 ];
  1663. szDP[ 0 ] = TEXT('\0');
  1664. ZeroMemory( &item, sizeof(item) );
  1665. item.mask = LVIF_TEXT | LVIF_PARAM;
  1666. item.iItem = i;
  1667. item.pszText = szDP;
  1668. item.cchTextMax = sizeof(szDP) / sizeof(TCHAR);
  1669. if (!ListView_GetItem( hwndLvNumbers, &item ))
  1670. continue;
  1671. szNumber[ 0 ] = TEXT('\0');
  1672. ListView_GetItemText( hwndLvNumbers, i, 1,
  1673. szNumber, RAS_MaxCallbackNumber + 1 );
  1674. if (!DeviceAndPortFromPsz( szDP, &pszDevice, &pszPort ))
  1675. continue;
  1676. pNode = CreateCallbackNode(
  1677. pszPort,
  1678. pszDevice,
  1679. szNumber,
  1680. ((CBCONTEXT*)item.lParam)->dwDeviceType );
  1681. if (pNode)
  1682. DtlAddNodeLast( pListCallback, pNode );
  1683. Free( pszDevice );
  1684. Free( pszPort );
  1685. }
  1686. }
  1687. /*----------------------------------------------------------------------------
  1688. ** Connections Preferences property page
  1689. ** Listed alphabetically following dialog proc
  1690. **----------------------------------------------------------------------------
  1691. */
  1692. INT_PTR CALLBACK
  1693. CoDlgProc(
  1694. IN HWND hwnd,
  1695. IN UINT unMsg,
  1696. IN WPARAM wparam,
  1697. IN LPARAM lparam )
  1698. {
  1699. switch (unMsg)
  1700. {
  1701. case WM_INITDIALOG:
  1702. return CoInit( hwnd, (UPARGS* )(((PROPSHEETPAGE* )lparam)->lParam) );
  1703. case WM_HELP:
  1704. case WM_CONTEXTMENU:
  1705. ContextHelp( g_adwCoHelp, hwnd, unMsg, wparam, lparam );
  1706. break;
  1707. case WM_NOTIFY:
  1708. {
  1709. switch (((NMHDR* )lparam)->code)
  1710. {
  1711. case PSN_APPLY:
  1712. {
  1713. BOOL fValid;
  1714. UPINFO *pUpInfo;
  1715. TRACE("CoAPPLY");
  1716. pUpInfo = UpContext(hwnd);
  1717. if(NULL != pUpInfo)
  1718. {
  1719. CoApply( pUpInfo );
  1720. }
  1721. /* Call UpApply only on first page.
  1722. */
  1723. fValid = UpApply( hwnd );
  1724. SetWindowLong(
  1725. hwnd, DWLP_MSGRESULT,
  1726. (fValid)
  1727. ? PSNRET_NOERROR
  1728. : PSNRET_INVALID_NOCHANGEPAGE );
  1729. return TRUE;
  1730. }
  1731. }
  1732. break;
  1733. }
  1734. }
  1735. return FALSE;
  1736. }
  1737. BOOL
  1738. CoApply(
  1739. IN UPINFO* pInfo )
  1740. // Return true to allow application of property sheet, false
  1741. // to refuse.
  1742. {
  1743. // If we're not the logon user, go ahead and commit
  1744. // the global phonebook editing flag.
  1745. if (! pInfo->pArgs->fNoUser )
  1746. {
  1747. BOOL bAllow;
  1748. bAllow = IsDlgButtonChecked(
  1749. pInfo->hwndCo,
  1750. CID_CO_CB_AllowConnectionModification );
  1751. if ( (!!bAllow) != (!!pInfo->userLogon.fAllowLogonPhonebookEdits) )
  1752. {
  1753. pInfo->userLogon.fAllowLogonPhonebookEdits = !!bAllow;
  1754. pInfo->userLogon.fDirty = TRUE;
  1755. }
  1756. }
  1757. return TRUE;
  1758. }
  1759. BOOL
  1760. CoInit(
  1761. IN HWND hwndPage,
  1762. IN OUT UPARGS* pArgs )
  1763. /* Called on WM_INITDIALOG. 'hwndPage' is the handle of the property
  1764. ** page. 'PArgs' is the arguments from the PropertySheet caller.
  1765. **
  1766. ** Return false if focus was set, true otherwise.
  1767. */
  1768. {
  1769. UPINFO * pInfo = NULL;
  1770. /* We're first page, so initialize the property sheet.
  1771. */
  1772. pInfo = UpInit( hwndPage, pArgs );
  1773. if (!pInfo)
  1774. return TRUE;
  1775. pInfo->hwndCo = hwndPage;
  1776. // Set the flag for allowing phonebook edits
  1777. if (! pInfo->pArgs->fNoUser )
  1778. {
  1779. Button_SetCheck (
  1780. GetDlgItem (pInfo->hwndCo, CID_CO_CB_AllowConnectionModification),
  1781. pInfo->userLogon.fAllowLogonPhonebookEdits);
  1782. }
  1783. return TRUE;
  1784. }
  1785. #if 0
  1786. /*----------------------------------------------------------------------------
  1787. ** General Preferences property page
  1788. ** Listed alphabetically following dialog proc
  1789. **----------------------------------------------------------------------------
  1790. */
  1791. INT_PTR CALLBACK
  1792. GpDlgProc(
  1793. IN HWND hwnd,
  1794. IN UINT unMsg,
  1795. IN WPARAM wparam,
  1796. IN LPARAM lparam )
  1797. /* DialogProc callback for the General page of the User Preferences
  1798. ** property sheet. Parameters and return value are as described for
  1799. ** standard windows 'DialogProc's.
  1800. */
  1801. {
  1802. #if 0
  1803. TRACE4("GpDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  1804. (DWORD)hwnd,(DWORD)unMsg,(DWORD)wparam,(DWORD)lparam);
  1805. #endif
  1806. switch (unMsg)
  1807. {
  1808. case WM_INITDIALOG:
  1809. return GpInit( hwnd );
  1810. case WM_HELP:
  1811. case WM_CONTEXTMENU:
  1812. ContextHelp( g_adwGpHelp, hwnd, unMsg, wparam, lparam );
  1813. break;
  1814. case WM_NOTIFY:
  1815. {
  1816. switch (((NMHDR* )lparam)->code)
  1817. {
  1818. case PSN_RESET:
  1819. {
  1820. /* Call UpCancel only on first page.
  1821. */
  1822. TRACE("GpRESET");
  1823. UpCancel( hwnd );
  1824. SetWindowLong( hwnd, DWLP_MSGRESULT, FALSE );
  1825. break;
  1826. }
  1827. }
  1828. break;
  1829. }
  1830. case WM_COMMAND:
  1831. {
  1832. UPINFO* pInfo = UpContext( hwnd );
  1833. ASSERT(pInfo);
  1834. return GpCommand(
  1835. pInfo, HIWORD( wparam ), LOWORD( wparam ),(HWND )lparam );
  1836. }
  1837. case WM_DESTROY:
  1838. {
  1839. /* UpTerm will handle making sure it only does its
  1840. ** thing once
  1841. */
  1842. UpTerm( hwnd );
  1843. break;
  1844. }
  1845. }
  1846. return FALSE;
  1847. }
  1848. VOID
  1849. GpApply(
  1850. IN UPINFO* pInfo )
  1851. /* Saves the contents of the property page. 'PInfo' is the property sheet
  1852. ** context.
  1853. */
  1854. {
  1855. DWORD dwErr;
  1856. TRACE("GpApply");
  1857. pInfo->user.fUseLocation =
  1858. IsDlgButtonChecked( pInfo->hwndGp, CID_GP_CB_Location );
  1859. pInfo->user.fPreviewPhoneNumber =
  1860. IsDlgButtonChecked( pInfo->hwndGp, CID_GP_CB_Preview );
  1861. pInfo->user.fShowConnectStatus =
  1862. IsDlgButtonChecked( pInfo->hwndGp, CID_GP_CB_Progress );
  1863. pInfo->user.fCloseOnDial =
  1864. IsDlgButtonChecked( pInfo->hwndGp, CID_GP_CB_CloseOnDial );
  1865. pInfo->user.fNewEntryWizard =
  1866. IsDlgButtonChecked( pInfo->hwndGp, CID_GP_CB_UseWizard );
  1867. if (pInfo->pArgs->fNoUser)
  1868. {
  1869. pInfo->user.fAllowLogonPhonebookEdits =
  1870. IsDlgButtonChecked( pInfo->hwndGp, CID_GP_CB_PhonebookEdits );
  1871. pInfo->user.fAllowLogonLocationEdits =
  1872. IsDlgButtonChecked( pInfo->hwndGp, CID_GP_CB_LocationEdits );
  1873. }
  1874. else
  1875. {
  1876. DWORD dwFlag;
  1877. pInfo->user.fShowLights =
  1878. IsDlgButtonChecked( pInfo->hwndGp, CID_GP_CB_Lights );
  1879. /* Flip it because the API wants true to mean "disable".
  1880. */
  1881. dwFlag = (DWORD )!IsDlgButtonChecked(
  1882. pInfo->hwndGp, CID_GP_CB_AutodialPrompt );
  1883. TRACE1("RasSetAutodialParam(%d)",dwFlag);
  1884. dwErr = g_pRasSetAutodialParam( RASADP_DisableConnectionQuery,
  1885. &dwFlag, sizeof(dwFlag) );
  1886. TRACE1("RasSetAutodialParam=%d",dwErr);
  1887. }
  1888. }
  1889. BOOL
  1890. GpCommand(
  1891. IN UPINFO* pInfo,
  1892. IN WORD wNotification,
  1893. IN WORD wId,
  1894. IN HWND hwndCtrl )
  1895. /* Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
  1896. ** is the notification code of the command. 'wId' is the control/menu
  1897. ** identifier of the command. 'HwndCtrl' is the control window handle of
  1898. ** the command.
  1899. **
  1900. ** Returns true if processed message, false otherwise.
  1901. */
  1902. {
  1903. TRACE3("GpCommand(n=%d,i=%d,c=$%x)",
  1904. (DWORD)wNotification,(DWORD)wId,(ULONG_PTR )hwndCtrl);
  1905. if (pInfo->pArgs->fNoUser)
  1906. {
  1907. switch (wId)
  1908. {
  1909. case CID_GP_CB_Location:
  1910. case CID_GP_CB_PhonebookEdits:
  1911. {
  1912. if (wNotification == BN_CLICKED)
  1913. GpUpdateCbStates( pInfo );
  1914. }
  1915. break;
  1916. }
  1917. }
  1918. return FALSE;
  1919. }
  1920. BOOL
  1921. GpInit(
  1922. IN HWND hwndPage )
  1923. /* Called on WM_INITDIALOG. 'hwndPage' is the handle of the property
  1924. ** page.
  1925. **
  1926. ** Return false if focus was set, true otherwise.
  1927. */
  1928. {
  1929. DWORD dwErr;
  1930. UPINFO* pInfo;
  1931. TRACE("GpInit");
  1932. pInfo = UpContext( hwndPage );
  1933. if (!pInfo)
  1934. return TRUE;
  1935. /* Initialize page-specific context information.
  1936. */
  1937. pInfo->hwndGp = hwndPage;
  1938. /* Initialize page.
  1939. */
  1940. CheckDlgButton( hwndPage, CID_GP_CB_Preview,
  1941. pInfo->user.fPreviewPhoneNumber );
  1942. CheckDlgButton( hwndPage, CID_GP_CB_Location,
  1943. pInfo->user.fUseLocation );
  1944. CheckDlgButton( hwndPage, CID_GP_CB_Progress,
  1945. pInfo->user.fShowConnectStatus );
  1946. CheckDlgButton( hwndPage, CID_GP_CB_CloseOnDial,
  1947. pInfo->user.fCloseOnDial );
  1948. CheckDlgButton( hwndPage, CID_GP_CB_UseWizard,
  1949. pInfo->user.fNewEntryWizard );
  1950. if (pInfo->pArgs->fNoUser)
  1951. {
  1952. /* Edit restriction check boxes for logon mode only.
  1953. */
  1954. CheckDlgButton( hwndPage, CID_GP_CB_PhonebookEdits,
  1955. pInfo->user.fAllowLogonPhonebookEdits );
  1956. CheckDlgButton( hwndPage, CID_GP_CB_LocationEdits,
  1957. pInfo->user.fAllowLogonLocationEdits );
  1958. GpUpdateCbStates( pInfo );
  1959. }
  1960. else
  1961. {
  1962. DWORD dwFlag;
  1963. DWORD cb;
  1964. /* Start rasmon check box for non-logon mode only.
  1965. */
  1966. CheckDlgButton( hwndPage, CID_GP_CB_Lights,
  1967. pInfo->user.fShowLights );
  1968. /* Autodial prompt check box for non-logon mode only.
  1969. */
  1970. dwFlag = FALSE;
  1971. cb = sizeof(dwFlag);
  1972. TRACE("RasGetAutodialParam(DCQ)");
  1973. dwErr = g_pRasGetAutodialParam(
  1974. RASADP_DisableConnectionQuery, &dwFlag, &cb );
  1975. TRACE1("RasGetAutodialParam=%d",dwErr);
  1976. /* Flip it because the API wants true to mean "disable".
  1977. */
  1978. CheckDlgButton( hwndPage, CID_GP_CB_AutodialPrompt, (BOOL )!dwFlag );
  1979. }
  1980. return TRUE;
  1981. }
  1982. VOID
  1983. GpUpdateCbStates(
  1984. IN UPINFO* pInfo )
  1985. /* Updates the enable/disable state of dependent checkboxes.
  1986. */
  1987. {
  1988. BOOL fLocation;
  1989. BOOL fPbEdits;
  1990. ASSERT(pInfo->pArgs->fNoUser);
  1991. fLocation = IsDlgButtonChecked( pInfo->hwndGp, CID_GP_CB_Location );
  1992. if (!fLocation)
  1993. CheckDlgButton( pInfo->hwndGp, CID_GP_CB_LocationEdits, FALSE );
  1994. EnableWindow( GetDlgItem( pInfo->hwndGp, CID_GP_CB_LocationEdits ),
  1995. fLocation );
  1996. fPbEdits = IsDlgButtonChecked( pInfo->hwndGp, CID_GP_CB_PhonebookEdits );
  1997. if (!fPbEdits)
  1998. CheckDlgButton( pInfo->hwndGp, CID_GP_CB_UseWizard, FALSE );
  1999. EnableWindow( GetDlgItem( pInfo->hwndGp, CID_GP_CB_UseWizard ),
  2000. fPbEdits );
  2001. }
  2002. /*----------------------------------------------------------------------------
  2003. ** Phone List property page
  2004. ** Listed alphabetically following dialog proc
  2005. **----------------------------------------------------------------------------
  2006. */
  2007. INT_PTR CALLBACK
  2008. PlDlgProc(
  2009. IN HWND hwnd,
  2010. IN UINT unMsg,
  2011. IN WPARAM wparam,
  2012. IN LPARAM lparam )
  2013. /* DialogProc callback for the Phone List page of the User Preferences
  2014. ** Property sheet. Parameters and return value are as described for
  2015. ** standard windows 'DialogProc's.
  2016. */
  2017. {
  2018. #if 0
  2019. TRACE4("PlDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  2020. (DWORD)hwnd,(DWORD)unMsg,(DWORD)wparam,(DWORD)lparam);
  2021. #endif
  2022. switch (unMsg)
  2023. {
  2024. case WM_INITDIALOG:
  2025. return PlInit( hwnd );
  2026. case WM_HELP:
  2027. case WM_CONTEXTMENU:
  2028. ContextHelp( g_adwPlHelp, hwnd, unMsg, wparam, lparam );
  2029. break;
  2030. case WM_COMMAND:
  2031. {
  2032. UPINFO* pInfo = UpContext( hwnd );
  2033. ASSERT(pInfo);
  2034. return PlCommand(
  2035. pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  2036. }
  2037. }
  2038. return FALSE;
  2039. }
  2040. BOOL
  2041. PlApply(
  2042. IN UPINFO* pInfo )
  2043. /* Saves the contents of the property page. 'PInfo' is the property sheet
  2044. ** context.
  2045. **
  2046. ** Returns false if invalid and can't dismiss, otherwise true.
  2047. */
  2048. {
  2049. DWORD dwErr;
  2050. DWORD dwOldMode;
  2051. DWORD dwNewMode;
  2052. TCHAR* pszOldPersonal;
  2053. TCHAR* pszNewPersonal;
  2054. TCHAR* pszOldAlternate;
  2055. TCHAR* pszNewAlternate;
  2056. PBFILE* pFile;
  2057. TRACE("PlApply");
  2058. dwOldMode = pInfo->user.dwPhonebookMode;
  2059. if (Button_GetCheck( pInfo->hwndRbSystem ))
  2060. dwNewMode = PBM_System;
  2061. else if (Button_GetCheck( pInfo->hwndRbPersonal ))
  2062. dwNewMode = PBM_Personal;
  2063. else
  2064. dwNewMode = PBM_Alternate;
  2065. if (!pInfo->user.pszAlternatePath)
  2066. pInfo->user.pszAlternatePath = StrDup( TEXT("") );
  2067. if (!pInfo->user.pszPersonalFile)
  2068. pInfo->user.pszPersonalFile = StrDup( TEXT("") );
  2069. pszOldAlternate = pInfo->user.pszAlternatePath;
  2070. pszOldPersonal = pInfo->user.pszPersonalFile;
  2071. pszNewAlternate = GetText( pInfo->hwndClbAlternates );
  2072. if (!pszOldAlternate || !pszOldPersonal || !pszNewAlternate)
  2073. {
  2074. ErrorDlg( pInfo->hwndDlg, SID_OP_LoadPhonebook,
  2075. ERROR_NOT_ENOUGH_MEMORY, NULL );
  2076. return TRUE;
  2077. }
  2078. if (dwNewMode == PBM_Alternate && IsAllWhite( pszNewAlternate ))
  2079. {
  2080. /* Alternate phonebook mode, but no path. Tell user to fix it.
  2081. */
  2082. MsgDlg( pInfo->hwndDlg, SID_NoAltPath, NULL );
  2083. //PropSheet_SetCurSel( pInfo->hwndDlg, NULL, UP_PlPage );
  2084. SetFocus( pInfo->hwndClbAlternates );
  2085. ComboBox_SetEditSel( pInfo->hwndClbAlternates, 0, -1 );
  2086. return FALSE;
  2087. }
  2088. if (dwNewMode == dwOldMode
  2089. && (dwNewMode != PBM_Alternate
  2090. || lstrcmpi( pszNewAlternate, pszOldAlternate ) == 0))
  2091. {
  2092. /* User made no changes.
  2093. */
  2094. TRACE("No phonebook change.");
  2095. Free0( pszNewAlternate );
  2096. return TRUE;
  2097. }
  2098. /* User changed phonebook settings.
  2099. */
  2100. if (dwNewMode == PBM_Personal && IsAllWhite( pszOldPersonal ))
  2101. {
  2102. /* Create the personal phonebook and tell user what happened.
  2103. */
  2104. dwErr = InitPersonalPhonebook( &pszNewPersonal );
  2105. if (dwErr != 0)
  2106. {
  2107. ErrorDlg( pInfo->hwndDlg, SID_OP_MakePhonebook, dwErr, NULL );
  2108. Free( pszNewAlternate );
  2109. return TRUE;
  2110. }
  2111. ASSERT(pszNewPersonal);
  2112. MsgDlg( pInfo->hwndDlg, SID_NewPhonebook, NULL );
  2113. }
  2114. else
  2115. pszNewPersonal = NULL;
  2116. pInfo->user.dwPhonebookMode = dwNewMode;
  2117. pInfo->user.pszAlternatePath = pszNewAlternate;
  2118. if (pszNewPersonal)
  2119. pInfo->user.pszPersonalFile = pszNewPersonal;
  2120. if (pInfo->pArgs->ppFile)
  2121. {
  2122. /* Open the new phonebook returning the associated file context block
  2123. ** to the stub API caller.
  2124. */
  2125. pFile = Malloc( sizeof(*pFile) );
  2126. if (!pFile)
  2127. {
  2128. ErrorDlg( pInfo->hwndDlg, SID_OP_LoadPhonebook,
  2129. ERROR_NOT_ENOUGH_MEMORY, NULL );
  2130. Free0( pszNewPersonal );
  2131. Free0( pszNewAlternate );
  2132. return TRUE;
  2133. }
  2134. dwErr = ReadPhonebookFile( NULL, &pInfo->user, NULL, 0, pFile );
  2135. if (dwErr != 0)
  2136. {
  2137. ErrorDlg( pInfo->hwndDlg, SID_OP_LoadPhonebook,
  2138. ERROR_NOT_ENOUGH_MEMORY, NULL );
  2139. pInfo->user.dwPhonebookMode = dwOldMode;
  2140. pInfo->user.pszAlternatePath = pszOldAlternate;
  2141. if (pszNewPersonal)
  2142. pInfo->user.pszPersonalFile = pszOldPersonal;
  2143. Free0( pszNewPersonal );
  2144. Free0( pszNewAlternate );
  2145. Free( pFile );
  2146. return TRUE;
  2147. }
  2148. /* Return opened file to stub API caller.
  2149. */
  2150. *pInfo->pArgs->ppFile = pFile;
  2151. }
  2152. Free0( pszOldAlternate );
  2153. if (pszNewPersonal)
  2154. Free0( pszOldPersonal );
  2155. /* Add the edit field path to the list, if it's not already.
  2156. */
  2157. if (!IsAllWhite( pszNewAlternate ))
  2158. {
  2159. DTLNODE* pNode;
  2160. for (pNode = DtlGetFirstNode( pInfo->user.pdtllistPhonebooks );
  2161. pNode;
  2162. pNode = DtlGetNextNode( pNode ))
  2163. {
  2164. TCHAR* psz;
  2165. psz = (TCHAR* )DtlGetData( pNode );
  2166. ASSERT(psz);
  2167. if (lstrcmpi( psz, pszNewAlternate ) == 0)
  2168. break;
  2169. }
  2170. if (!pNode)
  2171. {
  2172. pNode = CreatePszNode( pszNewAlternate );
  2173. if (pNode)
  2174. DtlAddNodeFirst( pInfo->user.pdtllistPhonebooks, pNode );
  2175. else
  2176. Free( pszNewAlternate );
  2177. }
  2178. }
  2179. return TRUE;
  2180. }
  2181. BOOL
  2182. PlCommand(
  2183. IN UPINFO* pInfo,
  2184. IN WORD wNotification,
  2185. IN WORD wId,
  2186. IN HWND hwndCtrl )
  2187. /* Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
  2188. ** is the notification code of the command. 'wId' is the control/menu
  2189. ** identifier of the command. 'HwndCtrl' is the control window handle of
  2190. ** the command.
  2191. **
  2192. ** Returns true if processed message, false otherwise.
  2193. */
  2194. {
  2195. TRACE3("PlCommand(n=%d,i=%d,c=$%x)",
  2196. (DWORD)wNotification,(DWORD)wId,(ULONG_PTR )hwndCtrl);
  2197. switch (wId)
  2198. {
  2199. case CID_PL_RB_SystemList:
  2200. case CID_PL_RB_PersonalList:
  2201. {
  2202. if (wNotification == BN_CLICKED)
  2203. {
  2204. EnableWindow( pInfo->hwndClbAlternates, FALSE );
  2205. EnableWindow( pInfo->hwndPbBrowse, FALSE );
  2206. }
  2207. return TRUE;
  2208. }
  2209. case CID_PL_RB_AlternateList:
  2210. {
  2211. if (wNotification == BN_CLICKED)
  2212. {
  2213. EnableWindow( pInfo->hwndClbAlternates, TRUE );
  2214. EnableWindow( pInfo->hwndPbBrowse, TRUE );
  2215. }
  2216. break;
  2217. }
  2218. case CID_PL_PB_Browse:
  2219. {
  2220. PlBrowse( pInfo );
  2221. return TRUE;
  2222. }
  2223. }
  2224. return FALSE;
  2225. }
  2226. VOID
  2227. PlBrowse(
  2228. IN UPINFO* pInfo )
  2229. /* Called when the Browse button is pressed. 'PInfo' is the property
  2230. ** sheet context.
  2231. */
  2232. {
  2233. OPENFILENAME ofn;
  2234. TCHAR szBuf[ MAX_PATH + 1 ];
  2235. TCHAR szFilter[ 64 ];
  2236. TCHAR* pszFilterDesc;
  2237. TCHAR* pszFilter;
  2238. TCHAR* pszTitle;
  2239. TCHAR* pszDefExt;
  2240. TRACE("PlBrowse");
  2241. szBuf[ 0 ] = TEXT('\0');
  2242. /* Fill in FileOpen dialog parameter buffer.
  2243. */
  2244. pszFilterDesc = PszFromId( g_hinstDll, SID_PbkDescription );
  2245. pszFilter = PszFromId( g_hinstDll, SID_PbkFilter );
  2246. if (pszFilterDesc && pszFilter)
  2247. {
  2248. DWORD dwSize = sizeof(szFilter) / sizeof(TCHAR), dwLen;
  2249. ZeroMemory( szFilter, sizeof(szFilter) );
  2250. lstrcpyn( szFilter, pszFilterDesc, dwSize );
  2251. dwLen = lstrlen( szFilter ) + 1;
  2252. lstrcpyn( szFilter + dwLen, pszFilter, dwSize - dwLen );
  2253. }
  2254. Free0( pszFilterDesc );
  2255. Free0( pszFilter );
  2256. pszTitle = PszFromId( g_hinstDll, SID_PbkTitle );
  2257. pszDefExt = PszFromId( g_hinstDll, SID_PbkDefExt );
  2258. ZeroMemory( &ofn, sizeof(ofn) );
  2259. ofn.lStructSize = sizeof(ofn);
  2260. ofn.hwndOwner = pInfo->hwndDlg;
  2261. ofn.hInstance = g_hinstDll;
  2262. ofn.lpstrFilter = szFilter;
  2263. ofn.nFilterIndex = 1;
  2264. ofn.lpstrFile = szBuf;
  2265. ofn.nMaxFile = MAX_PATH;
  2266. ofn.lpstrTitle = pszTitle;
  2267. ofn.lpstrDefExt = pszDefExt;
  2268. ofn.Flags = OFN_HIDEREADONLY;
  2269. {
  2270. HHOOK hhook;
  2271. BOOL f;
  2272. /* Install hook that will get the message box centered on the
  2273. ** owner window.
  2274. */
  2275. hhook = SetWindowsHookEx( WH_CALLWNDPROC,
  2276. CenterDlgOnOwnerCallWndProc, g_hinstDll, GetCurrentThreadId() );
  2277. TRACE("GetOpenFileName");
  2278. f = GetOpenFileName( &ofn );
  2279. TRACE1("GetOpenFileName=%d",f);
  2280. if (hhook)
  2281. UnhookWindowsHookEx( hhook );
  2282. if (f)
  2283. SetWindowText( pInfo->hwndClbAlternates, ofn.lpstrFile );
  2284. }
  2285. Free0( pszTitle );
  2286. Free0( pszDefExt );
  2287. }
  2288. BOOL
  2289. PlInit(
  2290. IN HWND hwndPage )
  2291. /* Called on WM_INITDIALOG. 'hwndPage' is the handle of the property
  2292. ** page.
  2293. **
  2294. ** Return false if focus was set, true otherwise.
  2295. */
  2296. {
  2297. UPINFO* pInfo;
  2298. TRACE("PlInit");
  2299. pInfo = UpContext( hwndPage );
  2300. if (!pInfo)
  2301. return TRUE;
  2302. /* Initialize page-specific context information.
  2303. */
  2304. pInfo->hwndPl = hwndPage;
  2305. pInfo->hwndRbSystem = GetDlgItem( hwndPage, CID_PL_RB_SystemList );
  2306. ASSERT(pInfo->hwndRbSystem);
  2307. if (!pInfo->pArgs->fNoUser)
  2308. {
  2309. pInfo->hwndRbPersonal = GetDlgItem( hwndPage, CID_PL_RB_PersonalList );
  2310. ASSERT(pInfo->hwndRbPersonal);
  2311. if (pInfo->user.dwPhonebookMode == PBM_Personal)
  2312. pInfo->user.dwPhonebookMode = PBM_System;
  2313. }
  2314. pInfo->hwndRbAlternate = GetDlgItem( hwndPage, CID_PL_RB_AlternateList );
  2315. ASSERT(pInfo->hwndRbAlternate);
  2316. pInfo->hwndClbAlternates = GetDlgItem( hwndPage, CID_PL_CL_Lists );
  2317. ASSERT(pInfo->hwndClbAlternates);
  2318. pInfo->hwndPbBrowse = GetDlgItem( hwndPage, CID_PL_PB_Browse );
  2319. ASSERT(pInfo->hwndPbBrowse);
  2320. /* Load alternate phonebooks list.
  2321. */
  2322. {
  2323. INT iSel;
  2324. DTLNODE* pNode;
  2325. TCHAR* pszSel;
  2326. pszSel = pInfo->user.pszAlternatePath;
  2327. iSel = -1;
  2328. for (pNode = DtlGetFirstNode( pInfo->user.pdtllistPhonebooks );
  2329. pNode;
  2330. pNode = DtlGetNextNode( pNode ))
  2331. {
  2332. TCHAR* psz;
  2333. INT i;
  2334. psz = (TCHAR* )DtlGetData( pNode );
  2335. if (psz)
  2336. {
  2337. i = ComboBox_AddString( pInfo->hwndClbAlternates, psz );
  2338. if (iSel < 0 && pszSel && lstrcmpi( psz, pszSel ) == 0)
  2339. iSel = i;
  2340. }
  2341. }
  2342. if (iSel < 0 && pszSel)
  2343. iSel = ComboBox_AddString( pInfo->hwndClbAlternates, pszSel );
  2344. ComboBox_SetCurSel( pInfo->hwndClbAlternates, iSel );
  2345. ComboBox_AutoSizeDroppedWidth( pInfo->hwndClbAlternates );
  2346. }
  2347. /* Select the phonebook mode with a pseudo-click which will trigger
  2348. ** enabling/disabling of combo and button state.
  2349. */
  2350. {
  2351. HWND hwndRb;
  2352. if (pInfo->user.dwPhonebookMode == PBM_System)
  2353. hwndRb = pInfo->hwndRbSystem;
  2354. else if (pInfo->user.dwPhonebookMode == PBM_Personal)
  2355. hwndRb = pInfo->hwndRbPersonal;
  2356. else
  2357. {
  2358. ASSERT(pInfo->user.dwPhonebookMode==PBM_Alternate);
  2359. hwndRb = pInfo->hwndRbAlternate;
  2360. }
  2361. SendMessage( hwndRb, BM_CLICK, 0, 0 );
  2362. }
  2363. return TRUE;
  2364. }
  2365. #endif