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.

1523 lines
38 KiB

  1. /*
  2. File: AppMan.cpp
  3. Project:
  4. Author: DDalal & ScottLe
  5. Date: 10/22/99
  6. Comments:
  7. AppMan Settings Tab in Game Control Panel.
  8. Copyright (c) 1999, Microsoft Corporation
  9. */
  10. // This is necessary LVS_EX_INFOTIP
  11. #if (_WIN32_IE < 0x400)
  12. #undef _WIN32_IE
  13. #define _WIN32_IE 0x400
  14. #if 0
  15. typedef struct tagNMITEMACTIVATE{
  16. NMHDR hdr;
  17. int iItem;
  18. int iSubItem;
  19. UINT uNewState;
  20. UINT uOldState;
  21. UINT uChanged;
  22. POINT ptAction;
  23. LPARAM lParam;
  24. UINT uKeyFlags;
  25. } NMITEMACTIVATE, FAR *LPNMITEMACTIVATE;
  26. #endif
  27. #endif
  28. #include <afxcmn.h>
  29. #include <windowsx.h>
  30. #include <cpl.h>
  31. #include <winuser.h> // For RegisterDeviceNotification stuff!
  32. #include <dbt.h> // for DBT_ defines!!!
  33. #include <commctrl.h> // for listview
  34. #include <tchar.h> // for TCHAR
  35. #include <malloc.h> // for _alloca
  36. #include "hsvrguid.h"
  37. #include "cpanel.h"
  38. #include "resource.h"
  39. #include "joyarray.h"
  40. #ifdef MAX_DEVICES // The control panel and the addman both define MAX_DEVICES, we'll use the AppMan supplied version
  41. #undef MAX_DEVICES
  42. #endif
  43. #include <AppManAdmin.h>
  44. #if _DEBUG
  45. #define Assert(x) { if(!(x)) { DebugBreak(); }}
  46. #else
  47. #define Assert(x)
  48. #endif
  49. static HWND ghDlg;
  50. HWND hAppManCheckBox;
  51. extern const DWORD gaHelpIDs[];
  52. extern HINSTANCE ghInstance;
  53. // constants
  54. const short NO_ITEM = -1;
  55. static short iItem = NO_ITEM; // index of selected item
  56. static DWORD ct=0L;
  57. // Forwards
  58. //
  59. // local forwards
  60. //
  61. static BOOL OnInitDialog(HWND hDlg, HWND hWnd, LPARAM lParam);
  62. static void OnCommand(HWND hDlg, int id, HWND hWndCtl, UINT code);
  63. static BOOL OnNotify(HWND hDlg, WPARAM idFrom, LPARAM lParam);
  64. void OnScroll(HWND hDlg, WPARAM wParam);
  65. void OnListCtrl_Select(HWND hDlg);
  66. void OnListCtrl_DblClick(HWND hDlg);
  67. void OnListCtrl_UpdateFromCheckBoxes( HWND hDlg );
  68. void OnButtonPress( HWND hDlg );
  69. void OnAdvancedModeCheckBox( HWND hCtl);
  70. void OnMoreInfoButton( HWND hDlg );
  71. INT_PTR CALLBACK MoreInfoProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  72. static void OnAdvHelp (LPARAM);
  73. static void OnContextMenu (WPARAM wParam, LPARAM lParam);
  74. static void OnListviewContextMenu (HWND hWnd, LPARAM lParam );
  75. // util fcns
  76. int MyInsertItem( HWND hCtrl, LPTSTR lpszBuff, int iItem ); // replaced from cpanel.cpp
  77. void SetScrollBarString(HWND hDlg, INT pos, int iDevIndex );
  78. void SetScrollBarPosition( HWND hDlg, INT pos, int iDevIndex );
  79. void PostDlgItemEnableWindow( HWND hDlg, USHORT nItem, BOOL bEnabled );
  80. void EnableDiskManageControls( HWND hDlg, BOOL bEnable );
  81. void EnableScrollBarAndText( HWND hDlg, BOOL bEnable );
  82. void EnableAllControls( HWND hDlg, BOOL bEnable );
  83. DWORD GetCurrentDeviceFromList( HWND hDlg, BYTE *nItem = NULL );
  84. void ConfigureListControl( HWND hDlg );
  85. void PopulateListControl( HWND hDlg, BYTE nItem );
  86. void UpdateCurrentDeviceFromScrollBar( HWND hDlg, DWORD newPos );
  87. void UpdateListItem( HWND hDlg, int iItem, BOOL bUpdateScrollBarPos = TRUE);
  88. void UpdateListAndScrollBar( HWND hDlg, BOOL bJustScrollBar = FALSE );
  89. // appman fcns
  90. HRESULT AppManGetGameDiskUsage(DWORD devIndex, DWORD &percent);
  91. HRESULT AppManSetGameDiskUsage(DWORD devIndex, DWORD percent);
  92. HRESULT AppManGetAllocatedMeg(DWORD devIndex, DWORD percent, DWORD &dwMegaBytes);
  93. HRESULT AppManShutdown();
  94. HRESULT AppManInit();
  95. HRESULT AppManIsDeviceExcluded(DWORD devIndex, BOOL &isExcluded);
  96. HRESULT AppManExcludeDevice(DWORD devIndex, BOOL bDoExclude );
  97. BOOL AppManDoesDeviceExist(DWORD devIndex, GUID &sDevGuid);
  98. BOOL AppManInitialized();
  99. HRESULT AppManSetAdvMode(BOOL bAdvMode);
  100. HRESULT AppManGetAdvMode(BOOL &bAdvMode);
  101. //
  102. // from cpanel.cpp
  103. //
  104. extern void SetItemText( HWND hCtrl, BYTE nItem, BYTE nSubItem, LPTSTR lpStr);
  105. extern void InsertColumn(HWND hCtrl, BYTE nColumn, USHORT nStrID, USHORT nWidth);
  106. extern BOOL SetItemData( HWND hCtrl, BYTE nItem, DWORD dwFlag );
  107. extern DWORD GetItemData(HWND hCtrl, BYTE nItem );
  108. extern void SetListCtrlItemFocus ( HWND hCtrl, BYTE nItem );
  109. //
  110. // GLOBALS
  111. //
  112. BOOL g_ListPopulated = FALSE;
  113. int g_nm_click = -1;
  114. BOOL g_nm_click_state = FALSE;
  115. BOOL g_DlgInitialized = FALSE;
  116. BOOL g_ChkBoxUpdate = FALSE;
  117. #define APPMAN_LIST_EXCLUDE_CHECKBOX 0
  118. #define APPMAN_LIST_DRIVE 1
  119. #define APPMAN_LIST_EXCLUDED_PERCENT 2
  120. struct {
  121. BOOL isValid;
  122. int iItem;
  123. BOOL isClicked;
  124. int iNextItem;
  125. BOOL bKeybrdChange;
  126. } g_ItemChanged;
  127. ///////////////////////////////////////////////////////////////////////////////
  128. // FUNCTION: AppManProc(HWND hDlg, ULONG uMsg, WPARAM wParam, LPARAM lParam)
  129. //
  130. // PARAMETERS: hDlg -
  131. // uMsg -
  132. // wParam -
  133. // lParam -
  134. //
  135. // PURPOSE: Main callback function for "Appman" sheet
  136. ///////////////////////////////////////////////////////////////////////////////
  137. BOOL WINAPI AppManProc(HWND hDlg, ULONG uMsg, WPARAM wParam, LPARAM lParam)
  138. {
  139. switch( uMsg )
  140. {
  141. case WM_ACTIVATEAPP:
  142. if( wParam ) {
  143. HWND hListCtrl = NULL;
  144. hListCtrl = GetDlgItem((HWND) wParam, IDC_APPMAN_DRIVE_LIST);
  145. SetListCtrlItemFocus(hListCtrl, (BYTE)iItem);
  146. }
  147. break;
  148. case WM_DEVICECHANGE:
  149. switch( (UINT)wParam )
  150. {
  151. case DBT_DEVICEARRIVAL:
  152. // case DBT_DEVICEREMOVECOMPLETE:
  153. break;
  154. }
  155. break;
  156. case WM_LBUTTONDOWN:
  157. // Click Drag service for PropSheets!
  158. //PostMessage(GetParent(hDlg), WM_NCLBUTTONDOWN, (WPARAM)HTCAPTION, lParam);
  159. break;
  160. case WM_INITDIALOG:
  161. if( !HANDLE_WM_INITDIALOG(hDlg, wParam, lParam, OnInitDialog) )
  162. {
  163. // Fix #108983 NT, Remove Flash on Error condition.
  164. SetWindowPos(::GetParent(hDlg), HWND_BOTTOM, 0, 0, 0, 0, SWP_HIDEWINDOW);
  165. DestroyWindow(hDlg);
  166. }
  167. return(TRUE);
  168. case WM_COMMAND:
  169. HANDLE_WM_COMMAND(hDlg, wParam, lParam, OnCommand);
  170. return(TRUE);
  171. case WM_HSCROLL:
  172. OnScroll(hDlg, wParam);
  173. return(TRUE);
  174. case WM_DESTROY:
  175. //return(HANDLE_WM_DESTROY(hDlg, wParam, lParam, OnDestroy));
  176. return(TRUE);
  177. case WM_NOTIFY:
  178. return OnNotify(hDlg, wParam, lParam);
  179. case WM_HELP:
  180. OnAdvHelp(lParam);
  181. return(TRUE);
  182. case WM_CONTEXTMENU:
  183. OnContextMenu(wParam, lParam);
  184. return(TRUE);
  185. default:
  186. break;
  187. }
  188. return(0);
  189. }
  190. ///////////////////////////////////////////////////////////////////////////////
  191. // FUNCTION: OnInitDialog(HWND hDlg, HWND hWnd, LPARAM lParam)
  192. //
  193. // PARAMETERS: hDlg -
  194. // hWnd -
  195. // lParam -
  196. //
  197. // PURPOSE: WM_INITDIALOG message handler
  198. ///////////////////////////////////////////////////////////////////////////////
  199. BOOL OnInitDialog(HWND hDlg, HWND hWnd, LPARAM lParam)
  200. {
  201. HRESULT hr = S_OK;
  202. hr = AppManInit();
  203. //
  204. // init globals
  205. //
  206. ZeroMemory( &g_ItemChanged, sizeof(g_ItemChanged));
  207. g_DlgInitialized = FALSE;
  208. if( FAILED(hr) ) {
  209. //
  210. // Disable everything
  211. //
  212. EnableAllControls(hDlg, FALSE);
  213. //
  214. // popup saying: hey you need appman installed ?
  215. //
  216. } else {
  217. ghDlg = hDlg;
  218. //
  219. // Set defaults
  220. //
  221. //
  222. // Configure the List control, and then fill it in
  223. //
  224. ConfigureListControl( hDlg );
  225. PopulateListControl( hDlg, 0 );
  226. //
  227. // TRACK BAR
  228. //
  229. {
  230. // Set range [0..100]
  231. SendDlgItemMessage(hDlg,
  232. IDC_APPMAN_SCROLLBAR,
  233. TBM_SETRANGE,
  234. (WPARAM) TRUE,
  235. (LPARAM) MAKELONG(0,100));
  236. // set tick freq
  237. SendDlgItemMessage(hDlg,
  238. IDC_APPMAN_SCROLLBAR,
  239. TBM_SETTICFREQ,
  240. (WPARAM) 10,
  241. (LPARAM) 0);
  242. UpdateListAndScrollBar(hDlg, TRUE); // Update the scroll bar only
  243. // OnListCtrl_Select( hDlg );
  244. }
  245. // Set the Advanced user check box
  246. {
  247. BOOL bAdvMode;
  248. AppManGetAdvMode(bAdvMode);
  249. SendDlgItemMessage(hDlg,IDC_APPMAN_ADVUSER, BM_SETCHECK,(bAdvMode ? BST_CHECKED : BST_UNCHECKED),0L);
  250. }
  251. g_DlgInitialized = TRUE;
  252. } // else
  253. return(TRUE);
  254. }
  255. ///////////////////////////////////////////////////////////////////////////////
  256. // FUNCTION: OnCommand(HWND hDlg, int id, HWND hWndCtl, UINT code)
  257. //
  258. // PARAMETERS: hDlg -
  259. // id -
  260. // hWndCtl -
  261. // code -
  262. //
  263. // PURPOSE: WM_COMMAND message handler
  264. ///////////////////////////////////////////////////////////////////////////////
  265. void OnCommand(HWND hDlg, int id, HWND hWndCtl, UINT code)
  266. {
  267. HRESULT hr = S_OK;
  268. switch( id )
  269. {
  270. //
  271. // put the reset defaults button here
  272. //
  273. case IDC_APPMAN_RESTORE_DEFAULTS_BUTTON:
  274. OnButtonPress( hDlg );
  275. break;
  276. case IDC_APPMAN_ADVUSER:
  277. OnAdvancedModeCheckBox( hWndCtl);
  278. break;
  279. case IDS_WHATSTHIS:
  280. {
  281. // point to help file
  282. LPTSTR pszHelpFileName = new TCHAR[STR_LEN_32];
  283. ASSERT (pszHelpFileName);
  284. if( LoadString(ghInstance, IDS_HELPFILENAME, pszHelpFileName, STR_LEN_32) )
  285. WinHelp((HWND)hDlg, pszHelpFileName, HELP_WM_HELP, (ULONG_PTR)gaHelpIDs);
  286. #ifdef _DEBUG
  287. else
  288. OutputDebugString(TEXT("JOY.CPL: AppMan.cpp: OnCommand: LoadString Failed to find IDS_HELPFILENAME!\n"));
  289. #endif // _DEBUG
  290. if( pszHelpFileName )
  291. delete[] (pszHelpFileName);
  292. }
  293. break;
  294. case IDC_APPMAN_MORE_INFO:
  295. OnMoreInfoButton( hDlg );
  296. break;
  297. /*
  298. case IDC_APPMAN_MANAGE_DISK:
  299. {
  300. BOOL isChecked = (IsDlgButtonChecked(hDlg, id)) ? TRUE : FALSE;
  301. EnableDiskManageControls( hDlg, !isChecked );
  302. }
  303. break;
  304. */
  305. default:
  306. break;
  307. }
  308. }
  309. ////////////////////////////////////////////////////////////////////////////////
  310. //
  311. // FUNCTION: OnNotify(HWND hDlg, WPARAM idFrom, NMHDR* pnmhdr)
  312. //
  313. // PARAMETERS: hDlg -
  314. // idFrom - ID of control sending WM_NOTIFY message
  315. // pnmhdr -
  316. //
  317. // PURPOSE: WM_NOTIFY message handler
  318. ////////////////////////////////////////////////////////////////////////////////
  319. BOOL OnNotify(HWND hDlg, WPARAM idFrom, LPARAM lParam)
  320. {
  321. NMLISTVIEW *pnmv;
  322. LPNMHDR pnmhdr = (LPNMHDR)lParam;
  323. switch( pnmhdr->code )
  324. {
  325. case LVN_ITEMCHANGED:
  326. pnmv = (LPNMLISTVIEW) lParam;
  327. if( idFrom == IDC_APPMAN_DRIVE_LIST )
  328. {
  329. // this is called if a new item has been selected
  330. // or if the user clicked on the checkbox, changing state
  331. #ifdef _DEBUG
  332. {
  333. TCHAR tstring[256];
  334. NMITEMACTIVATE *pitemact = (LPNMITEMACTIVATE)lParam;
  335. _stprintf(tstring, TEXT("JOY.CPL: AppMan.cpp: OnNotify: LVN_ITEMCHANGED, ct=%ld,idFrom=%lx, item=%lx uChanged=%lx uNewState=%lx uOldState=%lx lParam=%lx\n"),++ct,idFrom,pitemact->iItem,pitemact->uChanged,pitemact->uNewState,pitemact->uOldState,pitemact->lParam);
  336. OutputDebugString(tstring);
  337. }
  338. #endif // _DEBUG
  339. if( AppManInitialized() &&
  340. g_DlgInitialized &&
  341. (pnmv->uNewState & LVIS_SELECTED ||
  342. pnmv->uNewState == 0x1000 || pnmv->uNewState == 0x2000) &&
  343. // TODO: Find definitions for x1000 and x2000 (check box state change in a list view control)
  344. // g_ItemChanged.isClicked &&
  345. g_ChkBoxUpdate)
  346. {
  347. NMITEMACTIVATE *ll = (LPNMITEMACTIVATE)lParam;
  348. HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST);
  349. g_ItemChanged.isValid = TRUE;
  350. g_ItemChanged.iItem = ll->iItem;
  351. g_ItemChanged.isClicked = FALSE;
  352. //
  353. // this flag is VERY important for consistent state changes
  354. // and eliminating race conditions
  355. //
  356. g_ChkBoxUpdate = FALSE;
  357. OnListCtrl_UpdateFromCheckBoxes( hDlg );
  358. g_ChkBoxUpdate = TRUE;
  359. g_ItemChanged.isValid = FALSE;
  360. UpdateListItem(hDlg, g_ItemChanged.iItem);
  361. {
  362. HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST);
  363. SetListCtrlItemFocus( hLC, (BYTE)g_ItemChanged.iItem );
  364. }
  365. // UpdateListAndScrollBar(hDlg, TRUE); // Update the scroll bar only
  366. }
  367. }
  368. return TRUE;
  369. break;
  370. } // switch
  371. return(0);
  372. }
  373. const INT bigInc = 5;
  374. const INT smlInc = 1;
  375. void OnScroll(HWND hDlg, WPARAM wParam)
  376. {
  377. INT curPos = 0;
  378. INT newPos = 0;
  379. INT xInc = 0;
  380. curPos = (INT) SendDlgItemMessage(hDlg,
  381. IDC_APPMAN_SCROLLBAR,
  382. TBM_GETPOS,
  383. (WPARAM) 0,
  384. (LPARAM) 0);
  385. switch(LOWORD (wParam))
  386. {
  387. // User clicked shaft left of the scroll box.
  388. case SB_PAGEUP:
  389. xInc = -bigInc;
  390. break;
  391. // User clicked shaft right of the scroll box.
  392. case SB_PAGEDOWN:
  393. xInc = +bigInc;
  394. break;
  395. // User clicked the left arrow.
  396. case SB_LINEUP:
  397. xInc = -smlInc;
  398. break;
  399. // User clicked the right arrow.
  400. case SB_LINEDOWN:
  401. xInc = +smlInc;
  402. break;
  403. // User dragged the scroll box.
  404. case SB_THUMBTRACK:
  405. xInc = HIWORD(wParam) - curPos;
  406. break;
  407. default:
  408. xInc = 0;
  409. }
  410. newPos = curPos + xInc;
  411. // also sets scroll bar
  412. UpdateCurrentDeviceFromScrollBar( hDlg, newPos );
  413. }
  414. void UpdateCurrentDeviceFromScrollBar( HWND hDlg, DWORD newPos )
  415. {
  416. DWORD percent, devIndex;
  417. //
  418. // Update scroll bar & text to this drive
  419. //
  420. devIndex = GetCurrentDeviceFromList( hDlg );
  421. if( devIndex < 0 ) return;
  422. percent = newPos;
  423. // SET app man drive percentage
  424. HRESULT hr = AppManSetGameDiskUsage( devIndex, percent );
  425. UpdateListItem(hDlg, g_ItemChanged.iItem, FALSE);
  426. //UpdateListAndScrollBar( hDlg);
  427. }
  428. #if 0
  429. void OnListCtrl_DblClick(HWND hDlg)
  430. {
  431. HRESULT hr;
  432. BOOL bIsExcluded = FALSE;
  433. BYTE nItem = 0;
  434. //
  435. // toggle drive exlusion
  436. //
  437. DWORD nDevIndex = GetCurrentDeviceFromList( hDlg, &nItem );
  438. if( nDevIndex < 0 ) return;
  439. hr = AppManIsDeviceExcluded( nDevIndex, bIsExcluded );
  440. //
  441. // Toggle exclusion
  442. //
  443. hr = AppManExcludeDevice( nDevIndex, !bIsExcluded );
  444. //
  445. // Update display: list & scroll bar!
  446. //
  447. UpdateListAndScrollBar( hDlg );
  448. }
  449. #endif
  450. void OnListCtrl_UpdateFromCheckBoxes( HWND hDlg )
  451. {
  452. HRESULT hr;
  453. BOOL bIsExcluded = FALSE;
  454. BYTE nItem = 0;
  455. //
  456. // go through each item, check the box & set exclusion
  457. //
  458. HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST);
  459. if( !hLC ) return;
  460. int iItem = -1;
  461. if( g_ItemChanged.isValid )
  462. {
  463. //
  464. // very important: tell the system that this information is no longer
  465. // valid. hence we won't recurse misteriously or unpredictably
  466. //
  467. g_ItemChanged.isValid = FALSE;
  468. iItem = g_ItemChanged.iItem;
  469. BOOL isIncluded = ListView_GetCheckState( hLC, iItem );
  470. DWORD dwDevIndex = GetItemData( hLC, (BYTE)iItem );
  471. hr = AppManExcludeDevice( dwDevIndex, isIncluded );
  472. }
  473. //
  474. // Update display: list & scroll bar!
  475. //
  476. //UpdateListAndScrollBar( hDlg );
  477. g_ChkBoxUpdate = TRUE;
  478. }
  479. #define APPMAN_DEFAULT_GAME_DISK_USAGE 0xFFFFFFFF // this code means, get default from registry
  480. void OnButtonPress( HWND hDlg )
  481. {
  482. if( !AppManInitialized() ) return;
  483. GUID sDevGuid;
  484. // reset defaults
  485. for(int i = 0; i<MAX_DEVICES; i++) {
  486. if( AppManDoesDeviceExist( i, sDevGuid ) ) {
  487. AppManExcludeDevice( i, TRUE );
  488. AppManSetGameDiskUsage( i, APPMAN_DEFAULT_GAME_DISK_USAGE);
  489. }
  490. }
  491. // Force the advanced mode off
  492. if (SUCCEEDED(AppManSetAdvMode(FALSE)))
  493. {
  494. // Clear the advance mode check box
  495. HWND hCtl = GetDlgItem(hDlg,IDC_APPMAN_ADVUSER);
  496. ::SendMessage(hCtl,BM_SETCHECK,BST_UNCHECKED,0L);
  497. InvalidateRect(hCtl, NULL, TRUE);
  498. }
  499. // update everything
  500. UpdateListAndScrollBar( hDlg );
  501. g_ItemChanged.iItem = 0;
  502. OnListCtrl_Select(hDlg);
  503. }
  504. void OnMoreInfoButton( HWND hDlg )
  505. {
  506. DialogBox(ghInstance, MAKEINTRESOURCE(IDD_APPMAN_MORE_INFO), hDlg, MoreInfoProc);
  507. return;
  508. }
  509. INT_PTR CALLBACK MoreInfoProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  510. {
  511. #define INFO_STR_LEN 2048
  512. BOOL fRet;
  513. HICON hIcon;
  514. TCHAR szMoreInfo[INFO_STR_LEN] = {0};
  515. fRet = FALSE;
  516. switch (message)
  517. {
  518. case WM_INITDIALOG:
  519. {
  520. if (hIcon = LoadIcon(NULL, IDI_INFORMATION))
  521. SendDlgItemMessage(hDlg, IDC_INFO_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
  522. if (LoadString(ghInstance, IDS_APPMAN_MORE_INFO_EDITBOX, szMoreInfo, INFO_STR_LEN))
  523. SetDlgItemText(hDlg, IDC_APPMAN_MORE_INFO_EDITBOX, szMoreInfo);
  524. break;
  525. }
  526. case WM_COMMAND:
  527. switch (LOWORD(wParam))
  528. {
  529. case IDOK:
  530. case IDCANCEL:
  531. EndDialog(hDlg, LOWORD(wParam));
  532. fRet = TRUE;
  533. break;
  534. default:
  535. break;
  536. }
  537. break;
  538. default:
  539. break;
  540. }
  541. return fRet;
  542. }
  543. void OnAdvancedModeCheckBox( HWND hCtl )
  544. {
  545. if( !hCtl || !AppManInitialized() ) return;
  546. // Advanced mode check box has been selected. Toggle the selection.
  547. BOOL bAdvMode;
  548. AppManGetAdvMode(bAdvMode);
  549. if (SUCCEEDED(AppManSetAdvMode(!bAdvMode)))
  550. {
  551. // Set the check box
  552. ::SendMessage(hCtl,BM_SETCHECK,(!bAdvMode ? BST_CHECKED : BST_UNCHECKED),0L);
  553. InvalidateRect(hCtl, NULL, TRUE);
  554. }
  555. }
  556. void UpdateListItem( HWND hDlg, int iItem, BOOL bUpdateScrollBarPos)
  557. {
  558. HRESULT hr;
  559. DWORD percent, devIndex;
  560. BOOL isExcluded = FALSE;
  561. GUID sDeviceGuid;
  562. TCHAR szTempText[MAX_STR_LEN] = {0};
  563. TCHAR szItemText1[MAX_STR_LEN] = {0};
  564. TCHAR szItemText2[MAX_STR_LEN] = {0};
  565. HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST);
  566. devIndex = GetItemData( hLC, (BYTE)iItem );
  567. if ( devIndex < 0 )
  568. return;
  569. if ( AppManDoesDeviceExist(devIndex, sDeviceGuid) )
  570. {
  571. #if 0 // Don't need to update the drive letter...
  572. // sets the text in the "Drive" column
  573. LPTSTR lpszDriveText = new (TCHAR[MAX_STR_LEN]);
  574. LoadString(ghInstance, IDS_APPMAN_DRIVE_TEXT, lpszDriveText, MAX_STR_LEN);
  575. _stprintf(szItemText1, lpszDriveText, devIndex + 65);
  576. delete lpszDriveText;
  577. SetItemText(hLC, iItem, APPMAN_LIST_DRIVE, szItemText1);
  578. #endif
  579. // Set the included/excluded text
  580. hr = AppManIsDeviceExcluded( devIndex, isExcluded );
  581. if ( isExcluded )
  582. {
  583. LoadString(ghInstance, IDS_APPMAN_EXCLUDED, szTempText, MAX_STR_LEN);
  584. _stprintf(szItemText1, szTempText);
  585. LoadString(ghInstance, IDS_APPMAN_CHECKBOX_NO, szTempText, MAX_STR_LEN);
  586. _stprintf(szItemText2, szTempText);
  587. }
  588. else
  589. {
  590. LoadString(ghInstance, IDS_APPMAN_GAME_USAGE, szTempText, MAX_STR_LEN);
  591. hr = AppManGetGameDiskUsage(devIndex, percent);
  592. _stprintf(szItemText1, szTempText, percent);
  593. LoadString(ghInstance, IDS_APPMAN_CHECKBOX_YES, szTempText, MAX_STR_LEN);
  594. _stprintf(szItemText2, szTempText);
  595. }
  596. //
  597. // Set the checkbox (FALSE = Not Checked = Excluded in the UI only).
  598. //
  599. ListView_SetCheckState( hLC, iItem, !isExcluded );
  600. // Set the excluded or percent (if not excluded) text
  601. SetItemText(hLC, (BYTE)iItem, APPMAN_LIST_EXCLUDED_PERCENT, szItemText1);
  602. // 3/31/2000(RichGr): Set "Allow new games" column to "Yes" or "No".
  603. SetItemText(hLC, (BYTE)iItem, APPMAN_LIST_EXCLUDE_CHECKBOX, szItemText2);
  604. if (bUpdateScrollBarPos)
  605. {
  606. // Set the scroll bar position
  607. // GET appman drive percentage
  608. hr = AppManGetGameDiskUsage( devIndex, percent );
  609. // set position on sb
  610. SetScrollBarPosition( hDlg, percent, devIndex );
  611. // En/disable scroll bar as needed
  612. EnableScrollBarAndText( hDlg, !isExcluded );
  613. }
  614. else
  615. {
  616. // At least change scroll bar text
  617. SetScrollBarString( hDlg, percent, devIndex );
  618. }
  619. }
  620. return;
  621. }
  622. void UpdateListAndScrollBar( HWND hDlg, BOOL bJustScrollBar )
  623. {
  624. HRESULT hr;
  625. DWORD percent, devIndex;
  626. BYTE nItem = 0;
  627. BOOL bCurrentDeviceExcluded = FALSE;
  628. devIndex = GetCurrentDeviceFromList( hDlg, &nItem );
  629. if( devIndex < 0 ) return;
  630. if( !bJustScrollBar )
  631. {
  632. // populate list
  633. PopulateListControl( hDlg, nItem );
  634. }
  635. hr = AppManIsDeviceExcluded( devIndex, bCurrentDeviceExcluded );
  636. // GET appman drive percentage
  637. hr = AppManGetGameDiskUsage( devIndex, percent );
  638. // set position on sb
  639. SetScrollBarPosition( hDlg, percent, devIndex );
  640. // set special text "Device D: is excluded"
  641. // disable scroll bar
  642. EnableScrollBarAndText( hDlg, !bCurrentDeviceExcluded );
  643. }
  644. void OnListCtrl_Select(HWND hDlg)
  645. {
  646. // UpdateListAndScrollBar( hDlg, TRUE );
  647. HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST);
  648. SetListCtrlItemFocus( hLC, (BYTE)g_ItemChanged.iItem );
  649. }
  650. int MyInsertItem( HWND hCtrl, LPTSTR lpszBuff, int iItem )
  651. {
  652. LPLVITEM plvItem = (LPLVITEM)_alloca(sizeof(LVITEM));
  653. ASSERT (plvItem);
  654. ZeroMemory( plvItem, sizeof( LVITEM ) );
  655. plvItem->mask = LVIF_TEXT;
  656. plvItem->pszText = lpszBuff;
  657. plvItem->cchTextMax = lstrlen(lpszBuff);
  658. plvItem->iItem = iItem;
  659. return ListView_InsertItem(hCtrl, (const LPLVITEM)plvItem);
  660. }
  661. void SetScrollBarPosition( HWND hDlg, INT pos, int iDevIndex )
  662. {
  663. SendDlgItemMessage(hDlg,
  664. IDC_APPMAN_SCROLLBAR,
  665. TBM_SETPOS,
  666. (WPARAM) TRUE,
  667. (LPARAM) pos);
  668. // change text
  669. SetScrollBarString( hDlg, pos, iDevIndex );
  670. }
  671. void SetScrollBarString(HWND hDlg, INT pos, int iDevIndex)
  672. {
  673. HRESULT hr;
  674. DWORD dwMegaBytes;
  675. TCHAR szTempText[MAX_STR_LEN] = {0};
  676. TCHAR szItemText1[MAX_STR_LEN] = {0};
  677. TCHAR szItemText2[MAX_STR_LEN] = {0};
  678. LoadString(ghInstance, IDS_APPMAN_GRP_PERCENT_DISK_USED, szTempText, MAX_STR_LEN);
  679. _stprintf(szItemText1, szTempText, iDevIndex + 65);
  680. hr = AppManGetAllocatedMeg( iDevIndex, pos, dwMegaBytes );
  681. LoadString(ghInstance, IDS_APPMAN_GAME_SPACE_ON_DRIVE, szTempText, MAX_STR_LEN);
  682. _stprintf(szItemText2, szTempText, iDevIndex + 65, dwMegaBytes, pos);
  683. SendDlgItemMessage(hDlg, IDC_APPMAN_GRP_PERCENT_DISK_USED, WM_SETTEXT, 0, (LPARAM)szItemText1);
  684. SendDlgItemMessage(hDlg, IDC_APPMAN_TEXT_PERCENT_DISK_USED, WM_SETTEXT, 0, (LPARAM)szItemText2);
  685. return;
  686. }
  687. #define ISVALID(item) ( (item < MAX_DEVICES) && (item>=0) )
  688. // Default device is the first one.
  689. DWORD g_CurrentItem = 0;
  690. DWORD GetCurrentDeviceFromList( HWND hDlg, BYTE *nItem )
  691. {
  692. if( ! AppManInitialized() ) return -1;
  693. if( ! g_ListPopulated ) return -1;
  694. int item = -1;
  695. HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST);
  696. if( g_ItemChanged.isValid ) {
  697. // use this info 'cause it was set by the itemchanged notification
  698. item = g_ItemChanged.iItem;
  699. } else {
  700. item = ListView_GetNextItem(hLC, -1, LVNI_SELECTED);
  701. if( ! ISVALID(item) ) {
  702. item = ListView_GetNextItem(hLC, -1, LVNI_FOCUSED);
  703. }
  704. }
  705. DWORD dwDev = -1;
  706. if( ISVALID(item) ) {
  707. dwDev = GetItemData( hLC, (BYTE)item );
  708. if( ISVALID(dwDev) ) {
  709. g_CurrentItem = item;
  710. if( nItem != NULL) {
  711. *nItem = (BYTE)item;
  712. }
  713. } else {
  714. dwDev = item = -1;
  715. }
  716. }
  717. return dwDev;
  718. }
  719. void ConfigureListControl( HWND hDlg )
  720. {
  721. HWND hLC;
  722. LVCOLUMN lvColumn = {0};
  723. RECT rc;
  724. hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST);
  725. ::SendMessage(hLC , LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
  726. LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES | LVS_EX_HEADERDRAGDROP
  727. // LVS_EX_TWOCLICKACTIVATE // LVN_ITEMACTIVATE (WM_NOTIFY)
  728. );
  729. GetClientRect(hLC, &rc);
  730. // 4/18/2000(RichGr): Bug 32634 - Reduce the size of the columns to just below 100% so we
  731. // can avoid a horizontal scrollbar showing up under some resolutions.
  732. DWORD w = ((rc.right - rc.left) * 95) / 100;
  733. DWORD w1 = w / 3; // 33% of width
  734. w = w - w1;
  735. DWORD w2 = w / 3; // 1/3 of remaining width
  736. DWORD w3 = w - w2; // remaining width
  737. InsertColumn(hLC, APPMAN_LIST_EXCLUDE_CHECKBOX, IDS_APPMAN_EXCLUDE_CHECKBOX, (USHORT)(w1));
  738. InsertColumn(hLC, APPMAN_LIST_DRIVE, IDS_APPMAN_DRIVE, (USHORT)(w2));
  739. InsertColumn(hLC, APPMAN_LIST_EXCLUDED_PERCENT, IDS_APPMAN_EXCLUDED_PERCENT, (USHORT)(w3));
  740. // 3/31/2000(RichGr): Center Yes/No text in checkbox column.
  741. lvColumn.mask = LVCF_FMT;
  742. lvColumn.fmt = LVCFMT_CENTER;
  743. ListView_SetColumn( hLC, APPMAN_LIST_EXCLUDE_CHECKBOX, &lvColumn );
  744. #if 0
  745. //
  746. // now move the 0'th column all the way to the right
  747. //
  748. // Allocate the structure
  749. LPLVCOLUMN plvColumn = (LPLVCOLUMN)_alloca(sizeof(LVCOLUMN));
  750. ASSERT (plvColumn);
  751. ZeroMemory(plvColumn, sizeof(LVCOLUMN));
  752. plvColumn->mask = LVCF_FMT | LVCF_ORDER;
  753. plvColumn->fmt = LVCFMT_CENTER;
  754. plvColumn->iOrder = 2;
  755. ListView_SetColumn( hLC, APPMAN_LIST_EXCLUDE_CHECKBOX, plvColumn );
  756. #endif
  757. return;
  758. }
  759. // populates from appman state
  760. void PopulateListControl( HWND hDlg, BYTE nItem )
  761. {
  762. HRESULT hr = S_OK;
  763. GUID sDeviceGuid;
  764. BOOL isExcluded = FALSE;
  765. DWORD percent = 70;
  766. UCHAR listIndex = (UCHAR)0;
  767. TCHAR szTempText[MAX_STR_LEN] = {0};
  768. TCHAR szItemText1[MAX_STR_LEN] = {0};
  769. TCHAR szItemText2[MAX_STR_LEN] = {0};
  770. g_ListPopulated = FALSE;
  771. g_ChkBoxUpdate = FALSE;
  772. Assert( AppManInitialized() );
  773. HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST);
  774. // Turn Redraw off here else it will flicker!
  775. ::SendMessage(hLC, WM_SETREDRAW, (WPARAM)FALSE, 0);
  776. // Out with the old...
  777. ::SendMessage(hLC, LVM_DELETEALLITEMS, 0, 0);
  778. //
  779. // we use do/while construct because we can only insert at the front of the list.
  780. //
  781. for(DWORD nDevIndex = 0; nDevIndex < MAX_DEVICES; nDevIndex++)
  782. {
  783. if( AppManDoesDeviceExist(nDevIndex, sDeviceGuid) )
  784. {
  785. //
  786. // this array maps list entry indices to valid device indices.
  787. // for example, list entry index 0 contains drive D, which is index 2
  788. //
  789. LoadString(ghInstance, IDS_APPMAN_DRIVE_TEXT, szTempText, MAX_STR_LEN);
  790. _stprintf(szItemText1, szTempText, nDevIndex + 65);
  791. //
  792. // Insert the Drive name
  793. //
  794. // Creates an item with a checkbox.
  795. int actualListIndex = MyInsertItem( hLC, _T(""), listIndex );
  796. SetItemData( hLC, (BYTE)actualListIndex, nDevIndex );
  797. // sets the text in the "Drive" column
  798. SetItemText(hLC, (BYTE)actualListIndex, APPMAN_LIST_DRIVE, szItemText1);
  799. //
  800. // Populate the columns with "excluded" or "percentage"
  801. //
  802. hr = AppManIsDeviceExcluded( nDevIndex, isExcluded );
  803. if ( isExcluded )
  804. {
  805. LoadString(ghInstance, IDS_APPMAN_EXCLUDED, szTempText, MAX_STR_LEN);
  806. _stprintf(szItemText1, szTempText);
  807. LoadString(ghInstance, IDS_APPMAN_CHECKBOX_NO, szTempText, MAX_STR_LEN);
  808. _stprintf(szItemText2, szTempText);
  809. }
  810. else
  811. {
  812. LoadString(ghInstance, IDS_APPMAN_GAME_USAGE, szTempText, MAX_STR_LEN);
  813. hr = AppManGetGameDiskUsage(nDevIndex, percent);
  814. _stprintf(szItemText1, szTempText, percent);
  815. LoadString(ghInstance, IDS_APPMAN_CHECKBOX_YES, szTempText, MAX_STR_LEN);
  816. _stprintf(szItemText2, szTempText);
  817. }
  818. //
  819. // sets the checkbox if it's excluded
  820. //
  821. ListView_SetCheckState( hLC, actualListIndex, !isExcluded );
  822. SetItemText(hLC, (BYTE)actualListIndex, APPMAN_LIST_EXCLUDED_PERCENT, szItemText1);
  823. // 3/31/2000(RichGr): Set "Allow new games" column to "Yes" or "No".
  824. SetItemText(hLC, (BYTE)actualListIndex, APPMAN_LIST_EXCLUDE_CHECKBOX, szItemText2);
  825. listIndex++;
  826. } // if
  827. } // for
  828. //
  829. // set focus on that item
  830. //
  831. SetListCtrlItemFocus( hLC, nItem );
  832. //
  833. // Turn the redraw flag back on!
  834. //
  835. ::SendMessage (hLC, WM_SETREDRAW, (WPARAM)TRUE, 0);
  836. g_ListPopulated = TRUE;
  837. g_ChkBoxUpdate = TRUE;
  838. return;
  839. }
  840. /*
  841. BOOL ListView_SortItems(
  842. HWND hwnd,
  843. PFNLVCOMPARE pfnCompare,
  844. LPARAM lParamSort
  845. );
  846. BOOL ListView_SortItemsEx(
  847. HWND hwnd,
  848. PFNLVCOMPARE pfnCompare,
  849. LPARAM lParamSort
  850. );
  851. This macro is similar to ListView_SortItems,
  852. except for the type of information passed to the comparison function.
  853. With ListView_SortItemsEx, the item's index is passed instead
  854. of its lparam value.
  855. int CALLBACK CompareFunc(
  856. LPARAM lParam1,
  857. LPARAM lParam2,
  858. LPARAM lParamSort);
  859. */
  860. void EnableAllControls( HWND hDlg, BOOL bEnable )
  861. {
  862. // HWND hwnd;
  863. // do manage disk cb
  864. //hwnd = GetDlgItem(hDlg, IDC_APPMAN_MANAGE_DISK);
  865. //EnableWindow( hwnd, bEnable );
  866. EnableDiskManageControls( hDlg, bEnable );
  867. }
  868. void EnableDiskManageControls( HWND hDlg, BOOL bEnable )
  869. {
  870. HWND hwnd;
  871. // LIST CONTROL
  872. hwnd = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST);
  873. EnableWindow( hwnd, bEnable );
  874. EnableScrollBarAndText( hDlg, bEnable );
  875. }
  876. void EnableScrollBarAndText( HWND hDlg, BOOL bEnable )
  877. {
  878. HWND hwnd;
  879. // SCROLLBAR
  880. //PostDlgItemEnableWindow( hDlg, IDC_APPMAN_SCROLLBAR, enableManageDiskSpace );
  881. hwnd = GetDlgItem(hDlg, IDC_APPMAN_SCROLLBAR);
  882. EnableWindow( hwnd, bEnable );
  883. // TEXT
  884. hwnd = GetDlgItem(hDlg, IDC_APPMAN_TEXT_PERCENT_DISK_USED);
  885. EnableWindow( hwnd, bEnable );
  886. }
  887. ///////////////////////////////////////////////////////////////////
  888. // AppMan functions
  889. ///////////////////////////////////////////////////////////////////
  890. #define RELEASE(p) { if((p)) { (p)->Release(); p = NULL; } }
  891. IApplicationManagerAdmin *g_IAppManAdmin = NULL;
  892. BOOL AppManInitialized() { return (g_IAppManAdmin != NULL); }
  893. HRESULT AppManInit()
  894. {
  895. HRESULT hr = S_OK;
  896. // Important
  897. if( AppManInitialized() ) return hr;
  898. if (FAILED(CoInitialize(NULL)))
  899. {
  900. return E_FAIL;
  901. }
  902. hr = CoCreateInstance(CLSID_ApplicationManager,
  903. NULL,
  904. CLSCTX_INPROC_SERVER,
  905. IID_ApplicationManagerAdmin,
  906. (LPVOID *) &g_IAppManAdmin);
  907. if( FAILED(hr) ) return hr;
  908. return hr;
  909. }
  910. BOOL AppManDoesDeviceExist(DWORD devIndex, GUID &sDevGuid)
  911. {
  912. return (SUCCEEDED(g_IAppManAdmin->EnumerateDevices(devIndex, &sDevGuid))) ? TRUE : FALSE;
  913. }
  914. DWORD g_dwExclusionMask = APP_CATEGORY_ENTERTAINMENT;
  915. HRESULT AppManShutdown()
  916. {
  917. RELEASE( g_IAppManAdmin );
  918. return S_OK;
  919. }
  920. HRESULT AppManSetGameDiskUsage(DWORD devIndex, DWORD percent)
  921. {
  922. HRESULT hr = S_OK;
  923. GUID sDeviceGuid;
  924. if( g_IAppManAdmin ) {
  925. if (SUCCEEDED(g_IAppManAdmin->EnumerateDevices(devIndex, &sDeviceGuid)))
  926. {
  927. hr = g_IAppManAdmin->SetDeviceProperty(DEVICE_PROPERTY_PERCENTCACHESIZE,
  928. &sDeviceGuid,
  929. &percent,
  930. sizeof(percent));
  931. }
  932. }
  933. return hr;
  934. }
  935. HRESULT AppManGetAdvMode(BOOL &bAdvMode)
  936. {
  937. HRESULT hr = S_OK;
  938. if( g_IAppManAdmin )
  939. hr = g_IAppManAdmin->GetAppManProperty(APPMAN_PROPERTY_ADVANCEDMODE, &bAdvMode, sizeof(DWORD));
  940. return hr;
  941. }
  942. HRESULT AppManSetAdvMode(BOOL bAdvMode)
  943. {
  944. HRESULT hr = S_OK;
  945. if( g_IAppManAdmin )
  946. hr = g_IAppManAdmin->SetAppManProperty(APPMAN_PROPERTY_ADVANCEDMODE, &bAdvMode, sizeof(DWORD));
  947. return hr;
  948. }
  949. HRESULT AppManGetGameDiskUsage(DWORD devIndex, DWORD &percent)
  950. {
  951. HRESULT hr = S_OK;
  952. GUID sDeviceGuid;
  953. if( g_IAppManAdmin ) {
  954. if (SUCCEEDED(g_IAppManAdmin->EnumerateDevices(devIndex, &sDeviceGuid)))
  955. {
  956. hr = g_IAppManAdmin->GetDeviceProperty(DEVICE_PROPERTY_PERCENTCACHESIZE,
  957. &sDeviceGuid,
  958. &percent,
  959. sizeof(percent));
  960. }
  961. }
  962. return hr;
  963. }
  964. HRESULT AppManExcludeDevice(DWORD devIndex, BOOL bDoInclude)
  965. {
  966. HRESULT hr = S_OK;
  967. GUID sDeviceGuid;
  968. if( g_IAppManAdmin )
  969. {
  970. if (SUCCEEDED(g_IAppManAdmin->EnumerateDevices(devIndex, &sDeviceGuid)))
  971. {
  972. DWORD dwMask = g_dwExclusionMask;
  973. // Get the prior mask.
  974. hr = g_IAppManAdmin->GetDeviceProperty(DEVICE_PROPERTY_EXCLUSIONMASK,
  975. &sDeviceGuid,
  976. &dwMask,
  977. sizeof(g_dwExclusionMask));
  978. if (SUCCEEDED(hr))
  979. {
  980. if( !bDoInclude )
  981. {
  982. // Exclude the drive, set the APP_CATEGORY_ENTERTAINMENT bit
  983. dwMask |= APP_CATEGORY_ENTERTAINMENT;
  984. }
  985. else
  986. {
  987. // Include the drive, clear the APP_CATEGORY_ENTERTAINMENT bit
  988. dwMask &= ~APP_CATEGORY_ENTERTAINMENT;
  989. }
  990. hr = g_IAppManAdmin->SetDeviceProperty(DEVICE_PROPERTY_EXCLUSIONMASK,
  991. &sDeviceGuid,
  992. &dwMask,
  993. sizeof(g_dwExclusionMask));
  994. }
  995. }
  996. }
  997. return hr;
  998. }
  999. HRESULT AppManIsDeviceExcluded(DWORD devIndex, BOOL &isExcluded)
  1000. {
  1001. HRESULT hr = S_OK;
  1002. GUID sDeviceGuid;
  1003. DWORD dwExcMask;
  1004. if( g_IAppManAdmin ) {
  1005. if (SUCCEEDED(g_IAppManAdmin->EnumerateDevices(devIndex, &sDeviceGuid)))
  1006. {
  1007. hr = g_IAppManAdmin->GetDeviceProperty(DEVICE_PROPERTY_EXCLUSIONMASK,
  1008. &sDeviceGuid,
  1009. &dwExcMask,
  1010. sizeof(dwExcMask));
  1011. if( SUCCEEDED(hr) ) {
  1012. //
  1013. // XXX: make sure JUST the flags i'm interested in are on
  1014. //
  1015. if( dwExcMask & APP_CATEGORY_ENTERTAINMENT) // somthing is on
  1016. {
  1017. isExcluded = TRUE;
  1018. } else {
  1019. isExcluded = FALSE;
  1020. }
  1021. }
  1022. }
  1023. }
  1024. return hr;
  1025. }
  1026. HRESULT AppManGetAllocatedMeg(DWORD devIndex, DWORD percent, DWORD &dwMegaBytes)
  1027. {
  1028. HRESULT hr = S_OK;
  1029. GUID sDeviceGuid;
  1030. if( g_IAppManAdmin ) {
  1031. if (SUCCEEDED(g_IAppManAdmin->EnumerateDevices(devIndex, &sDeviceGuid)))
  1032. {
  1033. hr = g_IAppManAdmin->GetDeviceProperty(DEVICE_PROPERTY_TOTALKILOBYTES,
  1034. &sDeviceGuid,
  1035. &dwMegaBytes,
  1036. sizeof(dwMegaBytes));
  1037. if(SUCCEEDED(hr)) {
  1038. dwMegaBytes = DWORD( float(dwMegaBytes) * (float(percent) / 100.0f) );
  1039. dwMegaBytes = dwMegaBytes >> 10; // turn kilobytes into megabytes
  1040. } else {
  1041. dwMegaBytes = -1;
  1042. }
  1043. }
  1044. }
  1045. return hr;
  1046. }
  1047. ////////////////////////////////////////////////////////////////////////////////////////
  1048. // FUNCTION: OnAdvHelp ( LPARAM lParam )
  1049. //
  1050. // PARAMETERS: lParam - Pointer to HELPINFO struct
  1051. //
  1052. // PURPOSE: WM_HELP message handler
  1053. ////////////////////////////////////////////////////////////////////////////////////////
  1054. void OnAdvHelp(LPARAM lParam)
  1055. {
  1056. ASSERT (lParam);
  1057. // point to help file
  1058. LPTSTR pszHelpFileName = new TCHAR[STR_LEN_32];
  1059. ASSERT (pszHelpFileName);
  1060. if( LoadString(ghInstance, IDS_HELPFILENAME, pszHelpFileName, STR_LEN_32) )
  1061. {
  1062. if( ((LPHELPINFO)lParam)->iContextType == HELPINFO_WINDOW )
  1063. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, pszHelpFileName, HELP_WM_HELP, (ULONG_PTR)gaHelpIDs);
  1064. }
  1065. #ifdef _DEBUG
  1066. else OutputDebugString(TEXT("JOY.CPL: AppMan.cpp: OnAdvHelp: LoadString Failed to find IDS_HELPFILENAME!\n"));
  1067. #endif // _DEBUG
  1068. if( pszHelpFileName )
  1069. delete[] (pszHelpFileName);
  1070. }
  1071. ////////////////////////////////////////////////////////////////////////////////////////
  1072. // FUNCTION: OnContextMenu ( WPARAM wParam )
  1073. //
  1074. // PARAMETERS: wParam - HWND of window under the pointer
  1075. //
  1076. // PURPOSE: Handle WM_RBUTTONDOWN over all client windows
  1077. // (except the list control... that's OnListviewContextMenu() job)
  1078. ////////////////////////////////////////////////////////////////////////////////////////
  1079. void OnContextMenu(WPARAM wParam, LPARAM lParam)
  1080. {
  1081. // HWND hListCtrl = NULL
  1082. ASSERT (wParam);
  1083. #if 0
  1084. hListCtrl = GetDlgItem((HWND) wParam, IDC_APPMAN_DRIVE_LIST);
  1085. // If you are on the ListCtrl...
  1086. if( (HWND)wParam == hListCtrl )
  1087. {
  1088. SetFocus(hListCtrl);
  1089. // Don't attempt if nothing selected
  1090. if( iItem != NO_ITEM )
  1091. OnListviewContextMenu(hListCtrl,lParam);
  1092. } else
  1093. #endif
  1094. {
  1095. // point to help file
  1096. LPTSTR pszHelpFileName = new TCHAR[STR_LEN_32];
  1097. ASSERT (pszHelpFileName);
  1098. if( LoadString(ghInstance, IDS_HELPFILENAME, pszHelpFileName, STR_LEN_32) )
  1099. WinHelp((HWND)wParam, pszHelpFileName, HELP_CONTEXTMENU, (ULONG_PTR)gaHelpIDs);
  1100. #ifdef _DEBUG
  1101. else OutputDebugString(TEXT("JOY.CPL: appman.cpp: OnContextMenu: LoadString Failed to find IDS_HELPFILENAME!\n"));
  1102. #endif // _DEBUG
  1103. if( pszHelpFileName )
  1104. delete[] (pszHelpFileName);
  1105. }
  1106. }
  1107. ///////////////////////////////////////////////////////////////////////////////
  1108. // FUNCTION: OnListviewContextMenu( void )
  1109. //
  1110. // PURPOSE: Handle Context menu in Listview
  1111. //
  1112. // RETURN: TRUE if successfull, FALSE otherwise
  1113. ///////////////////////////////////////////////////////////////////////////////
  1114. static void OnListviewContextMenu( HWND hWnd, LPARAM lParam )
  1115. {
  1116. HMENU hPopupMenu = CreatePopupMenu();
  1117. HWND hListCtrl = NULL;
  1118. hListCtrl = GetDlgItem(hWnd, IDC_APPMAN_DRIVE_LIST);
  1119. ASSERT (hPopupMenu);
  1120. // unlike life, bRet defaults to bliss
  1121. BOOL bRet = TRUE;
  1122. LPTSTR pszText = new TCHAR[STR_LEN_32];
  1123. ASSERT (pszText);
  1124. // Don't display Rename/Change if on (none) entry
  1125. if( !(GetItemData(hListCtrl, (BYTE)iItem) & ID_NONE) )
  1126. {
  1127. if( TRUE ) // Borrowed code...
  1128. {
  1129. // add the "Change..." string
  1130. ::SendDlgItemMessage(GetParent(hListCtrl), IDC_ADV_CHANGE, WM_GETTEXT, (WPARAM)STR_LEN_32, (LPARAM)(LPCTSTR)pszText);
  1131. bRet = AppendMenu(hPopupMenu, MF_ENABLED, IDC_ADV_CHANGE, pszText);
  1132. #ifdef _DEBUG
  1133. if( !bRet )
  1134. TRACE(TEXT("JOY.CPL: OnListviewCOntextMenu: AppendMenu Failed to insert %s\n"), pszText);
  1135. #endif //_DEBUG
  1136. // Add the Rename text
  1137. VERIFY(LoadString(ghInstance, IDS_RENAME, pszText, STR_LEN_32));
  1138. bRet = AppendMenu(hPopupMenu, MF_ENABLED, IDC_RENAME, pszText);
  1139. #ifdef _DEBUG
  1140. if( !bRet )
  1141. TRACE(TEXT("JOY.CPL: OnListviewCOntextMenu: AppendMenu Failed to insert %s\n"), pszText);
  1142. #endif //_DEBUG
  1143. // Add the SEPERATOR and "What's this?"
  1144. bRet = AppendMenu(hPopupMenu, MF_SEPARATOR, 0, 0);
  1145. #ifdef _DEBUG
  1146. if( !bRet )
  1147. TRACE(TEXT("JOY.CPL: OnListviewCOntextMenu: AppendMenu Failed to insert SEPERATOR!\n"));
  1148. #endif //_DEBUG
  1149. }
  1150. }
  1151. VERIFY(LoadString(ghInstance, IDS_WHATSTHIS, pszText, STR_LEN_32));
  1152. bRet = AppendMenu(hPopupMenu, MF_ENABLED, IDS_WHATSTHIS, pszText);
  1153. #ifdef _DEBUG
  1154. if( !bRet )
  1155. TRACE(TEXT("JOY.CPL: OnListviewCOntextMenu: AppendMenu Failed to insert %s\n"), pszText);
  1156. #endif //_DEBUG
  1157. if( pszText ) delete[] (pszText);
  1158. POINT pt;
  1159. // lParam is -1 if we got here via Shift+F10
  1160. if( lParam > 0 )
  1161. {
  1162. pt.x = GET_X_LPARAM(lParam);
  1163. pt.y = GET_Y_LPARAM(lParam);
  1164. } else
  1165. {
  1166. // Center the popup on the selected item!
  1167. // This get's a good X pos, but the y is the start of the control!
  1168. ::SendMessage(hListCtrl, LVM_GETITEMPOSITION, iItem, (LPARAM)&pt);
  1169. RECT rc;
  1170. ::GetClientRect(hListCtrl, &rc);
  1171. pt.x = rc.right>>1;
  1172. ClientToScreen(hListCtrl, &pt);
  1173. }
  1174. bRet = TrackPopupMenu (hPopupMenu, TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON, pt.x, pt.y, 0, ghDlg, NULL);
  1175. #ifdef _DEBUG
  1176. if( !bRet )
  1177. TRACE (TEXT("JOY.CPL: OnListviewContextMenu: TrackPopupMenu Failed!\n"));
  1178. #endif //_DEBUG
  1179. DestroyMenu (hPopupMenu);
  1180. }