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.

893 lines
25 KiB

  1. /*
  2. File: AppLock.cpp
  3. Project:
  4. Author: ScottLe
  5. Date: 1/31/00
  6. Comments:
  7. AppMan application locking (pinning) Tab in Game Control Panel.
  8. Copyright (c) 1999, 2000 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. static HWND hAppManCheckBox;
  51. extern const DWORD gaHelpIDs[];
  52. extern HINSTANCE ghInstance;
  53. //
  54. // GLOBALS
  55. //
  56. static BOOL g_ListPopulated = FALSE;
  57. static int g_nm_click = -1;
  58. static BOOL g_nm_click_state = FALSE;
  59. static BOOL g_DlgInitialized = FALSE;
  60. static BOOL g_ChkBoxUpdate = FALSE;
  61. static GUID *g_lpsGUID = NULL;
  62. extern IApplicationManagerAdmin *g_IAppManAdmin;
  63. static struct {
  64. BOOL isValid;
  65. int iItem;
  66. BOOL isClicked;
  67. } g_ItemChanged;
  68. // constants
  69. const short NO_ITEM = -1;
  70. static short iItem = NO_ITEM; // index of selected item
  71. // Forwards
  72. //
  73. // local forwards
  74. //
  75. static BOOL OnInitDialog(HWND hDlg, HWND hWnd, LPARAM lParam);
  76. static void OnCommand(HWND hDlg, int id, HWND hWndCtl, UINT code);
  77. static BOOL OnNotify(HWND hDlg, WPARAM idFrom, LPARAM lParam);
  78. static void OnScroll(HWND hDlg, WPARAM wParam);
  79. static void OnListCtrl_Select(HWND hDlg);
  80. static void OnListCtrl_DblClick(HWND hDlg);
  81. static void OnListCtrl_UpdateFromCheckBoxes( HWND hDlg );
  82. static void OnAdvHelp (LPARAM);
  83. //static void OnContextMenu (WPARAM wParam, LPARAM lParam);
  84. static void OnListviewContextMenu (HWND hWnd, LPARAM lParam );
  85. // util fcns
  86. static int MyInsertItem( HWND hCtrl, LPTSTR lpszBuff, int iItem ); // replaced from cpanel.cpp
  87. static void PostDlgItemEnableWindow( HWND hDlg, USHORT nItem, BOOL bEnabled );
  88. static void EnableDiskManageControls( HWND hDlg, BOOL bEnable );
  89. static void EnableScrollBarAndText( HWND hDlg, BOOL bEnable );
  90. //static void EnableAllControls( HWND hDlg, BOOL bEnable );
  91. DWORD GetCurrentDeviceFromList( HWND hDlg, BYTE *nItem = NULL );
  92. static void ConfigureListControl( HWND hDlg );
  93. static void PopulateListControl( HWND hDlg, BYTE nItem );
  94. void UpdateCurrentDeviceFromScrollBar( HWND hDlg, DWORD newPos );
  95. //void UpdateListAndScrollBar( HWND hDlg, BOOL bJustScrollBar = FALSE );
  96. // From AppMan.cpp
  97. extern HRESULT AppManShutdown();
  98. extern HRESULT AppManInit();
  99. extern BOOL AppManInitialized();
  100. //
  101. // from cpanel.cpp
  102. //
  103. extern void SetItemText( HWND hCtrl, BYTE nItem, BYTE nSubItem, LPTSTR lpStr);
  104. extern void InsertColumn(HWND hCtrl, BYTE nColumn, USHORT nStrID, USHORT nWidth);
  105. extern BOOL SetItemData( HWND hCtrl, BYTE nItem, DWORD dwFlag );
  106. extern DWORD GetItemData(HWND hCtrl, BYTE nItem );
  107. extern void SetListCtrlItemFocus ( HWND hCtrl, BYTE nItem );
  108. ///////////////////////////////////////////////////////////////////////////////
  109. // FUNCTION: AppManLockProc(HWND hDlg, ULONG uMsg, WPARAM wParam, LPARAM lParam)
  110. //
  111. // PARAMETERS: hDlg -
  112. // uMsg -
  113. // wParam -
  114. // lParam -
  115. //
  116. // PURPOSE: Main callback function for "Appman" sheet
  117. ///////////////////////////////////////////////////////////////////////////////
  118. BOOL WINAPI AppManLockProc(HWND hDlg, ULONG uMsg, WPARAM wParam, LPARAM lParam)
  119. {
  120. switch( uMsg )
  121. {
  122. case WM_ACTIVATEAPP:
  123. if( wParam ) {
  124. HWND hListCtrl = NULL;
  125. hListCtrl = GetDlgItem((HWND) wParam, IDC_APPMAN_DRIVE_LIST);
  126. SetListCtrlItemFocus(hListCtrl, (BYTE)iItem);
  127. }
  128. break;
  129. case WM_DEVICECHANGE:
  130. switch( (UINT)wParam )
  131. {
  132. case DBT_DEVICEARRIVAL:
  133. // case DBT_DEVICEREMOVECOMPLETE:
  134. break;
  135. }
  136. break;
  137. case WM_LBUTTONDOWN:
  138. // Click Drag service for PropSheets!
  139. //PostMessage(GetParent(hDlg), WM_NCLBUTTONDOWN, (WPARAM)HTCAPTION, lParam);
  140. break;
  141. case WM_INITDIALOG:
  142. if( !HANDLE_WM_INITDIALOG(hDlg, wParam, lParam, OnInitDialog) )
  143. {
  144. // Fix #108983 NT, Remove Flash on Error condition.
  145. SetWindowPos(::GetParent(hDlg), HWND_BOTTOM, 0, 0, 0, 0, SWP_HIDEWINDOW);
  146. DestroyWindow(hDlg);
  147. }
  148. return(TRUE);
  149. case WM_COMMAND:
  150. HANDLE_WM_COMMAND(hDlg, wParam, lParam, OnCommand);
  151. return(TRUE);
  152. case WM_DESTROY:
  153. //return(HANDLE_WM_DESTROY(hDlg, wParam, lParam, OnDestroy));
  154. //jchauvin 04/10/2000 Fix Build break in Win64
  155. free( g_lpsGUID );
  156. g_lpsGUID = NULL;
  157. return(TRUE);
  158. case WM_NOTIFY:
  159. return OnNotify(hDlg, wParam, lParam);
  160. case WM_HELP:
  161. // OnAdvHelp(lParam);
  162. return(TRUE);
  163. case WM_CONTEXTMENU:
  164. // OnContextMenu(wParam, lParam);
  165. return(TRUE);
  166. default:
  167. break;
  168. }
  169. return(0);
  170. }
  171. ///////////////////////////////////////////////////////////////////////////////
  172. // FUNCTION: OnInitDialog(HWND hDlg, HWND hWnd, LPARAM lParam)
  173. //
  174. // PARAMETERS: hDlg -
  175. // hWnd -
  176. // lParam -
  177. //
  178. // PURPOSE: WM_INITDIALOG message handler
  179. ///////////////////////////////////////////////////////////////////////////////
  180. BOOL OnInitDialog(HWND hDlg, HWND hWnd, LPARAM lParam)
  181. {
  182. HRESULT hr = S_OK;
  183. hr = AppManInit();
  184. //
  185. // init globals
  186. //
  187. ZeroMemory( &g_ItemChanged, sizeof(g_ItemChanged));
  188. g_DlgInitialized = FALSE;
  189. if( FAILED(hr) ) {
  190. //
  191. // Disable everything
  192. //
  193. // EnableAllControls(hDlg, FALSE);
  194. //
  195. // popup saying: hey you need appman installed ?
  196. //
  197. } else {
  198. ghDlg = hDlg;
  199. //
  200. // Set defaults
  201. //
  202. //
  203. // Configure the List control, and then fill it in
  204. //
  205. ConfigureListControl( hDlg );
  206. PopulateListControl( hDlg, 0 );
  207. g_DlgInitialized = TRUE;
  208. }
  209. return(TRUE);
  210. }
  211. ///////////////////////////////////////////////////////////////////////////////
  212. // FUNCTION: OnCommand(HWND hDlg, int id, HWND hWndCtl, UINT code)
  213. //
  214. // PARAMETERS: hDlg -
  215. // id -
  216. // hWndCtl -
  217. // code -
  218. //
  219. // PURPOSE: WM_COMMAND message handler
  220. ///////////////////////////////////////////////////////////////////////////////
  221. void OnCommand(HWND hDlg, int id, HWND hWndCtl, UINT code)
  222. {
  223. HRESULT hr = S_OK;
  224. #if 0
  225. switch( id )
  226. {
  227. case IDS_WHATSTHIS:
  228. {
  229. // point to help file
  230. LPTSTR pszHelpFileName = new TCHAR[STR_LEN_32];
  231. ASSERT (pszHelpFileName);
  232. if( LoadString(ghInstance, IDS_HELPFILENAME, pszHelpFileName, STR_LEN_32) )
  233. WinHelp((HWND)hDlg, pszHelpFileName, HELP_WM_HELP, (ULONG_PTR)gaHelpIDs);
  234. #ifdef _DEBUG
  235. else OutputDebugString(TEXT("JOY.CPL: AppMan.cpp: OnCommand: LoadString Failed to find IDS_HELPFILENAME!\n"));
  236. #endif // _DEBUG
  237. if( pszHelpFileName )
  238. delete[] (pszHelpFileName);
  239. }
  240. break;
  241. /*
  242. case IDC_APPMAN_MANAGE_DISK:
  243. {
  244. BOOL isChecked = (IsDlgButtonChecked(hDlg, id)) ? TRUE : FALSE;
  245. EnableDiskManageControls( hDlg, !isChecked );
  246. }
  247. break;
  248. */
  249. default:
  250. break;
  251. }
  252. #endif
  253. }
  254. ////////////////////////////////////////////////////////////////////////////////
  255. //
  256. // FUNCTION: OnNotify(HWND hDlg, WPARAM idFrom, NMHDR* pnmhdr)
  257. //
  258. // PARAMETERS: hDlg -
  259. // idFrom - ID of control sending WM_NOTIFY message
  260. // pnmhdr -
  261. //
  262. // PURPOSE: WM_NOTIFY message handler
  263. ////////////////////////////////////////////////////////////////////////////////
  264. static DWORD ct=0L;
  265. BOOL OnNotify(HWND hDlg, WPARAM idFrom, LPARAM lParam)
  266. {
  267. NMLISTVIEW *pnmv = NULL;
  268. LPNMHDR pnmhdr = (LPNMHDR)lParam;
  269. switch (pnmhdr->code)
  270. {
  271. // 4/13/2000(RichGr): Repopulate the List Control if we reacquire the focus.
  272. // This keeps the data in sync with installs and uninstalls.
  273. case NM_SETFOCUS:
  274. {
  275. PopulateListControl(hDlg, 0);
  276. break;
  277. }
  278. case LVN_ITEMCHANGED:
  279. pnmv = (LPNMLISTVIEW) lParam;
  280. if( idFrom == IDC_APPMAN_PIN_LIST )
  281. {
  282. // this is called if a new item has been selected
  283. // or if the user clicked on the checkbox, changing state
  284. #ifdef _DEBUG
  285. {
  286. TCHAR tstring[256];
  287. NMITEMACTIVATE *pitemact = (LPNMITEMACTIVATE)lParam;
  288. _stprintf(tstring, TEXT("JOY.CPL: AppLock.cpp: OnNotify: LVN_ITEMCHANGED, ct=%ld,idFrom=%lx, item=%lx uChanged=%lx uNewState=%lx uOldState=%lx lParam=%lx\n"),
  289. ++ct,idFrom,pitemact->iItem,pitemact->uChanged,pitemact->uNewState,pitemact->uOldState,pitemact->lParam);
  290. OutputDebugString(tstring);
  291. }
  292. #endif // _DEBUG
  293. if ( AppManInitialized() &&
  294. g_DlgInitialized &&
  295. (pnmv->uNewState & LVIS_SELECTED ||
  296. pnmv->uNewState == 0x1000 || pnmv->uNewState == 0x2000) &&
  297. // TODO: Find definitions for x1000 and x2000 (check box state change in a list view control)
  298. g_ChkBoxUpdate )
  299. {
  300. NMITEMACTIVATE *ll = (LPNMITEMACTIVATE)lParam;
  301. HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_PIN_LIST);
  302. g_ItemChanged.isValid = TRUE;
  303. g_ItemChanged.iItem = ll->iItem;
  304. g_ItemChanged.isClicked = FALSE;
  305. //
  306. // this flag is VERY important for consistent state changes
  307. // and eliminating race conditions
  308. //
  309. g_ChkBoxUpdate = FALSE;
  310. OnListCtrl_UpdateFromCheckBoxes( hDlg );
  311. g_ChkBoxUpdate = TRUE;
  312. g_ItemChanged.isValid = FALSE;
  313. g_ItemChanged.iItem = ll->iItem;
  314. OnListCtrl_Select( hDlg );
  315. }
  316. return TRUE;
  317. break;
  318. } // if
  319. } // switch
  320. return(0);
  321. }
  322. void OnListCtrl_UpdateFromCheckBoxes( HWND hDlg )
  323. {
  324. #if 1
  325. HRESULT hResult;
  326. BOOL bIsAppManPinned = FALSE;
  327. BOOL bDoToggle = FALSE;
  328. BYTE nItem = 0;
  329. GUID *pGuid = NULL;
  330. IApplicationManager * lpApplicationManager;
  331. IApplicationEntry * lpApplicationEntry;
  332. DWORD dwIndex;
  333. //
  334. // go through each item, check the box & set pinning
  335. //
  336. HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_PIN_LIST);
  337. if( !hLC ) return;
  338. int iItem = -1;
  339. //while( (iItem = ListView_GetNextItem( hLC, iItem, LVNI_ALL )) >= 0 )
  340. if( g_ItemChanged.isValid )
  341. {
  342. //
  343. // very important: tell the system that this information is no longer
  344. // valid. Hence we won't recurse mysteriously or unpredictably.
  345. //
  346. g_ItemChanged.isValid = FALSE;
  347. iItem = g_ItemChanged.iItem;
  348. BOOL bIsCheckBoxPinned = !(ListView_GetCheckState( hLC, iItem )); // Check box has the new state NOW
  349. // Set the pin state using the GUID to identify the app
  350. //JWC 4/10/2000 Added to fix Win64 Build problem
  351. dwIndex = (DWORD) GetItemData(hLC, (BYTE)iItem );
  352. pGuid = (GUID *) ((ULONG_PTR)g_lpsGUID + (ULONG_PTR)dwIndex*sizeof(GUID));
  353. // Find out what the pin state is in AppMan
  354. // Get an Application Manager interface
  355. hResult = CoCreateInstance(CLSID_ApplicationManager, NULL, CLSCTX_INPROC_SERVER, IID_ApplicationManager, (LPVOID *) &lpApplicationManager);
  356. if (SUCCEEDED(hResult))
  357. {
  358. // Get an application entry object.
  359. hResult = lpApplicationManager->CreateApplicationEntry(&lpApplicationEntry);
  360. if (SUCCEEDED(hResult))
  361. {
  362. // Set the app's GUID
  363. hResult = lpApplicationEntry->SetProperty(APP_PROPERTY_GUID, pGuid, sizeof(GUID));
  364. if (SUCCEEDED(hResult))
  365. {
  366. // Populate the app info structure
  367. hResult = lpApplicationManager->GetApplicationInfo(lpApplicationEntry);
  368. if (SUCCEEDED(hResult))
  369. {
  370. // Get the current PIN state of the app
  371. hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_PIN, &bIsAppManPinned, sizeof(bIsAppManPinned));
  372. if (SUCCEEDED(hResult))
  373. {
  374. // bIsAppManPinned is the state appman has for the application.
  375. // bIsCheckBoxPinned is the check box state (checked = true = not pinned)
  376. // Since AppMan's pinning state for an app is a toggle we could get out of sync
  377. // due to redraw or timing issues with the list view control -- so,
  378. // we need to make sure that the check box's state is insync with AppMan.
  379. // When in doubt, force it to the displayed state of the check box.
  380. // Truth table:
  381. //
  382. // AppManPinned CheckBoxPinned (T=not checked) DoToggle Reason
  383. // T T No Same State Already (sync error!)
  384. // F F No Same State Already (sync error!)
  385. // T F Yes New State Selected
  386. // F T Yes New State Selected
  387. //
  388. if (bIsAppManPinned != bIsCheckBoxPinned)
  389. bDoToggle = TRUE;
  390. else
  391. {
  392. // ERR: BUG BUG: The control panel and appman are out of sync, this is an error.
  393. bDoToggle = FALSE;
  394. #ifdef _DEBUG
  395. OutputDebugString(TEXT("JOY.CPL: AppLock.cpp: Pinning Update, AppMan and Check box states are out of sync!\n"));
  396. #endif // _DEBUG
  397. }
  398. if (bDoToggle && pGuid && g_IAppManAdmin) // Toggle the pin state
  399. hResult = g_IAppManAdmin->DoApplicationAction(ACTION_APP_PIN, pGuid, 0, (LPVOID) NULL, sizeof(DWORD));
  400. // ERR: Handle error conditions
  401. }
  402. }
  403. }
  404. lpApplicationEntry->Release();
  405. }
  406. lpApplicationManager->Release();
  407. }
  408. }
  409. g_ChkBoxUpdate = TRUE;
  410. #endif
  411. }
  412. void OnListCtrl_Select(HWND hDlg)
  413. {
  414. //
  415. // set focus on that item
  416. //
  417. HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_PIN_LIST);
  418. SetListCtrlItemFocus( hLC, (BYTE)g_ItemChanged.iItem );
  419. }
  420. int MyInsertItem( HWND hCtrl, LPTSTR lpszBuff, int iItem )
  421. {
  422. LPLVITEM plvItem = (LPLVITEM)_alloca(sizeof(LVITEM));
  423. ASSERT (plvItem);
  424. ZeroMemory( plvItem, sizeof( LVITEM ) );
  425. plvItem->mask = LVIF_TEXT;
  426. plvItem->pszText = lpszBuff;
  427. plvItem->cchTextMax = lstrlen(lpszBuff);
  428. plvItem->iItem = iItem;
  429. return ListView_InsertItem(hCtrl, (const LPLVITEM)plvItem);
  430. }
  431. #define APPMAN_ADV_PIN_CHECKBOX 0
  432. #define APPMAN_ADV_PIN_TITLENAME 1
  433. #define IDS_APPMANPIN_CHECKBOX 40043
  434. #define IDS_APPMANPIN_TITLENAME 40044
  435. void ConfigureListControl( HWND hDlg )
  436. {
  437. #if 1
  438. HWND hLC;
  439. hLC = GetDlgItem(hDlg, IDC_APPMAN_PIN_LIST);
  440. ::SendMessage( hLC , LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
  441. LVS_EX_FULLROWSELECT
  442. | LVS_EX_CHECKBOXES
  443. | LVS_EX_HEADERDRAGDROP
  444. // LVS_EX_TWOCLICKACTIVATE // LVN_ITEMACTIVATE (WM_NOTIFY)
  445. );
  446. RECT rc;
  447. GetClientRect(hLC, &rc);
  448. DWORD w = rc.right-rc.left;
  449. DWORD w1 = w / 3; // 1/3 of width
  450. DWORD w2 = w - w1; // 2/3 of the width
  451. InsertColumn(hLC, APPMAN_ADV_PIN_CHECKBOX, IDS_APPMANPIN_CHECKBOX, (USHORT)(w1));
  452. InsertColumn(hLC, APPMAN_ADV_PIN_TITLENAME,IDS_APPMANPIN_TITLENAME, (USHORT)(w2));
  453. #endif
  454. }
  455. //STDMETHODIMP CApplicationManagerAdmin::DoApplicationAction(const DWORD dwAction, const GUID * lpGuid, LPVOID lpData, const DWORD dwDataLen)
  456. //STDMETHODIMP CApplicationManagerAdmin::EnumApplications(const DWORD dwApplicationIndex, IApplicationEntry * lpObject)
  457. // populates from appman state
  458. void PopulateListControl( HWND hDlg, BYTE nItem )
  459. {
  460. #if 1
  461. HRESULT hr = S_OK;
  462. BOOL isExcluded = FALSE;
  463. UCHAR listIndex = (UCHAR)0;
  464. IApplicationManager *lpApplicationManager;
  465. IApplicationEntry *lpApplicationEntry;
  466. HRESULT hResult;
  467. DWORD dwIndex = 0L;
  468. TCHAR szString[MAX_PATH];
  469. GUID sGuid;
  470. g_ListPopulated = FALSE;
  471. g_ChkBoxUpdate = FALSE;
  472. Assert( AppManInitialized() );
  473. HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_PIN_LIST);
  474. // Turn Redraw off here else it will flicker!
  475. ::SendMessage(hLC, WM_SETREDRAW, (WPARAM)FALSE, 0);
  476. // Out with the old...
  477. ::SendMessage(hLC, LVM_DELETEALLITEMS, 0, 0);
  478. //JWC 04/10/2000 Fixing build break in Win64 code
  479. g_lpsGUID = (GUID *)malloc(sizeof(GUID));
  480. if (g_lpsGUID == NULL)
  481. {
  482. //Cannot allocate memory
  483. hResult = E_UNEXPECTED;
  484. }
  485. // Get an Application Manager interface
  486. hResult = CoCreateInstance(CLSID_ApplicationManager, NULL, CLSCTX_INPROC_SERVER, IID_ApplicationManager, (LPVOID *) &lpApplicationManager);
  487. if (SUCCEEDED(hResult) && g_IAppManAdmin)
  488. {
  489. // Get an application entry object. This will be populated during the Enumeration loop
  490. hResult = lpApplicationManager->CreateApplicationEntry(&lpApplicationEntry);
  491. if (SUCCEEDED(hResult))
  492. {
  493. // Enumerate all the applications AppMan knows about
  494. dwIndex = 0;
  495. while (SUCCEEDED(g_IAppManAdmin->EnumApplications(dwIndex, lpApplicationEntry)))
  496. {
  497. // For each app, get information about it (Pinning state, title, GUID etc) and put in the list
  498. DWORD dwState = 0L;
  499. // App must be in a good state
  500. hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_STATE, &dwState, sizeof(dwState));
  501. dwState &= APP_STATE_MASK;
  502. if (!SUCCEEDED(hResult) ||
  503. dwState == APP_STATE_INSTALLING ||
  504. dwState == APP_STATE_UNSTABLE)
  505. {
  506. dwIndex++;
  507. continue; // Skip bad apps
  508. }
  509. else // Good app...
  510. {
  511. // Create the check box
  512. int actualListIndex = MyInsertItem( hLC, _T(""), dwIndex );
  513. // Get the app's GUID
  514. hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_GUID, &sGuid, sizeof(sGuid));
  515. if (SUCCEEDED(hResult))
  516. {
  517. // Allocate a GUID
  518. // ISSUE-2001/03/29-timgill Need error handling
  519. //JWC 04/10/2000 Fixing problem with GUID for Win64
  520. g_lpsGUID = (GUID *)realloc((void*)g_lpsGUID,(dwIndex+1)* sizeof(GUID));
  521. *(GUID *)((ULONG_PTR)g_lpsGUID+((ULONG_PTR)(dwIndex)*sizeof(GUID)))= sGuid;
  522. SetItemData(hLC, (BYTE)actualListIndex, dwIndex );
  523. }
  524. // Get Pin state
  525. {
  526. DWORD bPinned = FALSE;
  527. hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_PIN, &bPinned, sizeof(bPinned));
  528. if (SUCCEEDED(hResult))
  529. ListView_SetCheckState( hLC, actualListIndex, (BOOL)!bPinned ); // Checked=not pinned
  530. }
  531. // TODO: Company name and/or signature...?
  532. // hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_COMPANYNAME | APP_PROPERTY_STR_ANSI, &szString, sizeof(szString));
  533. #ifdef _UNICODE
  534. hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_SIGNATURE | APP_PROPERTY_STR_UNICODE, &szString, sizeof(szString));
  535. #else
  536. hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_SIGNATURE | APP_PROPERTY_STR_ANSI, &szString, sizeof(szString));
  537. #endif
  538. // Set the title name in the "title column"
  539. if (SUCCEEDED(hResult))
  540. SetItemText(hLC, (BYTE)actualListIndex, APPMAN_ADV_PIN_TITLENAME, szString);
  541. }
  542. dwIndex++;
  543. }
  544. }
  545. lpApplicationEntry->Release();
  546. }
  547. lpApplicationManager->Release();
  548. //
  549. // set focus on that item
  550. //
  551. SetListCtrlItemFocus( hLC, nItem );
  552. //
  553. // Turn the redraw flag back on!
  554. //
  555. ::SendMessage (hLC, WM_SETREDRAW, (WPARAM)TRUE, 0);
  556. g_ListPopulated = TRUE;
  557. g_ChkBoxUpdate = TRUE;
  558. #endif
  559. }
  560. void EnableScrollBarAndText( HWND hDlg, BOOL bEnable )
  561. {
  562. #if 0
  563. HWND hwnd;
  564. // SCROLLBAR
  565. //PostDlgItemEnableWindow( hDlg, IDC_APPMAN_SCROLLBAR, enableManageDiskSpace );
  566. hwnd = GetDlgItem(hDlg, IDC_APPMAN_SCROLLBAR);
  567. EnableWindow( hwnd, bEnable );
  568. // TEXT
  569. hwnd = GetDlgItem(hDlg, IDC_APPMAN_TEXT_PERCENT_DISK_USED);
  570. EnableWindow( hwnd, bEnable );
  571. #endif
  572. }
  573. ///////////////////////////////////////////////////////////////////
  574. // AppMan functions
  575. ///////////////////////////////////////////////////////////////////
  576. #define RELEASE(p) { if((p)) { (p)->Release(); p = NULL; } }
  577. #if 0
  578. ////////////////////////////////////////////////////////////////////////////////////////
  579. // FUNCTION: OnAdvHelp ( LPARAM lParam )
  580. //
  581. // PARAMETERS: lParam - Pointer to HELPINFO struct
  582. //
  583. // PURPOSE: WM_HELP message handler
  584. ////////////////////////////////////////////////////////////////////////////////////////
  585. void OnAdvHelp(LPARAM lParam)
  586. {
  587. ASSERT (lParam);
  588. // point to help file
  589. LPTSTR pszHelpFileName = new TCHAR[STR_LEN_32];
  590. ASSERT (pszHelpFileName);
  591. if( LoadString(ghInstance, IDS_HELPFILENAME, pszHelpFileName, STR_LEN_32) )
  592. {
  593. if( ((LPHELPINFO)lParam)->iContextType == HELPINFO_WINDOW )
  594. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, pszHelpFileName, HELP_WM_HELP, (ULONG_PTR)gaHelpIDs);
  595. }
  596. #ifdef _DEBUG
  597. else OutputDebugString(TEXT("JOY.CPL: AppMan.cpp: OnAdvHelp: LoadString Failed to find IDS_HELPFILENAME!\n"));
  598. #endif // _DEBUG
  599. if( pszHelpFileName )
  600. delete[] (pszHelpFileName);
  601. }
  602. ////////////////////////////////////////////////////////////////////////////////////////
  603. // FUNCTION: OnContextMenu ( WPARAM wParam )
  604. //
  605. // PARAMETERS: wParam - HWND of window under the pointer
  606. //
  607. // PURPOSE: Handle WM_RBUTTONDOWN over all client windows
  608. // (except the list control... that's OnListviewContextMenu() job)
  609. ////////////////////////////////////////////////////////////////////////////////////////
  610. void OnContextMenu(WPARAM wParam, LPARAM lParam)
  611. {
  612. // HWND hListCtrl = NULL
  613. ASSERT (wParam);
  614. #if 0
  615. hListCtrl = GetDlgItem((HWND) wParam, IDC_APPMAN_DRIVE_LIST);
  616. // If you are on the ListCtrl...
  617. if( (HWND)wParam == hListCtrl )
  618. {
  619. SetFocus(hListCtrl);
  620. // Don't attempt if nothing selected
  621. if( iItem != NO_ITEM )
  622. OnListviewContextMenu(hListCtrl,lParam);
  623. } else
  624. #endif
  625. {
  626. // point to help file
  627. LPTSTR pszHelpFileName = new TCHAR[STR_LEN_32];
  628. ASSERT (pszHelpFileName);
  629. if( LoadString(ghInstance, IDS_HELPFILENAME, pszHelpFileName, STR_LEN_32) )
  630. WinHelp((HWND)wParam, pszHelpFileName, HELP_CONTEXTMENU, (ULONG_PTR)gaHelpIDs);
  631. #ifdef _DEBUG
  632. else OutputDebugString(TEXT("JOY.CPL: appman.cpp: OnContextMenu: LoadString Failed to find IDS_HELPFILENAME!\n"));
  633. #endif // _DEBUG
  634. if( pszHelpFileName )
  635. delete[] (pszHelpFileName);
  636. }
  637. }
  638. ///////////////////////////////////////////////////////////////////////////////
  639. // FUNCTION: OnListviewContextMenu( void )
  640. //
  641. // PURPOSE: Handle Context menu in Listview
  642. //
  643. // RETURN: TRUE if successfull, FALSE otherwise
  644. ///////////////////////////////////////////////////////////////////////////////
  645. static void OnListviewContextMenu( HWND hWnd, LPARAM lParam )
  646. {
  647. HMENU hPopupMenu = CreatePopupMenu();
  648. HWND hListCtrl = NULL;
  649. hListCtrl = GetDlgItem(hWnd, IDC_APPMAN_DRIVE_LIST);
  650. ASSERT (hPopupMenu);
  651. // unlike life, bRet defaults to bliss
  652. BOOL bRet = TRUE;
  653. LPTSTR pszText = new TCHAR[STR_LEN_32];
  654. ASSERT (pszText);
  655. // Don't display Rename/Change if on (none) entry
  656. if( !(GetItemData(hListCtrl, (BYTE)iItem) & ID_NONE) )
  657. {
  658. if( TRUE ) // Borrowed code...
  659. {
  660. // add the "Change..." string
  661. ::SendDlgItemMessage(GetParent(hListCtrl), IDC_ADV_CHANGE, WM_GETTEXT, (WPARAM)STR_LEN_32, (LPARAM)(LPCTSTR)pszText);
  662. bRet = AppendMenu(hPopupMenu, MF_ENABLED, IDC_ADV_CHANGE, pszText);
  663. #ifdef _DEBUG
  664. if( !bRet )
  665. TRACE(TEXT("JOY.CPL: OnListviewCOntextMenu: AppendMenu Failed to insert %s\n"), pszText);
  666. #endif //_DEBUG
  667. // Add the Rename text
  668. VERIFY(LoadString(ghInstance, IDS_RENAME, pszText, STR_LEN_32));
  669. bRet = AppendMenu(hPopupMenu, MF_ENABLED, IDC_RENAME, pszText);
  670. #ifdef _DEBUG
  671. if( !bRet )
  672. TRACE(TEXT("JOY.CPL: OnListviewCOntextMenu: AppendMenu Failed to insert %s\n"), pszText);
  673. #endif //_DEBUG
  674. // Add the SEPERATOR and "What's this?"
  675. bRet = AppendMenu(hPopupMenu, MF_SEPARATOR, 0, 0);
  676. #ifdef _DEBUG
  677. if( !bRet )
  678. TRACE(TEXT("JOY.CPL: OnListviewCOntextMenu: AppendMenu Failed to insert SEPERATOR!\n"));
  679. #endif //_DEBUG
  680. }
  681. }
  682. VERIFY(LoadString(ghInstance, IDS_WHATSTHIS, pszText, STR_LEN_32));
  683. bRet = AppendMenu(hPopupMenu, MF_ENABLED, IDS_WHATSTHIS, pszText);
  684. #ifdef _DEBUG
  685. if( !bRet )
  686. TRACE(TEXT("JOY.CPL: OnListviewCOntextMenu: AppendMenu Failed to insert %s\n"), pszText);
  687. #endif //_DEBUG
  688. if( pszText ) delete[] (pszText);
  689. POINT pt;
  690. // lParam is -1 if we got here via Shift+F10
  691. if( lParam > 0 )
  692. {
  693. pt.x = GET_X_LPARAM(lParam);
  694. pt.y = GET_Y_LPARAM(lParam);
  695. } else
  696. {
  697. // Centre the popup on the selected item!
  698. // This get's a good X pos, but the y is the start of the control!
  699. ::SendMessage(hListCtrl, LVM_GETITEMPOSITION, iItem, (LPARAM)&pt);
  700. RECT rc;
  701. ::GetClientRect(hListCtrl, &rc);
  702. pt.x = rc.right>>1;
  703. ClientToScreen(hListCtrl, &pt);
  704. }
  705. bRet = TrackPopupMenu (hPopupMenu, TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON, pt.x, pt.y, 0, ghDlg, NULL);
  706. #ifdef _DEBUG
  707. if( !bRet )
  708. TRACE (TEXT("JOY.CPL: OnListviewContextMenu: TrackPopupMenu Failed!\n"));
  709. #endif //_DEBUG
  710. DestroyMenu (hPopupMenu);
  711. }
  712. #endif