/* File: AppMan.cpp Project: Author: DDalal & ScottLe Date: 10/22/99 Comments: AppMan Settings Tab in Game Control Panel. Copyright (c) 1999, Microsoft Corporation */ // This is necessary LVS_EX_INFOTIP #if (_WIN32_IE < 0x400) #undef _WIN32_IE #define _WIN32_IE 0x400 #if 0 typedef struct tagNMITEMACTIVATE{ NMHDR hdr; int iItem; int iSubItem; UINT uNewState; UINT uOldState; UINT uChanged; POINT ptAction; LPARAM lParam; UINT uKeyFlags; } NMITEMACTIVATE, FAR *LPNMITEMACTIVATE; #endif #endif #include #include #include #include // For RegisterDeviceNotification stuff! #include // for DBT_ defines!!! #include // for listview #include // for TCHAR #include // for _alloca #include "hsvrguid.h" #include "cpanel.h" #include "resource.h" #include "joyarray.h" #ifdef MAX_DEVICES // The control panel and the addman both define MAX_DEVICES, we'll use the AppMan supplied version #undef MAX_DEVICES #endif #include #if _DEBUG #define Assert(x) { if(!(x)) { DebugBreak(); }} #else #define Assert(x) #endif static HWND ghDlg; HWND hAppManCheckBox; extern const DWORD gaHelpIDs[]; extern HINSTANCE ghInstance; // constants const short NO_ITEM = -1; static short iItem = NO_ITEM; // index of selected item static DWORD ct=0L; // Forwards // // local forwards // static BOOL OnInitDialog(HWND hDlg, HWND hWnd, LPARAM lParam); static void OnCommand(HWND hDlg, int id, HWND hWndCtl, UINT code); static BOOL OnNotify(HWND hDlg, WPARAM idFrom, LPARAM lParam); void OnScroll(HWND hDlg, WPARAM wParam); void OnListCtrl_Select(HWND hDlg); void OnListCtrl_DblClick(HWND hDlg); void OnListCtrl_UpdateFromCheckBoxes( HWND hDlg ); void OnButtonPress( HWND hDlg ); void OnAdvancedModeCheckBox( HWND hCtl); void OnMoreInfoButton( HWND hDlg ); INT_PTR CALLBACK MoreInfoProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); static void OnAdvHelp (LPARAM); static void OnContextMenu (WPARAM wParam, LPARAM lParam); static void OnListviewContextMenu (HWND hWnd, LPARAM lParam ); // util fcns int MyInsertItem( HWND hCtrl, LPTSTR lpszBuff, int iItem ); // replaced from cpanel.cpp void SetScrollBarString(HWND hDlg, INT pos, int iDevIndex ); void SetScrollBarPosition( HWND hDlg, INT pos, int iDevIndex ); void PostDlgItemEnableWindow( HWND hDlg, USHORT nItem, BOOL bEnabled ); void EnableDiskManageControls( HWND hDlg, BOOL bEnable ); void EnableScrollBarAndText( HWND hDlg, BOOL bEnable ); void EnableAllControls( HWND hDlg, BOOL bEnable ); DWORD GetCurrentDeviceFromList( HWND hDlg, BYTE *nItem = NULL ); void ConfigureListControl( HWND hDlg ); void PopulateListControl( HWND hDlg, BYTE nItem ); void UpdateCurrentDeviceFromScrollBar( HWND hDlg, DWORD newPos ); void UpdateListItem( HWND hDlg, int iItem, BOOL bUpdateScrollBarPos = TRUE); void UpdateListAndScrollBar( HWND hDlg, BOOL bJustScrollBar = FALSE ); // appman fcns HRESULT AppManGetGameDiskUsage(DWORD devIndex, DWORD &percent); HRESULT AppManSetGameDiskUsage(DWORD devIndex, DWORD percent); HRESULT AppManGetAllocatedMeg(DWORD devIndex, DWORD percent, DWORD &dwMegaBytes); HRESULT AppManShutdown(); HRESULT AppManInit(); HRESULT AppManIsDeviceExcluded(DWORD devIndex, BOOL &isExcluded); HRESULT AppManExcludeDevice(DWORD devIndex, BOOL bDoExclude ); BOOL AppManDoesDeviceExist(DWORD devIndex, GUID &sDevGuid); BOOL AppManInitialized(); HRESULT AppManSetAdvMode(BOOL bAdvMode); HRESULT AppManGetAdvMode(BOOL &bAdvMode); // // from cpanel.cpp // extern void SetItemText( HWND hCtrl, BYTE nItem, BYTE nSubItem, LPTSTR lpStr); extern void InsertColumn(HWND hCtrl, BYTE nColumn, USHORT nStrID, USHORT nWidth); extern BOOL SetItemData( HWND hCtrl, BYTE nItem, DWORD dwFlag ); extern DWORD GetItemData(HWND hCtrl, BYTE nItem ); extern void SetListCtrlItemFocus ( HWND hCtrl, BYTE nItem ); // // GLOBALS // BOOL g_ListPopulated = FALSE; int g_nm_click = -1; BOOL g_nm_click_state = FALSE; BOOL g_DlgInitialized = FALSE; BOOL g_ChkBoxUpdate = FALSE; #define APPMAN_LIST_EXCLUDE_CHECKBOX 0 #define APPMAN_LIST_DRIVE 1 #define APPMAN_LIST_EXCLUDED_PERCENT 2 struct { BOOL isValid; int iItem; BOOL isClicked; int iNextItem; BOOL bKeybrdChange; } g_ItemChanged; /////////////////////////////////////////////////////////////////////////////// // FUNCTION: AppManProc(HWND hDlg, ULONG uMsg, WPARAM wParam, LPARAM lParam) // // PARAMETERS: hDlg - // uMsg - // wParam - // lParam - // // PURPOSE: Main callback function for "Appman" sheet /////////////////////////////////////////////////////////////////////////////// BOOL WINAPI AppManProc(HWND hDlg, ULONG uMsg, WPARAM wParam, LPARAM lParam) { switch( uMsg ) { case WM_ACTIVATEAPP: if( wParam ) { HWND hListCtrl = NULL; hListCtrl = GetDlgItem((HWND) wParam, IDC_APPMAN_DRIVE_LIST); SetListCtrlItemFocus(hListCtrl, (BYTE)iItem); } break; case WM_DEVICECHANGE: switch( (UINT)wParam ) { case DBT_DEVICEARRIVAL: // case DBT_DEVICEREMOVECOMPLETE: break; } break; case WM_LBUTTONDOWN: // Click Drag service for PropSheets! //PostMessage(GetParent(hDlg), WM_NCLBUTTONDOWN, (WPARAM)HTCAPTION, lParam); break; case WM_INITDIALOG: if( !HANDLE_WM_INITDIALOG(hDlg, wParam, lParam, OnInitDialog) ) { // Fix #108983 NT, Remove Flash on Error condition. SetWindowPos(::GetParent(hDlg), HWND_BOTTOM, 0, 0, 0, 0, SWP_HIDEWINDOW); DestroyWindow(hDlg); } return(TRUE); case WM_COMMAND: HANDLE_WM_COMMAND(hDlg, wParam, lParam, OnCommand); return(TRUE); case WM_HSCROLL: OnScroll(hDlg, wParam); return(TRUE); case WM_DESTROY: //return(HANDLE_WM_DESTROY(hDlg, wParam, lParam, OnDestroy)); return(TRUE); case WM_NOTIFY: return OnNotify(hDlg, wParam, lParam); case WM_HELP: OnAdvHelp(lParam); return(TRUE); case WM_CONTEXTMENU: OnContextMenu(wParam, lParam); return(TRUE); default: break; } return(0); } /////////////////////////////////////////////////////////////////////////////// // FUNCTION: OnInitDialog(HWND hDlg, HWND hWnd, LPARAM lParam) // // PARAMETERS: hDlg - // hWnd - // lParam - // // PURPOSE: WM_INITDIALOG message handler /////////////////////////////////////////////////////////////////////////////// BOOL OnInitDialog(HWND hDlg, HWND hWnd, LPARAM lParam) { HRESULT hr = S_OK; hr = AppManInit(); // // init globals // ZeroMemory( &g_ItemChanged, sizeof(g_ItemChanged)); g_DlgInitialized = FALSE; if( FAILED(hr) ) { // // Disable everything // EnableAllControls(hDlg, FALSE); // // popup saying: hey you need appman installed ? // } else { ghDlg = hDlg; // // Set defaults // // // Configure the List control, and then fill it in // ConfigureListControl( hDlg ); PopulateListControl( hDlg, 0 ); // // TRACK BAR // { // Set range [0..100] SendDlgItemMessage(hDlg, IDC_APPMAN_SCROLLBAR, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG(0,100)); // set tick freq SendDlgItemMessage(hDlg, IDC_APPMAN_SCROLLBAR, TBM_SETTICFREQ, (WPARAM) 10, (LPARAM) 0); UpdateListAndScrollBar(hDlg, TRUE); // Update the scroll bar only // OnListCtrl_Select( hDlg ); } // Set the Advanced user check box { BOOL bAdvMode; AppManGetAdvMode(bAdvMode); SendDlgItemMessage(hDlg,IDC_APPMAN_ADVUSER, BM_SETCHECK,(bAdvMode ? BST_CHECKED : BST_UNCHECKED),0L); } g_DlgInitialized = TRUE; } // else return(TRUE); } /////////////////////////////////////////////////////////////////////////////// // FUNCTION: OnCommand(HWND hDlg, int id, HWND hWndCtl, UINT code) // // PARAMETERS: hDlg - // id - // hWndCtl - // code - // // PURPOSE: WM_COMMAND message handler /////////////////////////////////////////////////////////////////////////////// void OnCommand(HWND hDlg, int id, HWND hWndCtl, UINT code) { HRESULT hr = S_OK; switch( id ) { // // put the reset defaults button here // case IDC_APPMAN_RESTORE_DEFAULTS_BUTTON: OnButtonPress( hDlg ); break; case IDC_APPMAN_ADVUSER: OnAdvancedModeCheckBox( hWndCtl); break; case IDS_WHATSTHIS: { // point to help file LPTSTR pszHelpFileName = new TCHAR[STR_LEN_32]; ASSERT (pszHelpFileName); if( LoadString(ghInstance, IDS_HELPFILENAME, pszHelpFileName, STR_LEN_32) ) WinHelp((HWND)hDlg, pszHelpFileName, HELP_WM_HELP, (ULONG_PTR)gaHelpIDs); #ifdef _DEBUG else OutputDebugString(TEXT("JOY.CPL: AppMan.cpp: OnCommand: LoadString Failed to find IDS_HELPFILENAME!\n")); #endif // _DEBUG if( pszHelpFileName ) delete[] (pszHelpFileName); } break; case IDC_APPMAN_MORE_INFO: OnMoreInfoButton( hDlg ); break; /* case IDC_APPMAN_MANAGE_DISK: { BOOL isChecked = (IsDlgButtonChecked(hDlg, id)) ? TRUE : FALSE; EnableDiskManageControls( hDlg, !isChecked ); } break; */ default: break; } } //////////////////////////////////////////////////////////////////////////////// // // FUNCTION: OnNotify(HWND hDlg, WPARAM idFrom, NMHDR* pnmhdr) // // PARAMETERS: hDlg - // idFrom - ID of control sending WM_NOTIFY message // pnmhdr - // // PURPOSE: WM_NOTIFY message handler //////////////////////////////////////////////////////////////////////////////// BOOL OnNotify(HWND hDlg, WPARAM idFrom, LPARAM lParam) { NMLISTVIEW *pnmv; LPNMHDR pnmhdr = (LPNMHDR)lParam; switch( pnmhdr->code ) { case LVN_ITEMCHANGED: pnmv = (LPNMLISTVIEW) lParam; if( idFrom == IDC_APPMAN_DRIVE_LIST ) { // this is called if a new item has been selected // or if the user clicked on the checkbox, changing state #ifdef _DEBUG { TCHAR tstring[256]; NMITEMACTIVATE *pitemact = (LPNMITEMACTIVATE)lParam; _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); OutputDebugString(tstring); } #endif // _DEBUG if( AppManInitialized() && g_DlgInitialized && (pnmv->uNewState & LVIS_SELECTED || pnmv->uNewState == 0x1000 || pnmv->uNewState == 0x2000) && // TODO: Find definitions for x1000 and x2000 (check box state change in a list view control) // g_ItemChanged.isClicked && g_ChkBoxUpdate) { NMITEMACTIVATE *ll = (LPNMITEMACTIVATE)lParam; HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST); g_ItemChanged.isValid = TRUE; g_ItemChanged.iItem = ll->iItem; g_ItemChanged.isClicked = FALSE; // // this flag is VERY important for consistent state changes // and eliminating race conditions // g_ChkBoxUpdate = FALSE; OnListCtrl_UpdateFromCheckBoxes( hDlg ); g_ChkBoxUpdate = TRUE; g_ItemChanged.isValid = FALSE; UpdateListItem(hDlg, g_ItemChanged.iItem); { HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST); SetListCtrlItemFocus( hLC, (BYTE)g_ItemChanged.iItem ); } // UpdateListAndScrollBar(hDlg, TRUE); // Update the scroll bar only } } return TRUE; break; } // switch return(0); } const INT bigInc = 5; const INT smlInc = 1; void OnScroll(HWND hDlg, WPARAM wParam) { INT curPos = 0; INT newPos = 0; INT xInc = 0; curPos = (INT) SendDlgItemMessage(hDlg, IDC_APPMAN_SCROLLBAR, TBM_GETPOS, (WPARAM) 0, (LPARAM) 0); switch(LOWORD (wParam)) { // User clicked shaft left of the scroll box. case SB_PAGEUP: xInc = -bigInc; break; // User clicked shaft right of the scroll box. case SB_PAGEDOWN: xInc = +bigInc; break; // User clicked the left arrow. case SB_LINEUP: xInc = -smlInc; break; // User clicked the right arrow. case SB_LINEDOWN: xInc = +smlInc; break; // User dragged the scroll box. case SB_THUMBTRACK: xInc = HIWORD(wParam) - curPos; break; default: xInc = 0; } newPos = curPos + xInc; // also sets scroll bar UpdateCurrentDeviceFromScrollBar( hDlg, newPos ); } void UpdateCurrentDeviceFromScrollBar( HWND hDlg, DWORD newPos ) { DWORD percent, devIndex; // // Update scroll bar & text to this drive // devIndex = GetCurrentDeviceFromList( hDlg ); if( devIndex < 0 ) return; percent = newPos; // SET app man drive percentage HRESULT hr = AppManSetGameDiskUsage( devIndex, percent ); UpdateListItem(hDlg, g_ItemChanged.iItem, FALSE); //UpdateListAndScrollBar( hDlg); } #if 0 void OnListCtrl_DblClick(HWND hDlg) { HRESULT hr; BOOL bIsExcluded = FALSE; BYTE nItem = 0; // // toggle drive exlusion // DWORD nDevIndex = GetCurrentDeviceFromList( hDlg, &nItem ); if( nDevIndex < 0 ) return; hr = AppManIsDeviceExcluded( nDevIndex, bIsExcluded ); // // Toggle exclusion // hr = AppManExcludeDevice( nDevIndex, !bIsExcluded ); // // Update display: list & scroll bar! // UpdateListAndScrollBar( hDlg ); } #endif void OnListCtrl_UpdateFromCheckBoxes( HWND hDlg ) { HRESULT hr; BOOL bIsExcluded = FALSE; BYTE nItem = 0; // // go through each item, check the box & set exclusion // HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST); if( !hLC ) return; int iItem = -1; if( g_ItemChanged.isValid ) { // // very important: tell the system that this information is no longer // valid. hence we won't recurse misteriously or unpredictably // g_ItemChanged.isValid = FALSE; iItem = g_ItemChanged.iItem; BOOL isIncluded = ListView_GetCheckState( hLC, iItem ); DWORD dwDevIndex = GetItemData( hLC, (BYTE)iItem ); hr = AppManExcludeDevice( dwDevIndex, isIncluded ); } // // Update display: list & scroll bar! // //UpdateListAndScrollBar( hDlg ); g_ChkBoxUpdate = TRUE; } #define APPMAN_DEFAULT_GAME_DISK_USAGE 0xFFFFFFFF // this code means, get default from registry void OnButtonPress( HWND hDlg ) { if( !AppManInitialized() ) return; GUID sDevGuid; // reset defaults for(int i = 0; imask = LVIF_TEXT; plvItem->pszText = lpszBuff; plvItem->cchTextMax = lstrlen(lpszBuff); plvItem->iItem = iItem; return ListView_InsertItem(hCtrl, (const LPLVITEM)plvItem); } void SetScrollBarPosition( HWND hDlg, INT pos, int iDevIndex ) { SendDlgItemMessage(hDlg, IDC_APPMAN_SCROLLBAR, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) pos); // change text SetScrollBarString( hDlg, pos, iDevIndex ); } void SetScrollBarString(HWND hDlg, INT pos, int iDevIndex) { HRESULT hr; DWORD dwMegaBytes; TCHAR szTempText[MAX_STR_LEN] = {0}; TCHAR szItemText1[MAX_STR_LEN] = {0}; TCHAR szItemText2[MAX_STR_LEN] = {0}; LoadString(ghInstance, IDS_APPMAN_GRP_PERCENT_DISK_USED, szTempText, MAX_STR_LEN); _stprintf(szItemText1, szTempText, iDevIndex + 65); hr = AppManGetAllocatedMeg( iDevIndex, pos, dwMegaBytes ); LoadString(ghInstance, IDS_APPMAN_GAME_SPACE_ON_DRIVE, szTempText, MAX_STR_LEN); _stprintf(szItemText2, szTempText, iDevIndex + 65, dwMegaBytes, pos); SendDlgItemMessage(hDlg, IDC_APPMAN_GRP_PERCENT_DISK_USED, WM_SETTEXT, 0, (LPARAM)szItemText1); SendDlgItemMessage(hDlg, IDC_APPMAN_TEXT_PERCENT_DISK_USED, WM_SETTEXT, 0, (LPARAM)szItemText2); return; } #define ISVALID(item) ( (item < MAX_DEVICES) && (item>=0) ) // Default device is the first one. DWORD g_CurrentItem = 0; DWORD GetCurrentDeviceFromList( HWND hDlg, BYTE *nItem ) { if( ! AppManInitialized() ) return -1; if( ! g_ListPopulated ) return -1; int item = -1; HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST); if( g_ItemChanged.isValid ) { // use this info 'cause it was set by the itemchanged notification item = g_ItemChanged.iItem; } else { item = ListView_GetNextItem(hLC, -1, LVNI_SELECTED); if( ! ISVALID(item) ) { item = ListView_GetNextItem(hLC, -1, LVNI_FOCUSED); } } DWORD dwDev = -1; if( ISVALID(item) ) { dwDev = GetItemData( hLC, (BYTE)item ); if( ISVALID(dwDev) ) { g_CurrentItem = item; if( nItem != NULL) { *nItem = (BYTE)item; } } else { dwDev = item = -1; } } return dwDev; } void ConfigureListControl( HWND hDlg ) { HWND hLC; LVCOLUMN lvColumn = {0}; RECT rc; hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST); ::SendMessage(hLC , LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES | LVS_EX_HEADERDRAGDROP // LVS_EX_TWOCLICKACTIVATE // LVN_ITEMACTIVATE (WM_NOTIFY) ); GetClientRect(hLC, &rc); // 4/18/2000(RichGr): Bug 32634 - Reduce the size of the columns to just below 100% so we // can avoid a horizontal scrollbar showing up under some resolutions. DWORD w = ((rc.right - rc.left) * 95) / 100; DWORD w1 = w / 3; // 33% of width w = w - w1; DWORD w2 = w / 3; // 1/3 of remaining width DWORD w3 = w - w2; // remaining width InsertColumn(hLC, APPMAN_LIST_EXCLUDE_CHECKBOX, IDS_APPMAN_EXCLUDE_CHECKBOX, (USHORT)(w1)); InsertColumn(hLC, APPMAN_LIST_DRIVE, IDS_APPMAN_DRIVE, (USHORT)(w2)); InsertColumn(hLC, APPMAN_LIST_EXCLUDED_PERCENT, IDS_APPMAN_EXCLUDED_PERCENT, (USHORT)(w3)); // 3/31/2000(RichGr): Center Yes/No text in checkbox column. lvColumn.mask = LVCF_FMT; lvColumn.fmt = LVCFMT_CENTER; ListView_SetColumn( hLC, APPMAN_LIST_EXCLUDE_CHECKBOX, &lvColumn ); #if 0 // // now move the 0'th column all the way to the right // // Allocate the structure LPLVCOLUMN plvColumn = (LPLVCOLUMN)_alloca(sizeof(LVCOLUMN)); ASSERT (plvColumn); ZeroMemory(plvColumn, sizeof(LVCOLUMN)); plvColumn->mask = LVCF_FMT | LVCF_ORDER; plvColumn->fmt = LVCFMT_CENTER; plvColumn->iOrder = 2; ListView_SetColumn( hLC, APPMAN_LIST_EXCLUDE_CHECKBOX, plvColumn ); #endif return; } // populates from appman state void PopulateListControl( HWND hDlg, BYTE nItem ) { HRESULT hr = S_OK; GUID sDeviceGuid; BOOL isExcluded = FALSE; DWORD percent = 70; UCHAR listIndex = (UCHAR)0; TCHAR szTempText[MAX_STR_LEN] = {0}; TCHAR szItemText1[MAX_STR_LEN] = {0}; TCHAR szItemText2[MAX_STR_LEN] = {0}; g_ListPopulated = FALSE; g_ChkBoxUpdate = FALSE; Assert( AppManInitialized() ); HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST); // Turn Redraw off here else it will flicker! ::SendMessage(hLC, WM_SETREDRAW, (WPARAM)FALSE, 0); // Out with the old... ::SendMessage(hLC, LVM_DELETEALLITEMS, 0, 0); // // we use do/while construct because we can only insert at the front of the list. // for(DWORD nDevIndex = 0; nDevIndex < MAX_DEVICES; nDevIndex++) { if( AppManDoesDeviceExist(nDevIndex, sDeviceGuid) ) { // // this array maps list entry indices to valid device indices. // for example, list entry index 0 contains drive D, which is index 2 // LoadString(ghInstance, IDS_APPMAN_DRIVE_TEXT, szTempText, MAX_STR_LEN); _stprintf(szItemText1, szTempText, nDevIndex + 65); // // Insert the Drive name // // Creates an item with a checkbox. int actualListIndex = MyInsertItem( hLC, _T(""), listIndex ); SetItemData( hLC, (BYTE)actualListIndex, nDevIndex ); // sets the text in the "Drive" column SetItemText(hLC, (BYTE)actualListIndex, APPMAN_LIST_DRIVE, szItemText1); // // Populate the columns with "excluded" or "percentage" // hr = AppManIsDeviceExcluded( nDevIndex, isExcluded ); if ( isExcluded ) { LoadString(ghInstance, IDS_APPMAN_EXCLUDED, szTempText, MAX_STR_LEN); _stprintf(szItemText1, szTempText); LoadString(ghInstance, IDS_APPMAN_CHECKBOX_NO, szTempText, MAX_STR_LEN); _stprintf(szItemText2, szTempText); } else { LoadString(ghInstance, IDS_APPMAN_GAME_USAGE, szTempText, MAX_STR_LEN); hr = AppManGetGameDiskUsage(nDevIndex, percent); _stprintf(szItemText1, szTempText, percent); LoadString(ghInstance, IDS_APPMAN_CHECKBOX_YES, szTempText, MAX_STR_LEN); _stprintf(szItemText2, szTempText); } // // sets the checkbox if it's excluded // ListView_SetCheckState( hLC, actualListIndex, !isExcluded ); SetItemText(hLC, (BYTE)actualListIndex, APPMAN_LIST_EXCLUDED_PERCENT, szItemText1); // 3/31/2000(RichGr): Set "Allow new games" column to "Yes" or "No". SetItemText(hLC, (BYTE)actualListIndex, APPMAN_LIST_EXCLUDE_CHECKBOX, szItemText2); listIndex++; } // if } // for // // set focus on that item // SetListCtrlItemFocus( hLC, nItem ); // // Turn the redraw flag back on! // ::SendMessage (hLC, WM_SETREDRAW, (WPARAM)TRUE, 0); g_ListPopulated = TRUE; g_ChkBoxUpdate = TRUE; return; } /* BOOL ListView_SortItems( HWND hwnd, PFNLVCOMPARE pfnCompare, LPARAM lParamSort ); BOOL ListView_SortItemsEx( HWND hwnd, PFNLVCOMPARE pfnCompare, LPARAM lParamSort ); This macro is similar to ListView_SortItems, except for the type of information passed to the comparison function. With ListView_SortItemsEx, the item's index is passed instead of its lparam value. int CALLBACK CompareFunc( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); */ void EnableAllControls( HWND hDlg, BOOL bEnable ) { // HWND hwnd; // do manage disk cb //hwnd = GetDlgItem(hDlg, IDC_APPMAN_MANAGE_DISK); //EnableWindow( hwnd, bEnable ); EnableDiskManageControls( hDlg, bEnable ); } void EnableDiskManageControls( HWND hDlg, BOOL bEnable ) { HWND hwnd; // LIST CONTROL hwnd = GetDlgItem(hDlg, IDC_APPMAN_DRIVE_LIST); EnableWindow( hwnd, bEnable ); EnableScrollBarAndText( hDlg, bEnable ); } void EnableScrollBarAndText( HWND hDlg, BOOL bEnable ) { HWND hwnd; // SCROLLBAR //PostDlgItemEnableWindow( hDlg, IDC_APPMAN_SCROLLBAR, enableManageDiskSpace ); hwnd = GetDlgItem(hDlg, IDC_APPMAN_SCROLLBAR); EnableWindow( hwnd, bEnable ); // TEXT hwnd = GetDlgItem(hDlg, IDC_APPMAN_TEXT_PERCENT_DISK_USED); EnableWindow( hwnd, bEnable ); } /////////////////////////////////////////////////////////////////// // AppMan functions /////////////////////////////////////////////////////////////////// #define RELEASE(p) { if((p)) { (p)->Release(); p = NULL; } } IApplicationManagerAdmin *g_IAppManAdmin = NULL; BOOL AppManInitialized() { return (g_IAppManAdmin != NULL); } HRESULT AppManInit() { HRESULT hr = S_OK; // Important if( AppManInitialized() ) return hr; if (FAILED(CoInitialize(NULL))) { return E_FAIL; } hr = CoCreateInstance(CLSID_ApplicationManager, NULL, CLSCTX_INPROC_SERVER, IID_ApplicationManagerAdmin, (LPVOID *) &g_IAppManAdmin); if( FAILED(hr) ) return hr; return hr; } BOOL AppManDoesDeviceExist(DWORD devIndex, GUID &sDevGuid) { return (SUCCEEDED(g_IAppManAdmin->EnumerateDevices(devIndex, &sDevGuid))) ? TRUE : FALSE; } DWORD g_dwExclusionMask = APP_CATEGORY_ENTERTAINMENT; HRESULT AppManShutdown() { RELEASE( g_IAppManAdmin ); return S_OK; } HRESULT AppManSetGameDiskUsage(DWORD devIndex, DWORD percent) { HRESULT hr = S_OK; GUID sDeviceGuid; if( g_IAppManAdmin ) { if (SUCCEEDED(g_IAppManAdmin->EnumerateDevices(devIndex, &sDeviceGuid))) { hr = g_IAppManAdmin->SetDeviceProperty(DEVICE_PROPERTY_PERCENTCACHESIZE, &sDeviceGuid, &percent, sizeof(percent)); } } return hr; } HRESULT AppManGetAdvMode(BOOL &bAdvMode) { HRESULT hr = S_OK; if( g_IAppManAdmin ) hr = g_IAppManAdmin->GetAppManProperty(APPMAN_PROPERTY_ADVANCEDMODE, &bAdvMode, sizeof(DWORD)); return hr; } HRESULT AppManSetAdvMode(BOOL bAdvMode) { HRESULT hr = S_OK; if( g_IAppManAdmin ) hr = g_IAppManAdmin->SetAppManProperty(APPMAN_PROPERTY_ADVANCEDMODE, &bAdvMode, sizeof(DWORD)); return hr; } HRESULT AppManGetGameDiskUsage(DWORD devIndex, DWORD &percent) { HRESULT hr = S_OK; GUID sDeviceGuid; if( g_IAppManAdmin ) { if (SUCCEEDED(g_IAppManAdmin->EnumerateDevices(devIndex, &sDeviceGuid))) { hr = g_IAppManAdmin->GetDeviceProperty(DEVICE_PROPERTY_PERCENTCACHESIZE, &sDeviceGuid, &percent, sizeof(percent)); } } return hr; } HRESULT AppManExcludeDevice(DWORD devIndex, BOOL bDoInclude) { HRESULT hr = S_OK; GUID sDeviceGuid; if( g_IAppManAdmin ) { if (SUCCEEDED(g_IAppManAdmin->EnumerateDevices(devIndex, &sDeviceGuid))) { DWORD dwMask = g_dwExclusionMask; // Get the prior mask. hr = g_IAppManAdmin->GetDeviceProperty(DEVICE_PROPERTY_EXCLUSIONMASK, &sDeviceGuid, &dwMask, sizeof(g_dwExclusionMask)); if (SUCCEEDED(hr)) { if( !bDoInclude ) { // Exclude the drive, set the APP_CATEGORY_ENTERTAINMENT bit dwMask |= APP_CATEGORY_ENTERTAINMENT; } else { // Include the drive, clear the APP_CATEGORY_ENTERTAINMENT bit dwMask &= ~APP_CATEGORY_ENTERTAINMENT; } hr = g_IAppManAdmin->SetDeviceProperty(DEVICE_PROPERTY_EXCLUSIONMASK, &sDeviceGuid, &dwMask, sizeof(g_dwExclusionMask)); } } } return hr; } HRESULT AppManIsDeviceExcluded(DWORD devIndex, BOOL &isExcluded) { HRESULT hr = S_OK; GUID sDeviceGuid; DWORD dwExcMask; if( g_IAppManAdmin ) { if (SUCCEEDED(g_IAppManAdmin->EnumerateDevices(devIndex, &sDeviceGuid))) { hr = g_IAppManAdmin->GetDeviceProperty(DEVICE_PROPERTY_EXCLUSIONMASK, &sDeviceGuid, &dwExcMask, sizeof(dwExcMask)); if( SUCCEEDED(hr) ) { // // XXX: make sure JUST the flags i'm interested in are on // if( dwExcMask & APP_CATEGORY_ENTERTAINMENT) // somthing is on { isExcluded = TRUE; } else { isExcluded = FALSE; } } } } return hr; } HRESULT AppManGetAllocatedMeg(DWORD devIndex, DWORD percent, DWORD &dwMegaBytes) { HRESULT hr = S_OK; GUID sDeviceGuid; if( g_IAppManAdmin ) { if (SUCCEEDED(g_IAppManAdmin->EnumerateDevices(devIndex, &sDeviceGuid))) { hr = g_IAppManAdmin->GetDeviceProperty(DEVICE_PROPERTY_TOTALKILOBYTES, &sDeviceGuid, &dwMegaBytes, sizeof(dwMegaBytes)); if(SUCCEEDED(hr)) { dwMegaBytes = DWORD( float(dwMegaBytes) * (float(percent) / 100.0f) ); dwMegaBytes = dwMegaBytes >> 10; // turn kilobytes into megabytes } else { dwMegaBytes = -1; } } } return hr; } //////////////////////////////////////////////////////////////////////////////////////// // FUNCTION: OnAdvHelp ( LPARAM lParam ) // // PARAMETERS: lParam - Pointer to HELPINFO struct // // PURPOSE: WM_HELP message handler //////////////////////////////////////////////////////////////////////////////////////// void OnAdvHelp(LPARAM lParam) { ASSERT (lParam); // point to help file LPTSTR pszHelpFileName = new TCHAR[STR_LEN_32]; ASSERT (pszHelpFileName); if( LoadString(ghInstance, IDS_HELPFILENAME, pszHelpFileName, STR_LEN_32) ) { if( ((LPHELPINFO)lParam)->iContextType == HELPINFO_WINDOW ) WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, pszHelpFileName, HELP_WM_HELP, (ULONG_PTR)gaHelpIDs); } #ifdef _DEBUG else OutputDebugString(TEXT("JOY.CPL: AppMan.cpp: OnAdvHelp: LoadString Failed to find IDS_HELPFILENAME!\n")); #endif // _DEBUG if( pszHelpFileName ) delete[] (pszHelpFileName); } //////////////////////////////////////////////////////////////////////////////////////// // FUNCTION: OnContextMenu ( WPARAM wParam ) // // PARAMETERS: wParam - HWND of window under the pointer // // PURPOSE: Handle WM_RBUTTONDOWN over all client windows // (except the list control... that's OnListviewContextMenu() job) //////////////////////////////////////////////////////////////////////////////////////// void OnContextMenu(WPARAM wParam, LPARAM lParam) { // HWND hListCtrl = NULL ASSERT (wParam); #if 0 hListCtrl = GetDlgItem((HWND) wParam, IDC_APPMAN_DRIVE_LIST); // If you are on the ListCtrl... if( (HWND)wParam == hListCtrl ) { SetFocus(hListCtrl); // Don't attempt if nothing selected if( iItem != NO_ITEM ) OnListviewContextMenu(hListCtrl,lParam); } else #endif { // point to help file LPTSTR pszHelpFileName = new TCHAR[STR_LEN_32]; ASSERT (pszHelpFileName); if( LoadString(ghInstance, IDS_HELPFILENAME, pszHelpFileName, STR_LEN_32) ) WinHelp((HWND)wParam, pszHelpFileName, HELP_CONTEXTMENU, (ULONG_PTR)gaHelpIDs); #ifdef _DEBUG else OutputDebugString(TEXT("JOY.CPL: appman.cpp: OnContextMenu: LoadString Failed to find IDS_HELPFILENAME!\n")); #endif // _DEBUG if( pszHelpFileName ) delete[] (pszHelpFileName); } } /////////////////////////////////////////////////////////////////////////////// // FUNCTION: OnListviewContextMenu( void ) // // PURPOSE: Handle Context menu in Listview // // RETURN: TRUE if successfull, FALSE otherwise /////////////////////////////////////////////////////////////////////////////// static void OnListviewContextMenu( HWND hWnd, LPARAM lParam ) { HMENU hPopupMenu = CreatePopupMenu(); HWND hListCtrl = NULL; hListCtrl = GetDlgItem(hWnd, IDC_APPMAN_DRIVE_LIST); ASSERT (hPopupMenu); // unlike life, bRet defaults to bliss BOOL bRet = TRUE; LPTSTR pszText = new TCHAR[STR_LEN_32]; ASSERT (pszText); // Don't display Rename/Change if on (none) entry if( !(GetItemData(hListCtrl, (BYTE)iItem) & ID_NONE) ) { if( TRUE ) // Borrowed code... { // add the "Change..." string ::SendDlgItemMessage(GetParent(hListCtrl), IDC_ADV_CHANGE, WM_GETTEXT, (WPARAM)STR_LEN_32, (LPARAM)(LPCTSTR)pszText); bRet = AppendMenu(hPopupMenu, MF_ENABLED, IDC_ADV_CHANGE, pszText); #ifdef _DEBUG if( !bRet ) TRACE(TEXT("JOY.CPL: OnListviewCOntextMenu: AppendMenu Failed to insert %s\n"), pszText); #endif //_DEBUG // Add the Rename text VERIFY(LoadString(ghInstance, IDS_RENAME, pszText, STR_LEN_32)); bRet = AppendMenu(hPopupMenu, MF_ENABLED, IDC_RENAME, pszText); #ifdef _DEBUG if( !bRet ) TRACE(TEXT("JOY.CPL: OnListviewCOntextMenu: AppendMenu Failed to insert %s\n"), pszText); #endif //_DEBUG // Add the SEPERATOR and "What's this?" bRet = AppendMenu(hPopupMenu, MF_SEPARATOR, 0, 0); #ifdef _DEBUG if( !bRet ) TRACE(TEXT("JOY.CPL: OnListviewCOntextMenu: AppendMenu Failed to insert SEPERATOR!\n")); #endif //_DEBUG } } VERIFY(LoadString(ghInstance, IDS_WHATSTHIS, pszText, STR_LEN_32)); bRet = AppendMenu(hPopupMenu, MF_ENABLED, IDS_WHATSTHIS, pszText); #ifdef _DEBUG if( !bRet ) TRACE(TEXT("JOY.CPL: OnListviewCOntextMenu: AppendMenu Failed to insert %s\n"), pszText); #endif //_DEBUG if( pszText ) delete[] (pszText); POINT pt; // lParam is -1 if we got here via Shift+F10 if( lParam > 0 ) { pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); } else { // Center the popup on the selected item! // This get's a good X pos, but the y is the start of the control! ::SendMessage(hListCtrl, LVM_GETITEMPOSITION, iItem, (LPARAM)&pt); RECT rc; ::GetClientRect(hListCtrl, &rc); pt.x = rc.right>>1; ClientToScreen(hListCtrl, &pt); } bRet = TrackPopupMenu (hPopupMenu, TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON, pt.x, pt.y, 0, ghDlg, NULL); #ifdef _DEBUG if( !bRet ) TRACE (TEXT("JOY.CPL: OnListviewContextMenu: TrackPopupMenu Failed!\n")); #endif //_DEBUG DestroyMenu (hPopupMenu); }