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.

615 lines
16 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. /***************************************************************************/
  4. /************************ dialog handling routines ************************/
  5. /***************************************************************************/
  6. /*
  7. ** Purpose:
  8. ** Creates a dialog on the screen. Called by HdlgPushDbcb
  9. ** Arguments:
  10. ** hinst: Handle to instance of the APP (i.e. the shell)
  11. ** szDlg: Name of dialog template
  12. ** hwndParent: Handle to parent window (i.e. the shell)
  13. ** lpproc: Procedure-instance address for the dialog procedure
  14. ** lParam: 32-bit initialization value that will be passed to the
  15. ** dialog procedure when the dialog box is created.
  16. ** Currently unused by our general dialog procedures.
  17. ** Returns:
  18. ** The window handle of the dialog box if window creation succeeds,
  19. ** otherwise NULL.
  20. **
  21. ****************************************************************************/
  22. HDLG APIENTRY HdlgCreateDialog(hinst, szDlg, hwndParent, lpproc,
  23. lParam)
  24. HANDLE hinst;
  25. SZ szDlg;
  26. HWND hwndParent;
  27. WNDPROC lpproc;
  28. DWORD lParam;
  29. {
  30. WNDPROC lpfnDlgProc;
  31. HDLG hdlgResult ;
  32. #ifdef DLL
  33. lpfnDlgProc = lpproc;
  34. #else /* !DLL */
  35. lpfnDlgProc = MakeProcInstance(lpproc, hinst);
  36. #endif /* !DLL */
  37. Assert(lpfnDlgProc != NULL);
  38. hdlgResult = CreateDialogParam(hinst, (LPCSTR)szDlg, hwndParent, (DLGPROC)lpfnDlgProc,
  39. (LONG)lParam);
  40. if ( hdlgResult == NULL )
  41. {
  42. #if DEVL
  43. OutputDebugString("SETUP: dialog load failed on [");
  44. OutputDebugString( szDlg );
  45. OutputDebugString( "].\n" );
  46. #endif
  47. }
  48. return hdlgResult ;
  49. }
  50. /*
  51. ** Purpose:
  52. ** To destroy a dialog
  53. ** Arguments:
  54. ** hdlg: A window handle to the dialog.
  55. ** Returns:
  56. ** fFalse if the window handle to the dialog is NULL, fTrue otherwise
  57. **
  58. ****************************************************************************/
  59. BOOL APIENTRY FCloseDialog(hdlg)
  60. HDLG hdlg;
  61. {
  62. HWND hwndShell;
  63. ChkArg(hdlg != NULL, 1, fFalse);
  64. hwndShell = GetParent(hdlg);
  65. SendMessage(hdlg, (WORD)STF_DESTROY_DLG, 0, 0L);
  66. if (hwndShell != NULL)
  67. UpdateWindow(hwndShell);
  68. return(fTrue);
  69. }
  70. /*
  71. ** Purpose:
  72. ** To make a dialog that has already been created invisible.
  73. ** Arguments:
  74. ** hdlg: non-NULL window handle to the dialog
  75. ** Returns:
  76. ** Nonzero if the dialog was previously visible, 0 if it was
  77. ** previously hidden.
  78. **
  79. ***************************************************************************/
  80. BOOL APIENTRY FHideDialog(hdlg)
  81. HDLG hdlg;
  82. {
  83. ChkArg(hdlg != NULL, 1, fFalse);
  84. ShowWindow(hdlg, SW_HIDE);
  85. return(fTrue);
  86. }
  87. /*
  88. ** Purpose:
  89. ** To show a dialog in either its active or inactive state.
  90. ** Arguments:
  91. ** hdlg: A window handle to the dialog
  92. ** fActive: a boolean value that specifies whether the dialog should be
  93. ** shown as active (fTrue) or inactive (fFalse);
  94. ** Returns:
  95. ** fTrue
  96. **
  97. ****************************************************************************/
  98. BOOL APIENTRY FShowDialog(hdlg, fActive)
  99. HDLG hdlg;
  100. BOOL fActive;
  101. {
  102. //***** REMOVED FOR NEW ACTIVATION SCHEME ******************************
  103. // if (fActive)
  104. // EvalAssert(FActivateDialog(hdlg));
  105. // else
  106. // EvalAssert(FInactivateDialog(hdlg));
  107. //
  108. // //
  109. // // And then show it
  110. // //
  111. //
  112. // SetWindowPos(hdlg, NULL, 0,0,0,0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
  113. //***** REMOVED FOR NEW ACTIVATION SCHEME ******************************
  114. if (fActive) {
  115. ShowWindow(hdlg, SW_SHOWNORMAL);
  116. }
  117. else {
  118. ShowWindow(hdlg, SW_SHOWNOACTIVATE);
  119. }
  120. return(fTrue);
  121. }
  122. /*
  123. ** Purpose:
  124. ** To activate a dialog. That is, set the title bar color to the active
  125. ** color and restore the sysmenu.
  126. ** Arguments:
  127. ** hdlg: The window handle to the dialog
  128. ** Returns:
  129. ** fTrue
  130. **
  131. *****************************************************************************/
  132. BOOL APIENTRY FActivateDialog(hdlg)
  133. HDLG hdlg;
  134. {
  135. LONG lStyle;
  136. ChkArg(hdlg != NULL, 1, fFalse);
  137. lStyle = GetWindowLong(hdlg, GWL_STYLE);
  138. lStyle = lStyle | WS_SYSMENU;
  139. SetWindowLong(hdlg, GWL_STYLE, lStyle);
  140. //***** REMOVED FOR NEW ACTIVATION SCHEME ******************************
  141. // SendMessage(hdlg, WM_NCACTIVATE, 1, 0L);
  142. //***** REMOVED FOR NEW ACTIVATION SCHEME ******************************
  143. return(fTrue);
  144. }
  145. /*
  146. ** Purpose:
  147. ** To inactivate the dialog. That is, change the title bar color to the
  148. ** inactive color and remove the sysmenu.
  149. ** Arguments:
  150. ** hdlg: The non-NULL window handle to the dialog.
  151. ** Returns:
  152. ** fTrue
  153. **
  154. *****************************************************************************/
  155. BOOL APIENTRY FInactivateDialog(hdlg)
  156. HDLG hdlg;
  157. {
  158. LONG lStyle;
  159. ChkArg(hdlg != NULL, 1, fFalse);
  160. lStyle = GetWindowLong(hdlg, GWL_STYLE);
  161. lStyle = lStyle & (~WS_SYSMENU);
  162. SetWindowLong(hdlg, GWL_STYLE, (DWORD)lStyle);
  163. //***** REMOVED FOR NEW ACTIVATION SCHEME ******************************
  164. // SendMessage(hdlg, WM_NCACTIVATE, 0, 0L);
  165. //***** REMOVED FOR NEW ACTIVATION SCHEME ******************************
  166. return(fTrue);
  167. }
  168. /*
  169. ** Purpose:
  170. ** To enable all mouse and keyboard input to the dialog.
  171. ** Arguments:
  172. ** hdlg: The window handle to the dialog.
  173. ** Returns:
  174. ** fFalse is hdlg is NULL. Otherwise it returns 0 if the attempt to
  175. ** enable the dialog fails, nonzero if it succeeds.
  176. **
  177. ****************************************************************************/
  178. BOOL APIENTRY FEnableDialog(hdlg)
  179. HDLG hdlg;
  180. {
  181. ChkArg(hdlg != NULL, 1, fFalse);
  182. return(EnableWindow(hdlg, fTrue));
  183. }
  184. /*
  185. ** Purpose:
  186. ** To disable all mouse and keyboard input to the dialog.
  187. ** Arguments:
  188. ** hdlg: The window handle to the dialog.
  189. ** Returns:
  190. ** fFalse is hdlg is NULL. Otherwise it returns 0 if the attempt to
  191. ** disable the dialog fails, nonzero if it succeeds.
  192. **
  193. ****************************************************************************/
  194. BOOL APIENTRY FDisableDialog(hdlg)
  195. HDLG hdlg;
  196. {
  197. ChkArg(hdlg != NULL, 1, fFalse);
  198. return(EnableWindow(hdlg, fFalse));
  199. }
  200. /*
  201. ** Purpose:
  202. ** To substitute the text in a dialog control with a value from the symbol
  203. ** table. If the text is of the form "@Key" then if there is an entry in
  204. ** the symbol table with the key "Key" its value is substitued for the text
  205. ** in the control. If no such symbol is found then a blank string is
  206. ** substituted.
  207. ** Arguments:
  208. ** hwnd: The window handle of the control whose text is to be
  209. ** substituted
  210. ** lParam: Currently unused.
  211. ** Notes:
  212. ** This function must be exported.
  213. ** Returns:
  214. ** fTrue always
  215. **
  216. ****************************************************************************/
  217. BOOL APIENTRY TextSubst(hwnd, lParam)
  218. HWND hwnd;
  219. DWORD lParam;
  220. {
  221. CHP rgch[cchpSymBuf + 1];
  222. CCHP cchpLength;
  223. SZ sz = 0;
  224. Unused(lParam);
  225. cchpLength = (CCHP)GetWindowText(hwnd, (LPSTR)rgch, cchpSymMax + 1);
  226. rgch[cchpLength] = '\0';
  227. if (rgch[0] == '@')
  228. {
  229. if ((sz = SzFindSymbolValueInSymTab(rgch + 1)) != NULL)
  230. {
  231. if (0 == lstrcmpi( rgch, "@ProCancel" ))
  232. {
  233. if (NULL != SzFindSymbolValueInSymTab("!STF_NETCANCELOVERIDE"))
  234. {
  235. // no cancel buttons on progress indicators
  236. EnableWindow( hwnd, FALSE );
  237. ShowWindow( hwnd, SW_HIDE );
  238. }
  239. }
  240. SetWindowText(hwnd, sz);
  241. }
  242. else
  243. {
  244. SetWindowText(hwnd, "");
  245. }
  246. }
  247. return(fTrue);
  248. }
  249. /*
  250. ** Purpose:
  251. ** To fill any appropriate controls in the dialog with text from the INF.
  252. ** Any control containing text of the form "@Key" will be filled with
  253. ** text from the INF associated with "Key" if it exists. No such
  254. ** substitution occurs for a control if "Key" doesn't exist.
  255. ** Arguments:
  256. ** hdlg: The window handle to the dialog.
  257. ** hinst: Handle to instance of the APP (i.e. the shell)
  258. ** Returns:
  259. ** Nonzero if all of the child windows have been substituted
  260. ** (if necessary), 0 otherwise.
  261. **
  262. ****************************************************************************/
  263. BOOL APIENTRY FFillInDialogTextFromInf(hdlg, hinst)
  264. HDLG hdlg;
  265. HANDLE hinst;
  266. {
  267. FARPROC lpproc;
  268. CHP rgch[cchpSymBuf + 1];
  269. CCHP cchpLength;
  270. SZ sz = NULL;
  271. Unused(hinst);
  272. cchpLength = GetWindowText(hdlg, (LPSTR)rgch, cchpSymMax + 1);
  273. rgch[cchpLength] = '\0';
  274. if (rgch[0] == '@')
  275. {
  276. if ((sz = SzFindSymbolValueInSymTab(rgch + 1)) != NULL)
  277. SetWindowText(hdlg, sz);
  278. else
  279. SetWindowText(hdlg, "");
  280. }
  281. #ifdef DLL
  282. lpproc = (FARPROC)TextSubst;
  283. #else /* !DLL */
  284. lpproc = MakeProcInstance((FARPROC)TextSubst, hinst);
  285. #endif /* !DLL */
  286. return((EnumChildWindows(hdlg, (WNDENUMPROC)lpproc, (LPARAM)0L)));
  287. }
  288. /*
  289. ** Purpose:
  290. ** To create a dialog, fill any appropriate control with text from the INF
  291. ** and make the dialog visible.
  292. ** Arguments:
  293. ** hinst: Handle to instance of the APP (i.e. the shell)
  294. ** szDlg: Name of dialog template
  295. ** hwndParent: Handle to parent window (i.e. the shell)
  296. ** lpproc: Procedure-instance address for the dialog procedure
  297. ** lParam: 32-bit initialization value that will be passed to the
  298. ** dialog procedure when the dialog box is created.
  299. ** Returns:
  300. ** Window handle of the dialog if window creation succeeds, NULL otherwise.
  301. **
  302. ****************************************************************************/
  303. HDLG APIENTRY HdlgCreateFillAndShowDialog(hinst, szDlg, hwndParent,
  304. lpproc, lParam)
  305. HANDLE hinst;
  306. SZ szDlg;
  307. HWND hwndParent;
  308. WNDPROC lpproc;
  309. DWORD lParam;
  310. {
  311. HDLG hdlg;
  312. CHAR Class[MAX_PATH];
  313. if ((hdlg = HdlgCreateDialog(hinst, szDlg, hwndParent, lpproc, lParam)) !=
  314. (HDLG)NULL) {
  315. //
  316. // If the dialog has no exit button, diable the close option
  317. // on the system menu
  318. //
  319. if ( ( GetDlgItem ( hdlg, IDC_X ) == (HWND)NULL )
  320. && ( GetWindowLong( hdlg, GWL_STYLE ) & WS_SYSMENU )
  321. && ( GetClassName( hdlg, Class, MAX_PATH ) )
  322. && ( !lstrcmpi( Class, (LPSTR)CLS_MYDLGS ) )
  323. ) {
  324. EnableMenuItem(
  325. GetSystemMenu(hdlg, FALSE),
  326. SC_CLOSE,
  327. MF_BYCOMMAND | MF_GRAYED | MF_DISABLED
  328. );
  329. }
  330. //
  331. // Do dialog text replacement from the inf. All @Var values
  332. // get replaced by the value of Var
  333. //
  334. EvalAssert(FFillInDialogTextFromInf(hdlg, hinst));
  335. EvalAssert(FShowDialog(hdlg, fTrue));
  336. }
  337. return(hdlg);
  338. }
  339. /*
  340. ** Purpose:
  341. ** To center a dialog on the desktop window.
  342. ** Arguments:
  343. ** hdlg: Handle to the dialog being centered
  344. ** Returns:
  345. ** fTrue: Centering succeeded.
  346. ** fFalse: Error condition.
  347. **
  348. ****************************************************************************/
  349. BOOL
  350. FCenterDialogOnDesktop(
  351. HWND hdlg
  352. )
  353. {
  354. RECT DesktopRect, DlgRect;
  355. BOOL bStatus;
  356. HWND hwMaster ;
  357. POINT pt,
  358. ptCtr,
  359. ptMax,
  360. ptDlgSize ;
  361. LONG l ;
  362. ptMax.x = GetSystemMetrics( SM_CXFULLSCREEN ) ;
  363. ptMax.y = GetSystemMetrics( SM_CYFULLSCREEN ) ;
  364. //
  365. // Determine area of shell and of dlg
  366. //
  367. // Center dialog over the "pseudo parent" if there is one.
  368. //
  369. hwMaster = hwPseudoParent
  370. ? hwPseudoParent
  371. : GetDesktopWindow() ;
  372. if ( ! GetWindowRect( hwMaster, & DesktopRect ) )
  373. return fFalse ;
  374. if ( ! GetWindowRect( hdlg, & DlgRect ) )
  375. return fFalse ;
  376. ptDlgSize.x = DlgRect.right - DlgRect.left ;
  377. ptDlgSize.y = DlgRect.bottom - DlgRect.top ;
  378. // Attempt to center our dialog on top of the "master" window.
  379. ptCtr.x = DesktopRect.left + ((DesktopRect.right - DesktopRect.left) / 2) ;
  380. ptCtr.y = DesktopRect.top + ((DesktopRect.bottom - DesktopRect.top) / 2) ;
  381. pt.x = ptCtr.x - (ptDlgSize.x / 2) ;
  382. pt.y = ptCtr.y - (ptDlgSize.y / 2) ;
  383. // Force upper left corner back onto screen if necessary.
  384. if ( pt.x < 0 )
  385. pt.x = 0 ;
  386. if ( pt.y < 0 )
  387. pt.y = 0 ;
  388. // Now check to see if the dialog is getting clipped
  389. // to the right or bottom.
  390. if ( (l = pt.x + ptDlgSize.x) > ptMax.x )
  391. pt.x -= l - ptMax.x ;
  392. if ( (l = pt.y + ptDlgSize.y) > ptMax.y )
  393. pt.y -= l - ptMax.y ;
  394. if ( pt.x < 0 )
  395. pt.x = 0 ;
  396. if ( pt.y < 0 )
  397. pt.y = 0 ;
  398. //
  399. // center the dialog window in the shell window. Specify:
  400. //
  401. // SWP_NOSIZE : To ignore the cx,cy params given
  402. // SWP_NOZORDER : To ignore the HwndInsert after parameter and retain the
  403. // current z ordering.
  404. // SWP_NOACTIVATE : To not activate the window.
  405. //
  406. bStatus = SetWindowPos
  407. (
  408. hdlg,
  409. (HWND) NULL,
  410. pt.x,
  411. pt.y,
  412. 0,
  413. 0,
  414. SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE
  415. );
  416. //
  417. // return Status of operation
  418. //
  419. return(bStatus);
  420. }
  421. #define MAX_SIZE_STRING 20
  422. /* MySetDlgItemInt
  423. *
  424. * This implements the equivalent of SetDlgItemInt for long integers
  425. * The reason why we cannot use SetDlgItemInt is that Setup is supposed
  426. * to be able to do long on Win 16 as well
  427. *
  428. * ENTRY: hdlg - handle to the dialog which has the text control
  429. * nId - Text Control ID
  430. * nVal - Integer decimal value
  431. *
  432. * EXIT: None.
  433. *
  434. */
  435. VOID
  436. MySetDlgItemInt(
  437. HDLG hdlg,
  438. INT nId,
  439. LONG nVal
  440. )
  441. {
  442. CHP rgchSrcStr[MAX_SIZE_STRING];
  443. CHP rgchDestStr[MAX_SIZE_STRING];
  444. NumericFormat ( _ltoa(nVal, rgchSrcStr, 10), (SZ)rgchDestStr );
  445. SetDlgItemText(
  446. hdlg,
  447. nId,
  448. (LPSTR)rgchDestStr
  449. );
  450. return;
  451. }
  452. /* NumericFormat
  453. *
  454. * This function will format a numeric string using comma seperators for
  455. * the thousands. The seperator used will be one specified in win.ini in
  456. * the [intl] section via the sThousand=, profile.
  457. *
  458. * ENTRY: szSrcBuf - Pointer to string in it's "raw" form.
  459. *
  460. * szDispBuf - Pointer to buffer that will be returned with the thousands
  461. * seperated numeric string.
  462. *
  463. * EXIT: None.
  464. *
  465. */
  466. VOID
  467. NumericFormat(
  468. SZ szSrcBuf,
  469. SZ szDispBuf
  470. )
  471. {
  472. #define INTL "intl"
  473. #define THOU "sThousand"
  474. #define WININI "win.ini"
  475. SZ szIndex = szSrcBuf;
  476. SZ szDispBufHead = szDispBuf;
  477. INT i = 0;
  478. CHP rgchThouSep[2];
  479. CHP chThouSep;
  480. if ( !szSrcBuf || !szSrcBuf[0] ) {
  481. szDispBuf[0] = '\0';
  482. return;
  483. }
  484. GetPrivateProfileString(INTL, THOU, ",", rgchThouSep, 2, WININI);
  485. chThouSep = rgchThouSep[0];
  486. /* if thousand seperator is NULL, just return szSrcBuf. */
  487. if (!chThouSep)
  488. {
  489. lstrcpy(szDispBuf, szSrcBuf);
  490. return;
  491. }
  492. while( *szIndex ) { // seek end of string and increment the display buffer
  493. szIndex++; // because were going to fill it up in reverse order.
  494. szDispBuf++;
  495. }
  496. szIndex--; // Back up to last digit of src.
  497. i = (lstrlen(szSrcBuf) / 3); // This code calculates how many thousand
  498. if (! (lstrlen(szSrcBuf) % 3) && i ) // seperators will be needed.
  499. szDispBuf += (i-1);
  500. else
  501. szDispBuf += i;
  502. *szDispBuf-- = '\0'; // Terminate display buffer and back up.
  503. i = 0;
  504. while( fTrue ) {
  505. while( (szIndex != szSrcBuf) && (i < 3) ) {
  506. *szDispBuf-- = *szIndex--;
  507. ++i;
  508. }
  509. if ( szDispBuf != szDispBufHead ) {
  510. *szDispBuf-- = chThouSep;
  511. i=0;
  512. }
  513. else {
  514. *szDispBuf = *szIndex; // Last char.
  515. break;
  516. }
  517. }
  518. }