894 lines
25 KiB
C++
894 lines
25 KiB
C++
/*
|
|
File: AppLock.cpp
|
|
Project:
|
|
Author: ScottLe
|
|
Date: 1/31/00
|
|
Comments:
|
|
AppMan application locking (pinning) Tab in Game Control Panel.
|
|
|
|
Copyright (c) 1999, 2000 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 <afxcmn.h>
|
|
#include <windowsx.h>
|
|
|
|
#include <cpl.h>
|
|
|
|
#include <winuser.h> // For RegisterDeviceNotification stuff!
|
|
#include <dbt.h> // for DBT_ defines!!!
|
|
#include <commctrl.h> // for listview
|
|
#include <tchar.h> // for TCHAR
|
|
#include <malloc.h> // 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 <AppManAdmin.h>
|
|
|
|
#if _DEBUG
|
|
#define Assert(x) { if(!(x)) { DebugBreak(); }}
|
|
#else
|
|
#define Assert(x)
|
|
#endif
|
|
|
|
static HWND ghDlg;
|
|
static HWND hAppManCheckBox;
|
|
extern const DWORD gaHelpIDs[];
|
|
extern HINSTANCE ghInstance;
|
|
|
|
//
|
|
// GLOBALS
|
|
//
|
|
static BOOL g_ListPopulated = FALSE;
|
|
static int g_nm_click = -1;
|
|
static BOOL g_nm_click_state = FALSE;
|
|
static BOOL g_DlgInitialized = FALSE;
|
|
static BOOL g_ChkBoxUpdate = FALSE;
|
|
|
|
static GUID *g_lpsGUID = NULL;
|
|
|
|
extern IApplicationManagerAdmin *g_IAppManAdmin;
|
|
|
|
static struct {
|
|
BOOL isValid;
|
|
int iItem;
|
|
BOOL isClicked;
|
|
} g_ItemChanged;
|
|
|
|
// constants
|
|
const short NO_ITEM = -1;
|
|
static short iItem = NO_ITEM; // index of selected item
|
|
|
|
// 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);
|
|
|
|
static void OnScroll(HWND hDlg, WPARAM wParam);
|
|
static void OnListCtrl_Select(HWND hDlg);
|
|
static void OnListCtrl_DblClick(HWND hDlg);
|
|
static void OnListCtrl_UpdateFromCheckBoxes( HWND hDlg );
|
|
|
|
static void OnAdvHelp (LPARAM);
|
|
//static void OnContextMenu (WPARAM wParam, LPARAM lParam);
|
|
static void OnListviewContextMenu (HWND hWnd, LPARAM lParam );
|
|
|
|
|
|
// util fcns
|
|
static int MyInsertItem( HWND hCtrl, LPTSTR lpszBuff, int iItem ); // replaced from cpanel.cpp
|
|
static void PostDlgItemEnableWindow( HWND hDlg, USHORT nItem, BOOL bEnabled );
|
|
static void EnableDiskManageControls( HWND hDlg, BOOL bEnable );
|
|
static void EnableScrollBarAndText( HWND hDlg, BOOL bEnable );
|
|
//static void EnableAllControls( HWND hDlg, BOOL bEnable );
|
|
DWORD GetCurrentDeviceFromList( HWND hDlg, BYTE *nItem = NULL );
|
|
|
|
static void ConfigureListControl( HWND hDlg );
|
|
static void PopulateListControl( HWND hDlg, BYTE nItem );
|
|
|
|
void UpdateCurrentDeviceFromScrollBar( HWND hDlg, DWORD newPos );
|
|
|
|
//void UpdateListAndScrollBar( HWND hDlg, BOOL bJustScrollBar = FALSE );
|
|
|
|
|
|
// From AppMan.cpp
|
|
extern HRESULT AppManShutdown();
|
|
extern HRESULT AppManInit();
|
|
extern BOOL AppManInitialized();
|
|
|
|
//
|
|
// 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 );
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// FUNCTION: AppManLockProc(HWND hDlg, ULONG uMsg, WPARAM wParam, LPARAM lParam)
|
|
//
|
|
// PARAMETERS: hDlg -
|
|
// uMsg -
|
|
// wParam -
|
|
// lParam -
|
|
//
|
|
// PURPOSE: Main callback function for "Appman" sheet
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL WINAPI AppManLockProc(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_DESTROY:
|
|
//return(HANDLE_WM_DESTROY(hDlg, wParam, lParam, OnDestroy));
|
|
//jchauvin 04/10/2000 Fix Build break in Win64
|
|
free( g_lpsGUID );
|
|
g_lpsGUID = NULL;
|
|
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 );
|
|
|
|
g_DlgInitialized = TRUE;
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
#if 0
|
|
switch( id )
|
|
{
|
|
|
|
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_MANAGE_DISK:
|
|
{
|
|
BOOL isChecked = (IsDlgButtonChecked(hDlg, id)) ? TRUE : FALSE;
|
|
EnableDiskManageControls( hDlg, !isChecked );
|
|
}
|
|
break;
|
|
*/
|
|
default:
|
|
break;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// FUNCTION: OnNotify(HWND hDlg, WPARAM idFrom, NMHDR* pnmhdr)
|
|
//
|
|
// PARAMETERS: hDlg -
|
|
// idFrom - ID of control sending WM_NOTIFY message
|
|
// pnmhdr -
|
|
//
|
|
// PURPOSE: WM_NOTIFY message handler
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
static DWORD ct=0L;
|
|
|
|
BOOL OnNotify(HWND hDlg, WPARAM idFrom, LPARAM lParam)
|
|
{
|
|
NMLISTVIEW *pnmv = NULL;
|
|
LPNMHDR pnmhdr = (LPNMHDR)lParam;
|
|
|
|
|
|
switch (pnmhdr->code)
|
|
{
|
|
// 4/13/2000(RichGr): Repopulate the List Control if we reacquire the focus.
|
|
// This keeps the data in sync with installs and uninstalls.
|
|
case NM_SETFOCUS:
|
|
{
|
|
PopulateListControl(hDlg, 0);
|
|
break;
|
|
}
|
|
|
|
case LVN_ITEMCHANGED:
|
|
pnmv = (LPNMLISTVIEW) lParam;
|
|
|
|
if( idFrom == IDC_APPMAN_PIN_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: AppLock.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_ChkBoxUpdate )
|
|
{
|
|
NMITEMACTIVATE *ll = (LPNMITEMACTIVATE)lParam;
|
|
HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_PIN_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;
|
|
|
|
g_ItemChanged.iItem = ll->iItem;
|
|
OnListCtrl_Select( hDlg );
|
|
}
|
|
|
|
return TRUE;
|
|
break;
|
|
} // if
|
|
} // switch
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
void OnListCtrl_UpdateFromCheckBoxes( HWND hDlg )
|
|
{
|
|
#if 1
|
|
HRESULT hResult;
|
|
BOOL bIsAppManPinned = FALSE;
|
|
BOOL bDoToggle = FALSE;
|
|
BYTE nItem = 0;
|
|
GUID *pGuid = NULL;
|
|
IApplicationManager * lpApplicationManager;
|
|
IApplicationEntry * lpApplicationEntry;
|
|
DWORD dwIndex;
|
|
|
|
//
|
|
// go through each item, check the box & set pinning
|
|
//
|
|
HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_PIN_LIST);
|
|
if( !hLC ) return;
|
|
|
|
int iItem = -1;
|
|
//while( (iItem = ListView_GetNextItem( hLC, iItem, LVNI_ALL )) >= 0 )
|
|
if( g_ItemChanged.isValid )
|
|
{
|
|
|
|
//
|
|
// very important: tell the system that this information is no longer
|
|
// valid. Hence we won't recurse mysteriously or unpredictably.
|
|
//
|
|
g_ItemChanged.isValid = FALSE;
|
|
|
|
iItem = g_ItemChanged.iItem;
|
|
BOOL bIsCheckBoxPinned = !(ListView_GetCheckState( hLC, iItem )); // Check box has the new state NOW
|
|
|
|
// Set the pin state using the GUID to identify the app
|
|
|
|
//JWC 4/10/2000 Added to fix Win64 Build problem
|
|
dwIndex = (DWORD) GetItemData(hLC, (BYTE)iItem );
|
|
pGuid = (GUID *) ((ULONG_PTR)g_lpsGUID + (ULONG_PTR)dwIndex*sizeof(GUID));
|
|
|
|
|
|
// Find out what the pin state is in AppMan
|
|
// Get an Application Manager interface
|
|
hResult = CoCreateInstance(CLSID_ApplicationManager, NULL, CLSCTX_INPROC_SERVER, IID_ApplicationManager, (LPVOID *) &lpApplicationManager);
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
|
|
// Get an application entry object.
|
|
hResult = lpApplicationManager->CreateApplicationEntry(&lpApplicationEntry);
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
|
|
// Set the app's GUID
|
|
hResult = lpApplicationEntry->SetProperty(APP_PROPERTY_GUID, pGuid, sizeof(GUID));
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
|
|
// Populate the app info structure
|
|
hResult = lpApplicationManager->GetApplicationInfo(lpApplicationEntry);
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
|
|
// Get the current PIN state of the app
|
|
hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_PIN, &bIsAppManPinned, sizeof(bIsAppManPinned));
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
|
|
// bIsAppManPinned is the state appman has for the application.
|
|
// bIsCheckBoxPinned is the check box state (checked = true = not pinned)
|
|
// Since AppMan's pinning state for an app is a toggle we could get out of sync
|
|
// due to redraw or timing issues with the list view control -- so,
|
|
// we need to make sure that the check box's state is insync with AppMan.
|
|
// When in doubt, force it to the displayed state of the check box.
|
|
|
|
// Truth table:
|
|
//
|
|
// AppManPinned CheckBoxPinned (T=not checked) DoToggle Reason
|
|
// T T No Same State Already (sync error!)
|
|
// F F No Same State Already (sync error!)
|
|
// T F Yes New State Selected
|
|
// F T Yes New State Selected
|
|
//
|
|
if (bIsAppManPinned != bIsCheckBoxPinned)
|
|
bDoToggle = TRUE;
|
|
else
|
|
{
|
|
// ERR: BUG BUG: The control panel and appman are out of sync, this is an error.
|
|
bDoToggle = FALSE;
|
|
#ifdef _DEBUG
|
|
OutputDebugString(TEXT("JOY.CPL: AppLock.cpp: Pinning Update, AppMan and Check box states are out of sync!\n"));
|
|
#endif // _DEBUG
|
|
|
|
}
|
|
|
|
if (bDoToggle && pGuid && g_IAppManAdmin) // Toggle the pin state
|
|
hResult = g_IAppManAdmin->DoApplicationAction(ACTION_APP_PIN, pGuid, 0, (LPVOID) NULL, sizeof(DWORD));
|
|
|
|
// ERR: Handle error conditions
|
|
}
|
|
}
|
|
}
|
|
lpApplicationEntry->Release();
|
|
}
|
|
lpApplicationManager->Release();
|
|
}
|
|
}
|
|
|
|
g_ChkBoxUpdate = TRUE;
|
|
#endif
|
|
}
|
|
|
|
|
|
void OnListCtrl_Select(HWND hDlg)
|
|
{
|
|
//
|
|
// set focus on that item
|
|
//
|
|
HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_PIN_LIST);
|
|
SetListCtrlItemFocus( hLC, (BYTE)g_ItemChanged.iItem );
|
|
}
|
|
|
|
int MyInsertItem( HWND hCtrl, LPTSTR lpszBuff, int iItem )
|
|
{
|
|
LPLVITEM plvItem = (LPLVITEM)_alloca(sizeof(LVITEM));
|
|
ASSERT (plvItem);
|
|
|
|
ZeroMemory( plvItem, sizeof( LVITEM ) );
|
|
|
|
plvItem->mask = LVIF_TEXT;
|
|
plvItem->pszText = lpszBuff;
|
|
plvItem->cchTextMax = lstrlen(lpszBuff);
|
|
plvItem->iItem = iItem;
|
|
|
|
return ListView_InsertItem(hCtrl, (const LPLVITEM)plvItem);
|
|
}
|
|
|
|
|
|
#define APPMAN_ADV_PIN_CHECKBOX 0
|
|
#define APPMAN_ADV_PIN_TITLENAME 1
|
|
|
|
#define IDS_APPMANPIN_CHECKBOX 40043
|
|
#define IDS_APPMANPIN_TITLENAME 40044
|
|
|
|
|
|
|
|
void ConfigureListControl( HWND hDlg )
|
|
{
|
|
#if 1
|
|
HWND hLC;
|
|
|
|
hLC = GetDlgItem(hDlg, IDC_APPMAN_PIN_LIST);
|
|
::SendMessage( hLC , LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
|
|
LVS_EX_FULLROWSELECT
|
|
| LVS_EX_CHECKBOXES
|
|
| LVS_EX_HEADERDRAGDROP
|
|
// LVS_EX_TWOCLICKACTIVATE // LVN_ITEMACTIVATE (WM_NOTIFY)
|
|
);
|
|
|
|
RECT rc;
|
|
GetClientRect(hLC, &rc);
|
|
DWORD w = rc.right-rc.left;
|
|
DWORD w1 = w / 3; // 1/3 of width
|
|
DWORD w2 = w - w1; // 2/3 of the width
|
|
InsertColumn(hLC, APPMAN_ADV_PIN_CHECKBOX, IDS_APPMANPIN_CHECKBOX, (USHORT)(w1));
|
|
InsertColumn(hLC, APPMAN_ADV_PIN_TITLENAME,IDS_APPMANPIN_TITLENAME, (USHORT)(w2));
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
//STDMETHODIMP CApplicationManagerAdmin::DoApplicationAction(const DWORD dwAction, const GUID * lpGuid, LPVOID lpData, const DWORD dwDataLen)
|
|
//STDMETHODIMP CApplicationManagerAdmin::EnumApplications(const DWORD dwApplicationIndex, IApplicationEntry * lpObject)
|
|
|
|
|
|
// populates from appman state
|
|
void PopulateListControl( HWND hDlg, BYTE nItem )
|
|
{
|
|
#if 1
|
|
HRESULT hr = S_OK;
|
|
BOOL isExcluded = FALSE;
|
|
UCHAR listIndex = (UCHAR)0;
|
|
IApplicationManager *lpApplicationManager;
|
|
IApplicationEntry *lpApplicationEntry;
|
|
HRESULT hResult;
|
|
DWORD dwIndex = 0L;
|
|
TCHAR szString[MAX_PATH];
|
|
GUID sGuid;
|
|
|
|
|
|
g_ListPopulated = FALSE;
|
|
g_ChkBoxUpdate = FALSE;
|
|
|
|
Assert( AppManInitialized() );
|
|
|
|
HWND hLC = GetDlgItem(hDlg, IDC_APPMAN_PIN_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);
|
|
|
|
//JWC 04/10/2000 Fixing build break in Win64 code
|
|
g_lpsGUID = (GUID *)malloc(sizeof(GUID));
|
|
if (g_lpsGUID == NULL)
|
|
{
|
|
//Cannot allocate memory
|
|
hResult = E_UNEXPECTED;
|
|
}
|
|
// Get an Application Manager interface
|
|
hResult = CoCreateInstance(CLSID_ApplicationManager, NULL, CLSCTX_INPROC_SERVER, IID_ApplicationManager, (LPVOID *) &lpApplicationManager);
|
|
if (SUCCEEDED(hResult) && g_IAppManAdmin)
|
|
{
|
|
|
|
// Get an application entry object. This will be populated during the Enumeration loop
|
|
hResult = lpApplicationManager->CreateApplicationEntry(&lpApplicationEntry);
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
// Enumerate all the applications AppMan knows about
|
|
dwIndex = 0;
|
|
while (SUCCEEDED(g_IAppManAdmin->EnumApplications(dwIndex, lpApplicationEntry)))
|
|
{
|
|
// For each app, get information about it (Pinning state, title, GUID etc) and put in the list
|
|
DWORD dwState = 0L;
|
|
|
|
// App must be in a good state
|
|
hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_STATE, &dwState, sizeof(dwState));
|
|
|
|
dwState &= APP_STATE_MASK;
|
|
|
|
if (!SUCCEEDED(hResult) ||
|
|
dwState == APP_STATE_INSTALLING ||
|
|
dwState == APP_STATE_UNSTABLE)
|
|
{
|
|
dwIndex++;
|
|
continue; // Skip bad apps
|
|
}
|
|
else // Good app...
|
|
{
|
|
// Create the check box
|
|
int actualListIndex = MyInsertItem( hLC, _T(""), dwIndex );
|
|
|
|
// Get the app's GUID
|
|
hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_GUID, &sGuid, sizeof(sGuid));
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
// Allocate a GUID
|
|
// ISSUE-2001/03/29-timgill Need error handling
|
|
|
|
//JWC 04/10/2000 Fixing problem with GUID for Win64
|
|
|
|
g_lpsGUID = (GUID *)realloc((void*)g_lpsGUID,(dwIndex+1)* sizeof(GUID));
|
|
|
|
*(GUID *)((ULONG_PTR)g_lpsGUID+((ULONG_PTR)(dwIndex)*sizeof(GUID)))= sGuid;
|
|
|
|
SetItemData(hLC, (BYTE)actualListIndex, dwIndex );
|
|
}
|
|
|
|
// Get Pin state
|
|
{
|
|
DWORD bPinned = FALSE;
|
|
hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_PIN, &bPinned, sizeof(bPinned));
|
|
if (SUCCEEDED(hResult))
|
|
ListView_SetCheckState( hLC, actualListIndex, (BOOL)!bPinned ); // Checked=not pinned
|
|
}
|
|
|
|
// TODO: Company name and/or signature...?
|
|
// hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_COMPANYNAME | APP_PROPERTY_STR_ANSI, &szString, sizeof(szString));
|
|
|
|
#ifdef _UNICODE
|
|
hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_SIGNATURE | APP_PROPERTY_STR_UNICODE, &szString, sizeof(szString));
|
|
#else
|
|
hResult = lpApplicationEntry->GetProperty(APP_PROPERTY_SIGNATURE | APP_PROPERTY_STR_ANSI, &szString, sizeof(szString));
|
|
#endif
|
|
// Set the title name in the "title column"
|
|
if (SUCCEEDED(hResult))
|
|
SetItemText(hLC, (BYTE)actualListIndex, APPMAN_ADV_PIN_TITLENAME, szString);
|
|
}
|
|
dwIndex++;
|
|
}
|
|
}
|
|
lpApplicationEntry->Release();
|
|
}
|
|
|
|
lpApplicationManager->Release();
|
|
|
|
//
|
|
// 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;
|
|
#endif
|
|
}
|
|
|
|
|
|
void EnableScrollBarAndText( HWND hDlg, BOOL bEnable )
|
|
{
|
|
#if 0
|
|
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 );
|
|
#endif
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// AppMan functions
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
#define RELEASE(p) { if((p)) { (p)->Release(); p = NULL; } }
|
|
|
|
#if 0
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
// 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
|
|
{
|
|
// Centre 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);
|
|
}
|
|
#endif
|