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.

646 lines
15 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. /* file gauge.c */
  4. HWND hwndProgressGizmo = NULL;
  5. static INT iCnt = 0;
  6. static WNDPROC fpxProDlg;
  7. static DWORD rgbFG;
  8. static DWORD rgbBG;
  9. extern HWND hwndFrame;
  10. extern HANDLE hinstShell;
  11. extern BOOL fMono;
  12. BOOL fUserQuit = fFalse;
  13. static BOOL fInsideGizmosQuitCode = fFalse;
  14. extern BOOL APIENTRY FYield(VOID);
  15. INT gaugeCopyPercentage = -1 ;
  16. #ifndef COLOR_HIGHLIGHT
  17. #define COLOR_HIGHLIGHT (COLOR_APPWORKSPACE + 1)
  18. #define COLOR_HIGHLIGHTTEXT (COLOR_APPWORKSPACE + 2)
  19. #endif
  20. #define COLORBG rgbBG
  21. #define COLORFG rgbFG
  22. BOOL
  23. ProInit(
  24. IN BOOL Init
  25. )
  26. {
  27. WNDCLASS rClass;
  28. BOOL b;
  29. if(Init) {
  30. rClass.hCursor = LoadCursor(NULL, IDC_ARROW);
  31. rClass.hIcon = NULL;
  32. rClass.lpszMenuName = NULL;
  33. rClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  34. rClass.hInstance = hInst;
  35. rClass.style = CS_HREDRAW | CS_VREDRAW;
  36. rClass.lpfnWndProc = ProBarProc;
  37. rClass.cbClsExtra = 0;
  38. rClass.cbWndExtra = 2 * sizeof(WORD);
  39. }
  40. rClass.lpszClassName = PRO_CLASS;
  41. if(Init) {
  42. if(fMono) {
  43. rgbBG = RGB( 0, 0, 0);
  44. rgbFG = RGB(255, 255, 255);
  45. } else {
  46. rgbBG = RGB( 0, 0, 255);
  47. rgbFG = RGB(255, 255, 255);
  48. }
  49. b = RegisterClass(&rClass);
  50. } else {
  51. b = UnregisterClass(rClass.lpszClassName,hInst);
  52. }
  53. return(b);
  54. }
  55. /***************************************************************************/
  56. VOID APIENTRY ProClear(HWND hdlg)
  57. {
  58. AssertDataSeg();
  59. if (!hdlg)
  60. hdlg = hwndProgressGizmo;
  61. SetDlgItemText(hdlg, ID_STATUS1, "");
  62. SetDlgItemText(hdlg, ID_STATUS2, "");
  63. SetDlgItemText(hdlg, ID_STATUS3, "");
  64. SetDlgItemText(hdlg, ID_STATUS4, "");
  65. }
  66. BOOL
  67. ControlInit(
  68. IN BOOL Init
  69. )
  70. {
  71. WNDCLASS cls;
  72. if(Init) {
  73. cls.hCursor = LoadCursor(NULL, IDC_ARROW);
  74. cls.hIcon = NULL;
  75. cls.lpszMenuName = NULL;
  76. cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  77. cls.hInstance = hInst;
  78. cls.style = CS_HREDRAW | CS_VREDRAW;
  79. cls.lpfnWndProc = fnText;
  80. cls.cbClsExtra = 0;
  81. cls.cbWndExtra = 0;
  82. }
  83. cls.lpszClassName = "stext";
  84. return(Init ? RegisterClass(&cls) : UnregisterClass(cls.lpszClassName,hInst));
  85. }
  86. static int getNumericSymbol ( SZ szSymName )
  87. {
  88. SZ sz = SzFindSymbolValueInSymTab( szSymName ) ;
  89. return sz ? atoi( sz ) : -1 ;
  90. }
  91. #define SYM_NAME_CTR_X "!G:STF_DLG_PRO_CTR_X"
  92. #define SYM_NAME_CTR_Y "!G:STF_DLG_PRO_CTR_Y"
  93. static void centerOnDesktop ( HWND hdlg )
  94. {
  95. RECT rc ;
  96. POINT pt, ptDlgSize ;
  97. int ixBias = getNumericSymbol( SYM_NAME_CTR_X ),
  98. iyBias = getNumericSymbol( SYM_NAME_CTR_Y ),
  99. cx = GetSystemMetrics( SM_CXFULLSCREEN ),
  100. cy = GetSystemMetrics( SM_CYFULLSCREEN ),
  101. l ;
  102. // Get specified or default bias
  103. if ( ixBias <= 0 || ixBias >= 100 )
  104. ixBias = 50 ; // default value is 1/2 across
  105. if ( iyBias <= 0 || iyBias >= 100 )
  106. iyBias = 50 ; // default value is 1/3 down
  107. // Compute logical center point
  108. pt.x = (cx * ixBias) / 100 ;
  109. pt.y = (cy * iyBias) / 100 ;
  110. GetWindowRect( hdlg, & rc ) ;
  111. ptDlgSize.x = rc.right - rc.left ;
  112. ptDlgSize.y = rc.bottom - rc.top ;
  113. pt.x -= ptDlgSize.x / 2 ;
  114. pt.y -= ptDlgSize.y / 2 ;
  115. // Force upper left corner back onto screen if necessary.
  116. if ( pt.x < 0 )
  117. pt.x = 0 ;
  118. if ( pt.y < 0 )
  119. pt.y = 0 ;
  120. // Now check to see if the dialog is getting clipped
  121. // to the right or bottom.
  122. if ( (l = pt.x + ptDlgSize.x) > cx )
  123. pt.x -= l - cx ;
  124. if ( (l = pt.y + ptDlgSize.y) > cy )
  125. pt.y -= l - cy ;
  126. if ( pt.x < 0 )
  127. pt.x = 0 ;
  128. if ( pt.y < 0 )
  129. pt.y = 0 ;
  130. SetWindowPos( hdlg, NULL,
  131. pt.x, pt.y,
  132. 0, 0, SWP_NOSIZE | SWP_NOACTIVATE ) ;
  133. }
  134. /*
  135. ** ProDlgProc(hWnd, wMessage, wParam, lParam)
  136. **
  137. ** Description:
  138. ** The window proc for the Progress dialog box
  139. ** Arguments:
  140. ** hWnd window handle for the dialog
  141. ** wMessage message number
  142. ** wParam message-dependent
  143. ** lParam message-dependent
  144. ** Returns:
  145. ** 0 if processed, nonzero if ignored
  146. ***************************************************************************/
  147. INT_PTR APIENTRY ProDlgProc(HWND hdlg, UINT wMessage, WPARAM wParam, LPARAM lParam)
  148. {
  149. static SZ szProCancelMsg;
  150. static SZ szProCancelCap;
  151. Unused(lParam); // GET_WM_COMMAND does not use the lParam
  152. AssertDataSeg();
  153. switch (wMessage)
  154. {
  155. case WM_INITDIALOG:
  156. if ((szProCancelMsg = SzFindSymbolValueInSymTab("ProCancelMsg")) == (SZ)NULL ||
  157. (szProCancelCap = SzFindSymbolValueInSymTab("ProCancelCap")) == (SZ)NULL ) {
  158. PreCondition(fFalse, fTrue);
  159. return(fTrue);
  160. }
  161. ProClear(hdlg);
  162. /* BLOCK */ /* centered on the screen - we really want this to be
  163. a WS_CHILD instead of WS_POPUP so we can do something
  164. intelligent inside the frame window */
  165. centerOnDesktop( hdlg ) ;
  166. gaugeCopyPercentage = 0 ;
  167. return(fTrue);
  168. // case WM_ACTIVATE:
  169. // if (wParam != 0)
  170. // SendMessage(hwndFrame, WM_NCACTIVATE, 1, 0L);
  171. // break;
  172. case WM_CLOSE:
  173. gaugeCopyPercentage = -1 ;
  174. PostMessage(
  175. hdlg,
  176. WM_COMMAND,
  177. MAKELONG(IDC_X, BN_CLICKED),
  178. 0L
  179. );
  180. return(fTrue);
  181. case WM_COMMAND:
  182. if (!fInsideGizmosQuitCode
  183. && (LOWORD(wParam) == IDCANCEL || LOWORD(wParam) == IDC_B))
  184. {
  185. fInsideGizmosQuitCode = fTrue;
  186. if (!FYield())
  187. {
  188. fInsideGizmosQuitCode = fFalse;
  189. DestroyWindow(hwndFrame);
  190. }
  191. if ( MessageBox(
  192. hdlg,
  193. (LPSTR)szProCancelMsg,
  194. (LPSTR)szProCancelCap,
  195. MB_YESNO | MB_ICONEXCLAMATION
  196. ) == IDYES ) {
  197. fUserQuit = fTrue;
  198. fInsideGizmosQuitCode = fFalse;
  199. return(fFalse);
  200. }
  201. fInsideGizmosQuitCode = fFalse;
  202. SendMessage(hwndFrame, WM_NCACTIVATE, 1, 0L);
  203. }
  204. break;
  205. }
  206. return(fFalse);
  207. }
  208. /*
  209. ** ProBarProc(hWnd, wMessage, wParam, lParam)
  210. **
  211. ** Description:
  212. ** The window proc for the Progress Bar chart
  213. ** Arguments:
  214. ** hWnd window handle for the dialog
  215. ** wMessage message number
  216. ** wParam message-dependent
  217. ** lParam message-dependent
  218. ** Returns:
  219. ** 0 if processed, nonzero if ignored
  220. ***************************************************************************/
  221. LRESULT APIENTRY ProBarProc(HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam)
  222. {
  223. PAINTSTRUCT rPS;
  224. RECT rc1, rc2;
  225. INT dx, dy, x;
  226. WORD iRange, iPos;
  227. CHP rgch[30];
  228. INT iHeight = 0, iWidth = 0;
  229. HFONT hfntSav = NULL;
  230. static HFONT hfntBar = NULL;
  231. SIZE size;
  232. AssertDataSeg();
  233. switch (wMessage)
  234. {
  235. case WM_CREATE:
  236. SetWindowWord(hWnd, BAR_RANGE, 10);
  237. SetWindowWord(hWnd, BAR_POS, 0);
  238. return(0L);
  239. case BAR_SETRANGE:
  240. case BAR_SETPOS:
  241. SetWindowWord(hWnd, wMessage - WM_USER, (WORD)wParam);
  242. InvalidateRect(hWnd, NULL, fFalse);
  243. UpdateWindow(hWnd);
  244. return(0L);
  245. case BAR_DELTAPOS:
  246. iRange = (WORD)GetWindowWord(hWnd, BAR_RANGE);
  247. iPos = (WORD)GetWindowWord(hWnd, BAR_POS);
  248. if (iRange <= 0)
  249. iRange = 1;
  250. if (iPos > iRange)
  251. iPos = iRange;
  252. if (iPos + wParam > iRange)
  253. wParam = iRange - iPos;
  254. SetWindowWord(hWnd, BAR_POS, (WORD)(iPos + wParam));
  255. if ((iPos * 100 / iRange) < ((iPos + (WORD)wParam) * 100 / iRange))
  256. {
  257. InvalidateRect(hWnd, NULL, fFalse);
  258. UpdateWindow(hWnd);
  259. }
  260. return(0L);
  261. case WM_SETFONT:
  262. hfntBar = (HFONT)wParam;
  263. if (!lParam)
  264. return(0L);
  265. InvalidateRect(hWnd, NULL, fTrue);
  266. case WM_PAINT:
  267. BeginPaint(hWnd, &rPS);
  268. if (hfntBar)
  269. hfntSav = SelectObject(rPS.hdc, hfntBar);
  270. GetClientRect(hWnd, &rc1);
  271. {
  272. HGDIOBJ hStockObject = GetStockObject(BLACK_BRUSH);
  273. if (hStockObject) {
  274. FrameRect(rPS.hdc, &rc1, hStockObject);
  275. InflateRect(&rc1, -1, -1);
  276. }
  277. }
  278. rc2 = rc1;
  279. iRange = GetWindowWord(hWnd, BAR_RANGE);
  280. iPos = GetWindowWord(hWnd, BAR_POS);
  281. if (iRange <= 0)
  282. iRange = 1;
  283. if (iPos > iRange)
  284. iPos = iRange;
  285. dx = rc1.right;
  286. dy = rc1.bottom;
  287. x = (WORD)((DWORD)iPos * dx / iRange) + 1;
  288. if (iPos < iRange)
  289. iPos++;
  290. gaugeCopyPercentage = ((DWORD) iPos) * 100 / iRange ;
  291. wsprintf(rgch, "%3d%%", (WORD) gaugeCopyPercentage );
  292. GetTextExtentPoint(rPS.hdc, rgch, strlen(rgch), &size);
  293. iWidth = size.cx;
  294. iHeight = size.cy;
  295. rc1.right = x;
  296. rc2.left = x;
  297. SetBkColor(rPS.hdc, COLORBG);
  298. SetTextColor(rPS.hdc, COLORFG);
  299. ExtTextOut(rPS.hdc, (dx-iWidth)/2, (dy-iHeight)/2,
  300. ETO_OPAQUE | ETO_CLIPPED, &rc1, rgch, strlen(rgch), NULL);
  301. SetBkColor(rPS.hdc, COLORFG);
  302. SetTextColor(rPS.hdc, COLORBG);
  303. ExtTextOut(rPS.hdc, (dx-iWidth)/2, (dy-iHeight)/2,
  304. ETO_OPAQUE | ETO_CLIPPED, &rc2, rgch, strlen(rgch), NULL);
  305. if (hfntSav)
  306. SelectObject(rPS.hdc, hfntSav);
  307. EndPaint(hWnd, (LPPAINTSTRUCT)&rPS);
  308. return(0L);
  309. }
  310. return(DefWindowProc(hWnd, wMessage, wParam, lParam));
  311. }
  312. /*
  313. ** ProOpen ()
  314. **
  315. ** Returns:
  316. ** 0 if processed, nonzero if ignored
  317. ***************************************************************************/
  318. HWND APIENTRY ProOpen(HWND hwnd, INT id)
  319. {
  320. CHP szTmpText[cchpBufTmpLongMax];
  321. Unused(id);
  322. AssertDataSeg();
  323. //
  324. // Maintain the number of times the progress guage is opened
  325. //
  326. iCnt++;
  327. //
  328. // Check if progress guage still present
  329. //
  330. if (!hwndProgressGizmo)
  331. {
  332. //
  333. // Get Progress Dialog procedure instance
  334. //
  335. #ifdef DLL
  336. fpxProDlg = ProDlgProc;
  337. #else /* !DLL */
  338. fpxProDlg = (WNDPROC)MakeProcInstance(ProDlgProc, hinstShell);
  339. #endif /* !DLL */
  340. //
  341. // Fetch dialog resource name
  342. //
  343. if (!LoadString(hinstShell, IDS_PROGRESS, szTmpText, cchpBufTmpLongMax)) {
  344. strcpy( szTmpText, "Progress" );
  345. }
  346. //
  347. // Create the Progress dialog
  348. //
  349. hwndProgressGizmo = CreateDialog(hinstShell, (LPCSTR)szTmpText, hwnd, (DLGPROC)fpxProDlg);
  350. //
  351. // Fill in @ items with text from the INF
  352. //
  353. EvalAssert(FFillInDialogTextFromInf(hwndProgressGizmo, hinstShell));
  354. //
  355. // Show the guage and paint it
  356. //
  357. ShowWindow(hwndProgressGizmo, SHOW_OPENWINDOW);
  358. UpdateWindow(hwndProgressGizmo);
  359. EnableWindow(hwndFrame, fFalse);
  360. // SendMessage(hwndFrame, WM_NCACTIVATE, 1, 0L);
  361. }
  362. return(hwndProgressGizmo);
  363. }
  364. /*
  365. ** ProClose(hwndFrame)
  366. **
  367. ** Returns:
  368. ** 0 if processed, nonzero if ignored
  369. ***************************************************************************/
  370. BOOL APIENTRY ProClose(HWND hwndFrame)
  371. {
  372. AssertDataSeg();
  373. iCnt--;
  374. if (hwndProgressGizmo && iCnt == 0)
  375. {
  376. EnableWindow(hwndFrame, fTrue);
  377. DestroyWindow(hwndProgressGizmo);
  378. FreeProcInstance(fpxProDlg);
  379. hwndProgressGizmo = NULL;
  380. }
  381. return(fTrue);
  382. }
  383. /***************************************************************************/
  384. BOOL APIENTRY ProSetText(INT i, LPSTR sz)
  385. {
  386. AssertDataSeg();
  387. if (hwndProgressGizmo)
  388. {
  389. SetDlgItemText(hwndProgressGizmo, i, sz);
  390. return(fTrue);
  391. }
  392. return(fFalse);
  393. }
  394. /***************************************************************************/
  395. BOOL APIENTRY ProSetCaption(LPSTR szCaption)
  396. {
  397. if (hwndProgressGizmo)
  398. {
  399. SetWindowText(hwndProgressGizmo, szCaption);
  400. return(fTrue);
  401. }
  402. return(fFalse);
  403. }
  404. /***************************************************************************/
  405. BOOL APIENTRY ProSetBarRange(INT i)
  406. {
  407. AssertDataSeg();
  408. if (hwndProgressGizmo)
  409. {
  410. SendDlgItemMessage(hwndProgressGizmo, ID_BAR, BAR_SETRANGE, i, 0L);
  411. return(fTrue);
  412. }
  413. return(fFalse);
  414. }
  415. /***************************************************************************/
  416. BOOL APIENTRY ProSetBarPos(INT i)
  417. {
  418. AssertDataSeg();
  419. if (hwndProgressGizmo)
  420. {
  421. SendDlgItemMessage(hwndProgressGizmo, ID_BAR, BAR_SETPOS, i, 0L);
  422. return(fTrue);
  423. }
  424. return(fFalse);
  425. }
  426. /***************************************************************************/
  427. BOOL APIENTRY ProDeltaPos(INT i)
  428. {
  429. AssertDataSeg();
  430. if (hwndProgressGizmo)
  431. {
  432. SendDlgItemMessage(hwndProgressGizmo, ID_BAR, BAR_DELTAPOS, i, 0L);
  433. return(fTrue);
  434. }
  435. return(fFalse);
  436. }
  437. /*
  438. ** text control that uses ExtTextOut() IE no flicker!
  439. ****************************************************************************/
  440. LRESULT APIENTRY fnText(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
  441. {
  442. PAINTSTRUCT ps;
  443. RECT rc;
  444. CHP rgch[256];
  445. INT len;
  446. HFONT hfntSav = NULL;
  447. static HFONT hfntText = NULL;
  448. SIZE size;
  449. switch (wMsg)
  450. {
  451. case WM_SETTEXT:
  452. DefWindowProc(hwnd, wMsg, wParam, lParam);
  453. InvalidateRect(hwnd,NULL,fFalse);
  454. UpdateWindow(hwnd);
  455. return(0L);
  456. case WM_ERASEBKGND:
  457. return(0L);
  458. case WM_SETFONT:
  459. hfntText = (HFONT)wParam;
  460. if (!lParam)
  461. return(0L);
  462. InvalidateRect(hwnd, NULL, fTrue);
  463. case WM_PAINT:
  464. BeginPaint(hwnd, &ps);
  465. if (hfntText)
  466. hfntSav = SelectObject(ps.hdc, hfntText);
  467. GetClientRect(hwnd,&rc);
  468. len = GetWindowText(hwnd, rgch, sizeof(rgch));
  469. SetBkColor(ps.hdc, GetSysColor(COLOR_BTNFACE));
  470. SetTextColor(ps.hdc, GetSysColor(COLOR_WINDOWTEXT));
  471. ExtTextOut(ps.hdc, 0, 0, ETO_OPAQUE, &rc, rgch, len, NULL);
  472. // see if text was too long. If so, place '...' at end of field.
  473. if(GetTextExtentPoint(ps.hdc,rgch,len,&size)) {
  474. if((size.cx > rc.right - rc.left + 1)
  475. && GetTextExtentPoint(ps.hdc,"...",3,&size))
  476. {
  477. ExtTextOut(ps.hdc,rc.right-size.cx+1,0,0,NULL,"...",3,NULL);
  478. }
  479. }
  480. if (hfntSav)
  481. SelectObject(ps.hdc, hfntSav);
  482. EndPaint(hwnd, &ps);
  483. return(0L);
  484. }
  485. return(DefWindowProc(hwnd, wMsg, wParam, lParam));
  486. }
  487. #ifdef UNUSED
  488. /*
  489. ** wsDlgInit(hdlg)
  490. **
  491. ** Handle the init message for a dialog box
  492. ***************************************************************************/
  493. VOID APIENTRY wsDlgInit(HWND hdlg)
  494. {
  495. AssertDataSeg();
  496. /* Center the dialog. */
  497. centerOnDesktop( hdlg ) ;
  498. }
  499. #endif /* UNUSED */