Leaked source code of windows server 2003
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.
 
 
 
 
 
 

857 lines
19 KiB

//
// Microsoft Windows Media Technologies
// Copyright (C) Microsoft Corporation, 1999 - 2001. All rights reserved.
//
//
// This workspace contains two projects -
// 1. ProgHelp which implements the Progress Interface
// 2. The Sample application WmdmApp.
//
// ProgHelp.dll needs to be registered first for the SampleApp to run.
// Includes
//
#include "appPCH.h"
// Local variables
//
// Constants
//
#define MIN_DEVICEWND_W 200
// Macros
//
// Local functions
//
INT_PTR CALLBACK Device_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
/////////////////////////////////////////////////////////////////////
//
// Function implementations
//
CDevices::CDevices()
{
m_hwndDevices = NULL;
m_hwndDevices_TV = NULL;
m_himlSmall = NULL;
}
CDevices::~CDevices()
{
}
HWND CDevices::GetHwnd( void )
{
return m_hwndDevices;
}
HWND CDevices::GetHwnd_TV( void )
{
return m_hwndDevices_TV;
}
BOOL CDevices::Create( HWND hwndParent )
{
BOOL fRet = FALSE;
// Create the Devices dialog
//
m_hwndDevices = CreateDialogParam(
g_hInst,
MAKEINTRESOURCE( IDD_DEVICES ),
hwndParent,
Device_DlgProc,
(LPARAM)this
);
ExitOnNull( m_hwndDevices );
m_hwndDevices_TV = GetDlgItem( m_hwndDevices, IDC_LV_DEVICES );
// Initialize image list
//
ExitOnFalse( InitImageList() );
// Show the window
//
ShowWindow( m_hwndDevices, SW_SHOW );
fRet = TRUE;
lExit:
return fRet;
}
VOID CDevices::Destroy( void )
{
RemoveAllItems();
if( m_hwndDevices )
{
DestroyWindow( m_hwndDevices );
}
if( m_himlSmall )
{
ImageList_Destroy( m_himlSmall );
}
}
VOID CDevices::OnSize( LPRECT prcMain )
{
INT nW, nH;
nW = max( (prcMain->right - prcMain->left)/4, MIN_DEVICEWND_W );
nH = prcMain->bottom - prcMain->top;
SetWindowPos( m_hwndDevices, NULL, -4, 0, nW, nH, SWP_NOZORDER );
SetWindowPos( m_hwndDevices_TV, NULL, 0, 0, nW-10, nH-27, SWP_NOZORDER );
}
BOOL CDevices::InitImageList( void )
{
BOOL fRet = FALSE;
HICON hIcon;
// Init Small image list
//
m_himlSmall = ImageList_Create(
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
ILC_COLOR32 | ILC_MASK,
-1, 0
);
ExitOnNull( m_himlSmall );
// Load icons and add them to the image list
//
hIcon = LoadIcon( g_hInst, MAKEINTRESOURCE(IDI_DEVICE) );
if( hIcon != NULL )
{
ImageList_AddIcon( m_himlSmall, hIcon );
}
// Add the shell folder icons to the image lsit
//
{
CHAR szWinPath[MAX_PATH+1];
SHFILEINFO si;
UINT nRet;
nRet = GetWindowsDirectory( szWinPath, sizeof(szWinPath)/sizeof(szWinPath[0]) );
if (nRet > 0 && nRet <= sizeof(szWinPath)/sizeof(szWinPath[0]))
{
SHGetFileInfo( szWinPath, 0, &si, sizeof(si), SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_ICON );
hIcon = si.hIcon;
ImageList_AddIcon( m_himlSmall, hIcon );
SHGetFileInfo( szWinPath, 0, &si, sizeof(si), SHGFI_SMALLICON | SHGFI_ICON | SHGFI_OPENICON );
hIcon = si.hIcon;
ImageList_AddIcon( m_himlSmall, hIcon );
}
else
{
// @@@@ Do we bail out or is ok to go on?
// goto lExit;
}
}
// Set the image list for the tree view
//
TreeView_SetImageList( m_hwndDevices_TV, m_himlSmall, TVSIL_NORMAL );
// Everything went Ok
//
fRet = TRUE;
lExit:
return fRet;
}
VOID CDevices::RemoveAllItems( void )
{
HTREEITEM hItem;
// Get Root item
//
hItem = TreeView_GetRoot( m_hwndDevices_TV );
if( hItem )
{
do
{
// Remove all children of this device
//
INT nChildren = RemoveChildren( hItem );
// Get the device class associated with this item
//
CItemData *pItemData = (CItemData *) TreeView_GetLParam( m_hwndDevices_TV, hItem );
// Release device class
//
if( pItemData )
{
delete pItemData;
TreeView_SetLParam( m_hwndDevices_TV, hItem, (LPARAM)NULL );
}
hItem = TreeView_GetNextSibling( m_hwndDevices_TV, hItem );
} while( hItem != NULL );
}
// Then delete all the items from the list
//
TreeView_DeleteAllItems( m_hwndDevices_TV );
}
INT CDevices::RemoveChildren( HTREEITEM hItem )
{
BOOL nChildren = 0;
HTREEITEM hNextItem;
hNextItem = TreeView_GetChild( m_hwndDevices_TV, hItem );
if( hNextItem )
{
do
{
nChildren++;
// Remove all children of this device
//
nChildren += RemoveChildren( hNextItem );
// Get the storage class associated with this item
//
CItemData *pItemData = (CItemData *) TreeView_GetLParam( m_hwndDevices_TV, hNextItem );
// Release storage class
//
if( pItemData )
{
delete pItemData;
TreeView_SetLParam( m_hwndDevices_TV, hNextItem, (LPARAM)NULL );
}
hNextItem = TreeView_GetNextSibling( m_hwndDevices_TV, hNextItem );
} while( hNextItem != NULL );
}
return nChildren;
}
BOOL CDevices::AddItem( CItemData *pItemData )
{
BOOL fRet = TRUE;
HTREEITEM hItem;
TVINSERTSTRUCT tvis;
// Set up the item information
//
tvis.hParent = TVI_ROOT;
tvis.hInsertAfter = TVI_SORT;
tvis.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_CHILDREN;
tvis.item.pszText = pItemData->m_szName;
tvis.item.iImage = I_IMAGECALLBACK;
tvis.item.iSelectedImage = I_IMAGECALLBACK;
tvis.item.lParam = (LPARAM)pItemData;
tvis.item.cChildren = 0;
// Add the item
//
hItem = TreeView_InsertItem( m_hwndDevices_TV, &tvis );
if( NULL == hItem )
{
return FALSE;
}
// If there are children, update the item
//
if( HasSubFolders(hItem) )
{
tvis.item.mask = TVIF_HANDLE | TVIF_CHILDREN;
tvis.item.hItem = hItem;
tvis.item.cChildren = 1;
TreeView_SetItem( m_hwndDevices_TV, &(tvis.item) );
}
return fRet;
}
INT CDevices::AddChildren( HTREEITEM hItem, BOOL fDeviceItem )
{
INT nChildren = 0;
HRESULT hr;
IWMDMEnumStorage *pEnumStorage;
// Get the storage enumerator associated with the hItem and
//
CItemData *pItemData = (CItemData *) TreeView_GetLParam( m_hwndDevices_TV, hItem );
ExitOnNull( pItemData );
pEnumStorage = pItemData->m_pEnumStorage;
ExitOnNull( pEnumStorage );
// Reset the storage enumerator
//
hr = pEnumStorage->Reset();
ExitOnFail( hr );
// Add the appropriate list of files to the ListView
//
while( TRUE )
{
IWMDMStorage *pWmdmStorage;
CItemData *pItemStorage;
ULONG ulFetched;
hr = pEnumStorage->Next( 1, &pWmdmStorage, &ulFetched );
if( hr != S_OK )
{
break;
}
if( ulFetched != 1 )
{
ExitOnFail( hr = E_UNEXPECTED );
}
pItemStorage = new CItemData;
if( pItemStorage )
{
hr = pItemStorage->Init( pWmdmStorage );
if( SUCCEEDED(hr) && pItemStorage->m_dwAttributes & WMDM_FILE_ATTR_FOLDER )
{
HTREEITEM hNewItem;
TVINSERTSTRUCT tvis;
// Set up the item information
//
tvis.hParent = hItem;
tvis.hInsertAfter = TVI_SORT;
tvis.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_CHILDREN;
tvis.item.pszText = pItemStorage->m_szName;
tvis.item.iImage = I_IMAGECALLBACK;
tvis.item.iSelectedImage = I_IMAGECALLBACK;
tvis.item.lParam = (LPARAM)pItemStorage;
tvis.item.cChildren = 0;
// Add the item
//
hNewItem = TreeView_InsertItem( m_hwndDevices_TV, &tvis );
if( hNewItem )
{
nChildren++;
// If there are children, update the item
//
if( HasSubFolders(hNewItem) )
{
tvis.item.mask = TVIF_HANDLE | TVIF_CHILDREN;
tvis.item.hItem = hNewItem;
tvis.item.cChildren = 1;
TreeView_SetItem( m_hwndDevices_TV, &(tvis.item) );
}
}
else
{
delete pItemStorage;
}
}
else
{
delete pItemStorage;
}
}
pWmdmStorage->Release();
}
lExit:
return nChildren;
}
BOOL CDevices::HasSubFolders( HTREEITEM hItem )
{
BOOL fRet = FALSE;
// Get the storage enumeration interface from the item
//
CItemData *pItemData = (CItemData *) TreeView_GetLParam( m_hwndDevices_TV, hItem );
ExitOnNull( pItemData );
// If the item is a device or has the has-subfolders attribute set,
// then return TRUE. Otherwise, return FALSE
//
if( pItemData->m_fIsDevice )
{
fRet = TRUE;
}
else if( pItemData->m_dwAttributes & WMDM_STORAGE_ATTR_HAS_FOLDERS )
{
fRet = TRUE;
}
else
{
fRet = FALSE;
}
lExit:
return fRet;
}
HTREEITEM CDevices::GetSelectedItem( LPARAM *pLParam )
{
HTREEITEM hItem = TreeView_GetSelection( m_hwndDevices_TV );
if( hItem )
{
// Return the lParam value of the item that is selected
//
if( pLParam )
{
*pLParam = TreeView_GetLParam( m_hwndDevices_TV, hItem );
}
}
return hItem;
}
BOOL CDevices::SetSelectedItem( HTREEITEM hItem )
{
return TreeView_SelectItem( m_hwndDevices_TV, hItem );
}
BOOL CDevices::UpdateSelection( HTREEITEM hItem, BOOL fDirty )
{
BOOL fRet = FALSE;
HRESULT hr;
IWMDMEnumStorage *pEnumStorage = NULL;
// If hItem is NULL, then use the currently-selected item.
// If no item is selected, use the first device.
//
if( NULL == hItem )
{
hItem = GetSelectedItem( NULL );
if( NULL == hItem )
{
hItem = TreeView_GetRoot( m_hwndDevices_TV );
// If there are no devices, just exit
//
ExitOnNull( hItem );
}
}
if( fDirty )
{
// Remove all current files
//
g_cDevFiles.RemoveAllItems();
// Get the storage enumeration interface from the item
//
CItemData *pItemData = (CItemData *) TreeView_GetLParam( m_hwndDevices_TV, hItem );
ExitOnNull( pItemData );
pEnumStorage = pItemData->m_pEnumStorage;
ExitOnNull( pEnumStorage );
// Reset the storage enumerator
//
hr = pEnumStorage->Reset();
ExitOnFail( hr );
// Add the appropriate list of files to the ListView
//
while( TRUE )
{
IWMDMStorage *pWmdmStorage;
CItemData *pItemStorage;
ULONG ulFetched;
hr = pEnumStorage->Next( 1, &pWmdmStorage, &ulFetched );
if( hr != S_OK )
{
break;
}
if( ulFetched != 1 )
{
ExitOnFail( hr = E_UNEXPECTED );
}
pItemStorage = new CItemData;
if( pItemStorage )
{
hr = pItemStorage->Init( pWmdmStorage );
if( SUCCEEDED(hr) )
{
g_cDevFiles.AddItem( pItemStorage );
}
else
{
delete pItemStorage;
}
UiYield();
}
pWmdmStorage->Release();
}
SetSelectedItem( hItem );
}
// Update the device portion of the status bar
//
UpdateStatusBar();
// Update the file portion of the status bar
//
g_cDevFiles.UpdateStatusBar();
fRet = TRUE;
lExit:
return fRet;
}
INT CDevices::GetDeviceCount( VOID )
{
INT nCount = 0;
HTREEITEM hItem;
// Count Root items
//
for(
hItem = TreeView_GetRoot( m_hwndDevices_TV );
hItem != NULL;
hItem = TreeView_GetNextSibling( m_hwndDevices_TV, hItem )
)
{
nCount++;
}
return nCount;
}
CItemData *CDevices::GetRootDevice( HTREEITEM hItem )
{
HTREEITEM hRootItem;
while( TRUE )
{
hRootItem = hItem;
hItem = TreeView_GetParent( m_hwndDevices_TV, hRootItem );
if( hItem == NULL )
{
break;
}
}
return (CItemData *) TreeView_GetLParam( m_hwndDevices_TV, hRootItem );
}
VOID CDevices::UpdateStatusBar( VOID )
{
INT nCount;
HRESULT hr;
UINT uStrID;
HTREEITEM hItem;
CItemData *pItemDevice;
DWORD dwMemUsed;
char szSpaceKB[MAX_PATH];
// Set the statusbar pane that shows the number of devices
//
nCount = GetDeviceCount();
if( nCount == 0 )
{
uStrID = IDS_SB_DEVICE_MANY;
}
else if( nCount == 1 )
{
uStrID = IDS_SB_DEVICE_ONE;
}
else
{
uStrID = IDS_SB_DEVICE_MANY;
}
g_cStatus.SetTextFormatted( SB_PANE_DEVICE, uStrID, nCount, NULL );
// If there is a selected device in the list, set the status for
// the space free and used
//
hItem = GetSelectedItem( NULL );
if( NULL == hItem )
{
// Empty the space used and free
//
g_cStatus.SetTextSz( SB_PANE_DEVFILES_USED, "" );
g_cStatus.SetTextSz( SB_PANE_DEVFILES_FREE, "" );
}
else
{
pItemDevice = GetRootDevice( hItem );
ExitOnNull( pItemDevice );
hr = pItemDevice->Refresh();
ExitOnFail( hr );
dwMemUsed = pItemDevice->m_dwMemSizeKB - pItemDevice->m_dwMemFreeKB - pItemDevice->m_dwMemBadKB;
// Set the space used
//
g_cStatus.SetTextFormatted(
SB_PANE_DEVFILES_USED,
IDS_SB_DEVICEFILES_USED,
-1,
FormatBytesToSz(dwMemUsed, 0, 1024, szSpaceKB, sizeof(szSpaceKB))
);
// Set the space free
//
g_cStatus.SetTextFormatted(
SB_PANE_DEVFILES_FREE,
IDS_SB_DEVICEFILES_FREE,
-1,
FormatBytesToSz(pItemDevice->m_dwMemFreeKB, 0, 1024, szSpaceKB, sizeof(szSpaceKB))
);
}
lExit:
return;
}
/////////////////////////////////////////////////////////////////////
//
// Local function implementations
//
INT_PTR CALLBACK Device_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WORD wId = LOWORD((DWORD)wParam);
WORD wNotifyCode = HIWORD((DWORD)wParam);
static CDevices *cDevices = NULL;
static HWND hwndTV = NULL;
static BOOL fSelChangeInProgress = FALSE;
switch( uMsg )
{
case WM_INITDIALOG:
cDevices = (CDevices *)lParam;
hwndTV = GetDlgItem( hWnd, IDC_LV_DEVICES );
break;
case WM_NOTIFY:
{
LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam;
HWND hwndCtl = pnmtv->hdr.hwndFrom;
UINT uCode = pnmtv->hdr.code;
// check for item changes in the device listview.
// if an item has changed its selected state, then update the files listview
//
if( hwndCtl != hwndTV )
{
break;
}
switch( uCode )
{
case TVN_SELCHANGED:
if( pnmtv->itemNew.state & LVIS_SELECTED )
{
HTREEITEM hItem = (HTREEITEM) pnmtv->itemNew.hItem;
CItemData *pItemDevice = (CItemData *) TreeView_GetLParam( hwndTV, hItem );
// Check for NULL. Without this, we crash when refreshing the display.
// All pDevice values have been cleared, and we get this message as the
// devices are being removed from the tree view as the selection moves
// from the device being removed, to the next in the list
if( NULL != pItemDevice )
{
// Serialize the device changes, so that we finish changing devices
// before another change begins
if( !fSelChangeInProgress )
{
fSelChangeInProgress = TRUE;
PostMessage( hWnd, WM_DRM_UPDATEDEVICE, (WPARAM)hItem, 0 );
fSelChangeInProgress = FALSE;
}
}
}
break;
case TVN_GETDISPINFO:
{
LPNMTVDISPINFO lptvdi = (LPNMTVDISPINFO) lParam;
INT nImage;
CItemData *pItemData = (CItemData *) TreeView_GetLParam( hwndTV, lptvdi->item.hItem );
if( NULL != pItemData )
{
if( pItemData->m_fIsDevice )
{
nImage = 0;
}
else
{
nImage = ( (lptvdi->item.state & TVIS_EXPANDED) ? 2 : 1 );
}
if( TVIF_IMAGE & lptvdi->item.mask )
{
lptvdi->item.iImage = nImage;
}
if( TVIF_SELECTEDIMAGE & lptvdi->item.mask )
{
lptvdi->item.iSelectedImage = nImage;
}
}
}
break;
case TVN_ITEMEXPANDING:
if( TVE_EXPAND & pnmtv->action )
{
// If the item has not been expanded once already,
// add all its children
//
if( !(pnmtv->itemNew.state & TVIS_EXPANDEDONCE) )
{
BOOL fDeviceItem;
fDeviceItem = ( NULL == TreeView_GetParent(hwndTV, pnmtv->itemNew.hItem) );
cDevices->AddChildren( pnmtv->itemNew.hItem, fDeviceItem );
}
}
else if( TVE_COLLAPSE & pnmtv->action )
{
// Do nothing
}
break;
default:
break;
}
}
break;
// Display the context menu for this device
case WM_CONTEXTMENU :
{
HMENU hMenuLoad;
HMENU hMenu;
hMenuLoad = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT_MENU));
hMenu = GetSubMenu(hMenuLoad, 0);
TrackPopupMenu( hMenu,
TPM_LEFTALIGN | TPM_RIGHTBUTTON,
LOWORD(lParam),
HIWORD(lParam),
0,
hWnd,
NULL);
DestroyMenu(hMenuLoad);
break;
}
case WM_COMMAND :
{
// Show properties dialog for device
if( wParam == IDM_PROPERTIES )
{
HTREEITEM hTree;
CItemData* pItemData;
// Get selected item
hTree = TreeView_GetSelection( cDevices->GetHwnd_TV() );
if( hTree )
{
// Get item data of selected item
pItemData = (CItemData *) TreeView_GetLParam( hwndTV, hTree );
if( pItemData )
{
if( pItemData->m_fIsDevice )
{
// Show the device property dialog
DialogBoxParam( g_hInst,
MAKEINTRESOURCE(IDD_PROPERTIES_DEVICE),
g_hwndMain,
DeviceProp_DlgProc,
(LPARAM)pItemData );
}
else
{
// Show the device property dialog
DialogBoxParam( g_hInst,
MAKEINTRESOURCE(IDD_PROPERTIES_STORAGE),
g_hwndMain,
StorageProp_DlgProc,
(LPARAM)pItemData );
}
}
}
}
break;
}
case WM_DRM_UPDATEDEVICE:
cDevices->UpdateSelection( (HTREEITEM)wParam, TRUE );
break;
default:
break;
}
return 0;
}