1003 lines
26 KiB
C++
1003 lines
26 KiB
C++
//=============================================================================*
|
|
// COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
//=============================================================================*
|
|
// File: ListView.cpp
|
|
//=============================================================================*
|
|
|
|
#include "stdafx.h"
|
|
|
|
#ifndef SNAPIN
|
|
#ifndef NOWINDOWSH
|
|
#include <windows.h>
|
|
#endif
|
|
#endif
|
|
#include <commctrl.h>
|
|
|
|
#include "Message.h"
|
|
#include "resource.h"
|
|
#include "DfrgRes.h"
|
|
#include "GetDfrgRes.h"
|
|
extern "C" {
|
|
#include "SysStruc.h"
|
|
}
|
|
#include "DfrgCmn.h"
|
|
#include "DfrgEngn.h"
|
|
#include "DfrgUI.h"
|
|
#include "DfrgCtl.h"
|
|
#include "ErrMacro.h"
|
|
#include "ErrMsg.h"
|
|
#include "VolList.h"
|
|
#include "ListView.h"
|
|
#include "uicommon.h"
|
|
|
|
#define NUM_COLUMNS 6
|
|
|
|
static isDescending = FALSE; // for sort function
|
|
|
|
static int CALLBACK ListViewCompareFunc(IN LPARAM lParam1, IN LPARAM lParam2, IN LPARAM lParamSort);
|
|
|
|
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
|
|
GLOBAL VARIABLES:
|
|
HINSTANCE hInst:
|
|
|
|
INPUT:
|
|
None;
|
|
|
|
RETURN:
|
|
None.
|
|
*/
|
|
|
|
CESIListView::CESIListView(CDfrgCtl *pDfrgCtl)
|
|
{
|
|
// the list view gets a pointer to his parent OCX
|
|
m_pDfrgCtl = pDfrgCtl;
|
|
|
|
m_hwndListView = NULL;
|
|
m_himlLarge = NULL; // image list for icon view
|
|
m_himlSmall = NULL; // image list for other views
|
|
m_pVolumeList = NULL;
|
|
}
|
|
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
|
|
GLOBAL VARIABLES:
|
|
|
|
INPUT:
|
|
None.
|
|
|
|
RETURN:
|
|
None.
|
|
*/
|
|
|
|
CESIListView::~CESIListView()
|
|
{
|
|
|
|
//These destroys are erroring and not freeing the memory. This is creating a memory leak.
|
|
// I think this is caused by the fact that the Listview is being destroyed early because
|
|
// it is a child of the main OCX, and when we try to destroy the ImageLists, they are no
|
|
// longer associated with a active window.
|
|
|
|
if(m_himlSmall) {
|
|
ImageList_RemoveAll(m_himlSmall);
|
|
ImageList_Destroy(m_himlSmall);
|
|
}
|
|
|
|
if(m_himlLarge) {
|
|
ImageList_RemoveAll(m_himlLarge);
|
|
ImageList_Destroy(m_himlLarge);
|
|
|
|
}
|
|
DeleteAllListViewItems();
|
|
|
|
if (IsWindow(m_hwndListView)) {
|
|
DestroyWindow(m_hwndListView);
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
|
|
GLOBAL VARIABLES:
|
|
HINSTANCE hInst:
|
|
|
|
INPUT:
|
|
None;
|
|
|
|
RETURN:
|
|
None.
|
|
*/
|
|
BOOL CESIListView::EnableWindow(BOOL bIsEnabled)
|
|
{
|
|
if (bIsEnabled){
|
|
ListView_SetTextColor(m_hwndListView, ::GetSysColor(COLOR_BTNTEXT));
|
|
}
|
|
else{
|
|
ListView_SetTextColor(m_hwndListView, ::GetSysColor(COLOR_GRAYTEXT));
|
|
}
|
|
|
|
return ::EnableWindow(m_hwndListView, bIsEnabled);
|
|
}
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
|
|
GLOBAL VARIABLES:
|
|
HINSTANCE hInst:
|
|
|
|
INPUT:
|
|
None;
|
|
|
|
RETURN:
|
|
None.
|
|
*/
|
|
|
|
BOOL
|
|
CESIListView::InitializeListView(
|
|
IN CVolList* pVolumeList,
|
|
IN HWND hwndMain,
|
|
IN HINSTANCE hInstance
|
|
)
|
|
{
|
|
require(pVolumeList != NULL);
|
|
require(hwndMain != NULL);
|
|
require(hInstance != NULL);
|
|
|
|
// save the address of the volume comtainer class object
|
|
m_pVolumeList = pVolumeList;
|
|
|
|
TCHAR cTemp[200];
|
|
|
|
// Create the list view window.
|
|
if((m_hwndListView = CreateWindowEx(
|
|
WS_EX_WINDOWEDGE, //WS_EX_CLIENTEDGE, WS_EX_DLGMODALFRAME, // extended window style
|
|
WC_LISTVIEW, // pointer to registered class name
|
|
TEXT("DEFRAG_LISTVIEW"), // pointer to window name
|
|
WS_CHILD | LVS_REPORT |
|
|
LVS_SHAREIMAGELISTS | //share the image list so we can delete it later and not cause a leak
|
|
LVS_SHOWSELALWAYS | LVS_SINGLESEL, // window style (see help on "CListCtrl::Create")
|
|
0, // hor position of window
|
|
0, // ver position of window
|
|
CW_USEDEFAULT, // window width
|
|
CW_USEDEFAULT, // window height
|
|
hwndMain, // handle to parent or owner
|
|
NULL, // handle to menu, or child-window identifier
|
|
hInstance, // handle to application instance
|
|
NULL // pointer to window-creation data
|
|
)) == NULL) {
|
|
|
|
Message(TEXT("InitializeListView - CreateWindow."), GetLastError(), TEXT("m_hwndListView"));
|
|
return FALSE;
|
|
}
|
|
|
|
// Initialize the image lists.
|
|
if (!InitListViewImageLists(m_hwndListView, hInstance)) {
|
|
Message(TEXT("InitializeListView - InitListViewImageLists."), E_FAIL, 0);
|
|
}
|
|
|
|
// make the listview hilite the entire row
|
|
ListView_SetExtendedListViewStyle(m_hwndListView, LVS_EX_FULLROWSELECT);
|
|
|
|
// Define the initial default width of each column entry.
|
|
// 0 = Volume
|
|
// 1 = Session Status
|
|
// 2 = File System
|
|
// 3 = Capacity
|
|
// 4 = Free Space
|
|
// 5 = %Free Space
|
|
int iColumnWidth[NUM_COLUMNS] = {120, 120, 90, 80, 100, 100};
|
|
int iColumnFormat[NUM_COLUMNS] = {
|
|
LVCFMT_LEFT,
|
|
LVCFMT_LEFT,
|
|
LVCFMT_LEFT,
|
|
LVCFMT_RIGHT,
|
|
LVCFMT_RIGHT,
|
|
LVCFMT_RIGHT
|
|
};
|
|
int iColumnID[NUM_COLUMNS] = {
|
|
IDS_FIRST_COLUMN,
|
|
IDS_SECOND_COLUMN,
|
|
IDS_THIRD_COLUMN,
|
|
IDS_FOURTH_COLUMN,
|
|
IDS_FIFTH_COLUMN,
|
|
IDS_SIXTH_COLUMN
|
|
};
|
|
|
|
// Initialize the LVCOLUMN structure.
|
|
LVCOLUMN lvc = {0};
|
|
lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM;
|
|
lvc.pszText = cTemp; // column header (loaded from resources in loop below)
|
|
|
|
// Prepare for font calculations.
|
|
int tmpStrWidth;
|
|
|
|
// Add the columns.
|
|
for (int col = 0; col < NUM_COLUMNS; col++) {
|
|
|
|
lvc.iSubItem = col;
|
|
lvc.fmt = iColumnFormat[col];
|
|
|
|
// Get the names from the main defrag resource string table.
|
|
LoadString(
|
|
GetDfrgResHandle(),
|
|
iColumnID[col],
|
|
cTemp,
|
|
sizeof(cTemp)/sizeof(TCHAR));
|
|
|
|
// _tcscpy(lvc.pszText, cTemp);
|
|
// _tcsnccpy(lvc.pszText, cTemp);
|
|
|
|
// Insert the columns into the ListView.
|
|
if (ListView_InsertColumn(m_hwndListView, col, &lvc) == -1) {
|
|
Message(TEXT("InitializeListView - ListView_InsertColumn."), E_FAIL, 0);
|
|
break;
|
|
}
|
|
|
|
// Size column to header text.
|
|
if (!ListView_SetColumnWidth(m_hwndListView, col, LVSCW_AUTOSIZE_USEHEADER)) {
|
|
Message(TEXT("InitializeListView - ListView_SetColumnWidth."), E_FAIL, 0);
|
|
}
|
|
|
|
// Grow width if needed.
|
|
tmpStrWidth = ListView_GetColumnWidth(m_hwndListView, col);
|
|
if (tmpStrWidth < iColumnWidth[col]) {
|
|
if (!ListView_SetColumnWidth(m_hwndListView, col, iColumnWidth[col])) {
|
|
Message(TEXT("InitializeListView - 2nd ListView_SetColumnWidth."), E_FAIL, 0);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
::ShowWindow(m_hwndListView, TRUE);
|
|
return TRUE;
|
|
}
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
Creates image lists for a list view.
|
|
|
|
GLOBAL VARIABLES:
|
|
|
|
INPUT:
|
|
HWND m_hwndListView - handle of the list view window.
|
|
|
|
RETURN:
|
|
TRUE = success
|
|
FALSE = error
|
|
*/
|
|
|
|
BOOL
|
|
CESIListView::InitListViewImageLists(
|
|
IN HWND m_hwndListView,
|
|
IN HINSTANCE hInstance
|
|
)
|
|
{
|
|
// Create the full-sized and small icon image lists.
|
|
m_himlLarge = ImageList_Create(GetSystemMetrics(SM_CXICON),
|
|
GetSystemMetrics(SM_CYICON),
|
|
ILC_MASK, //TRUE,
|
|
2,
|
|
1);
|
|
|
|
m_himlSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
|
|
GetSystemMetrics(SM_CYSMICON),
|
|
ILC_MASK, //TRUE,
|
|
2,
|
|
1);
|
|
|
|
// Add an icon to each image list.
|
|
HICON hiconItem = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DISK));
|
|
if (hiconItem){
|
|
ImageList_AddIcon(m_himlLarge, hiconItem);
|
|
ImageList_AddIcon(m_himlSmall, hiconItem);
|
|
}
|
|
|
|
hiconItem = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_REMDISK));
|
|
if (hiconItem){
|
|
ImageList_AddIcon(m_himlLarge, hiconItem);
|
|
ImageList_AddIcon(m_himlSmall, hiconItem);
|
|
}
|
|
|
|
// Assign the image lists to the list view control.
|
|
ListView_SetImageList(m_hwndListView, m_himlLarge, LVSIL_NORMAL);
|
|
|
|
|
|
|
|
ListView_SetImageList(m_hwndListView, m_himlSmall, LVSIL_SMALL);
|
|
|
|
return TRUE;
|
|
}
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
Sizes the list view window
|
|
|
|
GLOBAL VARIABLES:
|
|
HWND m_hwndListView - handle of the list view window.
|
|
|
|
INPUT:
|
|
|
|
RETURN:
|
|
TRUE = success
|
|
FALSE = error
|
|
*/
|
|
|
|
BOOL CESIListView::SizeListView(
|
|
IN int iHorizontal,
|
|
IN int iVertical,
|
|
IN int iWidth,
|
|
IN int iHeight
|
|
)
|
|
{
|
|
// Size and position the List View.
|
|
MoveWindow(
|
|
m_hwndListView, // handle of window
|
|
iHorizontal, // horizontal position
|
|
iVertical, // vertical position
|
|
iWidth, // width
|
|
iHeight, // height
|
|
TRUE // repaint
|
|
);
|
|
|
|
return TRUE;
|
|
}
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
Repaint the list view.
|
|
|
|
GLOBAL VARIABLES:
|
|
HWND m_hwndListView - handle of the list view window.
|
|
|
|
INPUT:
|
|
|
|
RETURN:
|
|
TRUE = success
|
|
FALSE = error
|
|
*/
|
|
BOOL CESIListView::RepaintListView(void)
|
|
{
|
|
ListView_RedrawItems(m_hwndListView, 0, ListView_GetItemCount(m_hwndListView)-1);
|
|
|
|
BOOL isOk = UpdateWindow(m_hwndListView);
|
|
if (!isOk) {
|
|
Message(L"RepaintListView", GetLastError(), NULL);
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
Repaint a single list view row
|
|
|
|
GLOBAL VARIABLES:
|
|
none
|
|
|
|
INPUT:
|
|
|
|
RETURN:
|
|
TRUE = success
|
|
FALSE = error
|
|
*/
|
|
BOOL CESIListView::Update(CVolume *pVolume)
|
|
{
|
|
LV_ITEM lvi;
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iSubItem = 0;
|
|
|
|
// Find that drive in the list
|
|
for (lvi.iItem=0; lvi.iItem < ListView_GetItemCount(m_hwndListView); lvi.iItem++) {
|
|
|
|
// Get the data structure associated with this drive
|
|
ListView_GetItem(m_hwndListView, &lvi);
|
|
|
|
// lparam is a pointer to the data struct
|
|
// if a match, update that row
|
|
if (pVolume == (CVolume *) lvi.lParam){
|
|
ListView_Update(m_hwndListView, lvi.iItem);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
handles notification messages for the list view window
|
|
|
|
GLOBAL VARIABLES:
|
|
HWND m_hwndListView - handle of the list view window.
|
|
|
|
INPUT:
|
|
|
|
RETURN:
|
|
TRUE = success
|
|
FALSE = error
|
|
*/
|
|
|
|
void CESIListView::NotifyListView(IN LPARAM lParam)
|
|
{
|
|
NM_LISTVIEW *pnm = (NM_LISTVIEW *)lParam;
|
|
|
|
// Branch depending on the specific notification message.
|
|
switch (pnm->hdr.code) {
|
|
|
|
case NM_KILLFOCUS: // when the listview loses the focus
|
|
//Message(TEXT("NotifyListView: NM_KILLFOCUS"), -1, NULL);
|
|
break;
|
|
|
|
case NM_DBLCLK:
|
|
//Message(TEXT("NotifyListView: NM_DBLCLK"), -1, NULL);
|
|
break;
|
|
|
|
case LVN_ITEMCHANGED:
|
|
//case NM_RCLICK:
|
|
//case NM_CLICK:
|
|
{
|
|
Message(TEXT("NotifyListView: LVN_ITEMCHANGED"), -1, NULL);
|
|
CVolume *pSelectedVolume = NULL;
|
|
|
|
// Get the current number of items in the list view window
|
|
UINT iItemCount = ListView_GetItemCount(pnm->hdr.hwndFrom);
|
|
|
|
// loop through list and find who's selected now
|
|
for (UINT index=0; index < iItemCount; index++) {
|
|
|
|
// Check if the item is selected.
|
|
if(ListView_GetItemState(pnm->hdr.hwndFrom, index, LVIS_SELECTED) == LVIS_SELECTED ) {
|
|
|
|
// Get the destination path & file name.
|
|
LV_ITEM lvi;
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iItem = index;
|
|
lvi.iSubItem = 0;
|
|
|
|
// get the lparam, it is a pointer to the data struct
|
|
ListView_GetItem(pnm->hdr.hwndFrom, &lvi);
|
|
|
|
pSelectedVolume = (CVolume *) lvi.lParam;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Bail if no selected item was found.
|
|
if (index >= iItemCount){
|
|
break;
|
|
}
|
|
|
|
//check the volume and change if it is not the current volume
|
|
if (pSelectedVolume != NULL) {
|
|
// make this the current volume
|
|
m_pVolumeList->SetCurrentVolume(pSelectedVolume);
|
|
|
|
// this call will resend the graphic well size to the engines
|
|
// in case the windows was resized
|
|
m_pDfrgCtl->SizeGraphicsWindow();
|
|
|
|
// tell the user of this listview that it's time to redraw
|
|
m_pDfrgCtl->InvalidateGraphicsWindow();
|
|
#ifdef ESI_PROGRESS_BAR
|
|
m_pDfrgCtl->InvalidateProgressBar();
|
|
#endif
|
|
m_pDfrgCtl->SetButtonState();
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Process LVN_GETDISPINFO to supply information about callback items.
|
|
case LVN_GETDISPINFO:
|
|
{
|
|
// Message(TEXT("NotifyListView: LVN_GETDISPINFO"), -1, NULL);
|
|
LV_DISPINFO *plvdi = (LV_DISPINFO *)lParam;
|
|
CVolume *pVolume = (CVolume *)(plvdi->item.lParam);
|
|
|
|
// Provide the item or subitem's text, if requested.
|
|
if (plvdi->item.mask & LVIF_TEXT) {
|
|
|
|
// copy the text from the array into the list column
|
|
switch (plvdi->item.iSubItem)
|
|
{
|
|
case 0:
|
|
_tcsnccpy(plvdi->item.pszText, pVolume->DisplayLabel(),
|
|
plvdi->item.cchTextMax);
|
|
break;
|
|
|
|
case 1:
|
|
_tcsnccpy(plvdi->item.pszText, pVolume->sDefragState(),
|
|
plvdi->item.cchTextMax);
|
|
break;
|
|
|
|
case 2:
|
|
_tcsnccpy(plvdi->item.pszText, pVolume->FileSystem(),
|
|
plvdi->item.cchTextMax);
|
|
break;
|
|
|
|
case 3:
|
|
_tcsnccpy(plvdi->item.pszText, pVolume->sCapacity(),
|
|
plvdi->item.cchTextMax);
|
|
break;
|
|
|
|
case 4:
|
|
_tcsnccpy(plvdi->item.pszText, pVolume->sFreeSpace(),
|
|
plvdi->item.cchTextMax);
|
|
break;
|
|
|
|
case 5:
|
|
_tcsnccpy(plvdi->item.pszText, pVolume->sFreeSpacePercent(),
|
|
plvdi->item.cchTextMax);
|
|
break;
|
|
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Process LVN_COLUMNCLICK to sort items by column.
|
|
case LVN_COLUMNCLICK:
|
|
{
|
|
//Message(TEXT("NotifyListView: LVN_COLUMNCLICK"), -1, NULL);
|
|
ListView_SortItems(
|
|
pnm->hdr.hwndFrom,
|
|
ListViewCompareFunc,
|
|
pnm->iSubItem);
|
|
isDescending = !isDescending;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
default:
|
|
{
|
|
TCHAR msg[200];
|
|
wsprintf(msg, L"message Number %d in list view", pnm->hdr.code);
|
|
Message(msg, -1, NULL);
|
|
}
|
|
*/
|
|
|
|
}
|
|
}
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
|
|
DATA STRUCTURES:
|
|
None.
|
|
|
|
GLOBAL VARIABLES:
|
|
HWND m_hwndListView - handle to the List View window.
|
|
|
|
INPUT:
|
|
|
|
RETURN:
|
|
TRUE = success
|
|
FALSE = error
|
|
*/
|
|
|
|
BOOL
|
|
CESIListView::AddListViewItem(
|
|
IN CVolume *pVolume
|
|
)
|
|
{
|
|
if(m_hwndListView == NULL) {
|
|
return TRUE;
|
|
}
|
|
|
|
// Get the current number of items in the list view window
|
|
UINT iItemCount = ListView_GetItemCount(m_hwndListView);
|
|
|
|
// Initialize LV_ITEM members.
|
|
LV_ITEM lvi;
|
|
lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
|
|
lvi.iItem = iItemCount;
|
|
lvi.iSubItem = 0;
|
|
lvi.state = 0;
|
|
lvi.stateMask = 0;
|
|
lvi.pszText = LPSTR_TEXTCALLBACK; // will be populated by the callback
|
|
lvi.cchTextMax = 0;
|
|
if (pVolume->RemovableVolume()){
|
|
lvi.iImage = 1; // removable vol icon
|
|
}
|
|
else {
|
|
lvi.iImage = 0; // fixed vol icon
|
|
}
|
|
|
|
lvi.lParam = (LPARAM) pVolume; // store pointer to volume object
|
|
|
|
if (ListView_InsertItem(m_hwndListView, &lvi) == -1)
|
|
return FALSE;
|
|
|
|
// for (UINT iSubItem = 1; iSubItem < NUM_COLUMNS; iSubItem++)
|
|
// {
|
|
// ListView_SetItemText(m_hwndListView,
|
|
// lvi.iItem,
|
|
// iSubItem,
|
|
// LPSTR_TEXTCALLBACK);
|
|
// }
|
|
|
|
ListView_RedrawItems(m_hwndListView, 0, ListView_GetItemCount(m_hwndListView)-1);
|
|
|
|
return TRUE;
|
|
}
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
|
|
GLOBAL VARIABLES:
|
|
HINSTANCE hInst:
|
|
|
|
INPUT:
|
|
HWND hWnd
|
|
|
|
RETURN:
|
|
None.
|
|
*/
|
|
|
|
BOOL
|
|
CESIListView::DeleteAllListViewItems(void)
|
|
{
|
|
if (IsWindow(m_hwndListView)) {
|
|
|
|
// Delete all the current ListView items.
|
|
if(!ListView_DeleteAllItems(m_hwndListView)) {
|
|
Message(TEXT("DeleteAllListViewItems - ListView_DeleteAllItems."), E_FAIL, 0);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
/*****************************************************************************************************************
|
|
|
|
Specific ListView Functions
|
|
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
|
|
GLOBAL VARIABLES:
|
|
|
|
INPUT:
|
|
None;
|
|
|
|
RETURN:
|
|
True is drives were added to the list, otherwise false.
|
|
*/
|
|
|
|
BOOL CESIListView::GetDrivesToListView(void)
|
|
{
|
|
CVolume *pVolume;
|
|
BOOL bDrivesAdded = FALSE;
|
|
|
|
if (!m_pVolumeList->Refresh()){
|
|
return FALSE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
// loop through all the volumes
|
|
//////////////////////////////////////////////////////////////
|
|
for(UINT i=0; i<m_pVolumeList->GetVolumeCount(); i++){
|
|
|
|
pVolume = m_pVolumeList->GetVolumeAt(i);
|
|
if (pVolume == (CVolume *) NULL)
|
|
continue;
|
|
|
|
// Is this volume no longer available
|
|
// (m_pVolumeList->Refresh() will leave deleted drives for one pass)
|
|
if (pVolume->Deleted()){
|
|
// Find the item and delete.
|
|
int index = FindListViewItem(pVolume);
|
|
if (index > -1) {
|
|
// is the currently selected drive the one we are deleting?
|
|
BOOL bSelectAnotherDrive = FALSE; // in case we delete the current drive
|
|
if(ListView_GetItemState(m_hwndListView, index, LVIS_SELECTED) == LVIS_SELECTED)
|
|
bSelectAnotherDrive = TRUE;
|
|
|
|
// delete this drive
|
|
ListView_DeleteItem(m_hwndListView, index);
|
|
|
|
// select the first drive in the list
|
|
if (bSelectAnotherDrive){
|
|
SelectInitialListViewDrive(NULL);
|
|
}
|
|
}
|
|
|
|
// go to next volume
|
|
continue;
|
|
}
|
|
|
|
// update the display of this volume (this will be TRUE for new volumes)
|
|
if (pVolume->Changed()){
|
|
|
|
// new volume, so add a drive letter to the list
|
|
if (pVolume->New()){
|
|
AddListViewItem(pVolume);
|
|
bDrivesAdded = TRUE;
|
|
//pVolume->New(FALSE); will be set during the next refresh()
|
|
}
|
|
|
|
// Find the item and update the ListView
|
|
int index = FindListViewItem(pVolume);
|
|
if (index > -1){
|
|
ListView_Update(m_hwndListView, index);
|
|
pVolume->Changed(FALSE);
|
|
}
|
|
}
|
|
|
|
// If this volume is being defragged, prompt the user to restart or stop the engine
|
|
if (pVolume->FileSystemChanged() && pVolume->EngineState() == ENGINE_STATE_RUNNING){
|
|
pVolume->AbortEngine();
|
|
}
|
|
}
|
|
|
|
return bDrivesAdded;
|
|
}
|
|
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
|
|
GLOBAL VARIABLES:
|
|
|
|
INPUT:
|
|
None;
|
|
|
|
RETURN:
|
|
None.
|
|
*/
|
|
|
|
void CESIListView::SelectInitialListViewDrive(BOOL * needFloppyWarn)
|
|
{
|
|
LV_ITEM lvi;
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iSubItem = 0;
|
|
CVolume *pVolume;
|
|
|
|
// default don't need to show illegal volume warning
|
|
if (needFloppyWarn != NULL) {
|
|
*needFloppyWarn = FALSE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// What drive letter, if any, was passed in on the command line?
|
|
// The drive letter and a colon are the last 2 chars in the string
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// Get the command line string
|
|
TCHAR *pCommandLine = GetCommandLine();
|
|
Message(TEXT("Command Line:"), -1, pCommandLine);
|
|
|
|
// find the last ":" in the string
|
|
TCHAR *pDriveLetter = wcsrchr(pCommandLine, L':');
|
|
|
|
// was a ":" found?, and was this the last char in the string?
|
|
if (pDriveLetter && *(pDriveLetter+1) == NULL){
|
|
|
|
// move back one character to get the drive letter
|
|
pDriveLetter--;
|
|
|
|
// If not null, then we found a ":"
|
|
if (IsCharAlpha(*pDriveLetter)){
|
|
|
|
TCHAR cDrive = towupper(*pDriveLetter);
|
|
|
|
if (IsValidVolume(cDrive)){
|
|
|
|
// Find that drive in the list
|
|
for (lvi.iItem=0; lvi.iItem < ListView_GetItemCount(m_hwndListView); lvi.iItem++) {
|
|
|
|
// Get the data structure associated with this drive
|
|
ListView_GetItem(m_hwndListView, &lvi);
|
|
|
|
// lparam is a pointer to the data struct
|
|
pVolume = (CVolume *) lvi.lParam;
|
|
|
|
// if a match, hilite that item and set to current drive
|
|
if(cDrive == pVolume->Drive()){
|
|
ListView_SetItemState(m_hwndListView, lvi.iItem, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
|
|
m_pVolumeList->SetCurrentVolume(pVolume);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
// must be an illegal volume - probably a floppy
|
|
else if (needFloppyWarn != NULL) {
|
|
*needFloppyWarn = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// no command line argument, or drive not found
|
|
// so set current drive to first one in the list
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// Get the first item in the list
|
|
lvi.iItem=0;
|
|
ListView_GetItem(m_hwndListView, &lvi);
|
|
|
|
// lparam is a pointer to the data struct
|
|
// use it to set the CurrentDrive index
|
|
pVolume = (CVolume *) lvi.lParam;
|
|
m_pVolumeList->SetCurrentVolume(pVolume);
|
|
|
|
// make that drive the selected drive
|
|
ListView_SetItemState(m_hwndListView, lvi.iItem,
|
|
LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
|
|
}
|
|
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
|
|
GLOBAL VARIABLES:
|
|
|
|
INPUT:
|
|
Address of Volume to find in list
|
|
|
|
RETURN:
|
|
Index of item in list.
|
|
*/
|
|
|
|
int CESIListView::FindListViewItem(CVolume *pVolume)
|
|
{
|
|
// Find the item and update the ListView
|
|
// base the search on the address of the data structure
|
|
// stored in the lParam field
|
|
LV_FINDINFO lvfi;
|
|
lvfi.flags = LVFI_PARAM;
|
|
lvfi.lParam = (LPARAM) pVolume;
|
|
|
|
return ListView_FindItem(m_hwndListView, /*start at beginnig=*/-1, &lvfi);
|
|
}
|
|
|
|
/*****************************************************************************************************************
|
|
|
|
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
|
|
|
|
ROUTINE DESCRIPTION:
|
|
Sets the focus to the list view
|
|
|
|
GLOBAL VARIABLES:
|
|
|
|
INPUT:
|
|
|
|
RETURN:
|
|
*/
|
|
|
|
void CESIListView::SetFocus()
|
|
{
|
|
::SetFocus( m_hwndListView );
|
|
}
|
|
|
|
/****************************************************************************************************************/
|
|
|
|
// ListViewCompareFunc - sorts the list view control. It is a comparison function.
|
|
// Returns a negative value if the first item should precede the
|
|
// second item, a positive value if the first item should
|
|
// follow the second item, and zero if the items are equivalent.
|
|
// lParam1 and lParam2 - pointers to the VOLUME_TEXT struct for that item (row)
|
|
// lParamSort - value specified by the LVM_SORTITEMS message
|
|
// (in this case, the index of the column to sort)
|
|
static int CALLBACK ListViewCompareFunc(
|
|
LPARAM lParam1,
|
|
LPARAM lParam2,
|
|
LPARAM lParamSort)
|
|
{
|
|
LPTSTR lpString1 = NULL, lpString2 = NULL;
|
|
LONGLONG number1, number2;
|
|
int iResult = 1;
|
|
BOOL isNumber = FALSE;
|
|
|
|
CVolume *pVol1 = (CVolume *)lParam1;
|
|
CVolume *pVol2 = (CVolume *)lParam2;
|
|
|
|
if (pVol1 && pVol2)
|
|
{
|
|
switch (lParamSort)
|
|
{
|
|
case 0:
|
|
if (pVol1->Drive())
|
|
number1 = pVol1->Drive();
|
|
else
|
|
number1 = (pVol1->VolumeLabel())[0];
|
|
|
|
if (pVol2->Drive())
|
|
number2 = pVol2->Drive();
|
|
else
|
|
number2 = (pVol2->VolumeLabel())[0];
|
|
|
|
isNumber = TRUE;
|
|
break;
|
|
|
|
case 1:
|
|
lpString1 = pVol1->sDefragState();
|
|
lpString2 = pVol2->sDefragState();
|
|
isNumber = FALSE;
|
|
break;
|
|
|
|
case 2:
|
|
lpString1 = pVol1->FileSystem();
|
|
lpString2 = pVol2->FileSystem();
|
|
isNumber = FALSE;
|
|
break;
|
|
|
|
case 3:
|
|
number1 = pVol1->Capacity();
|
|
number2 = pVol2->Capacity();
|
|
isNumber = TRUE;
|
|
break;
|
|
|
|
case 4:
|
|
number1 = pVol1->FreeSpace();
|
|
number2 = pVol2->FreeSpace();
|
|
isNumber = TRUE;
|
|
break;
|
|
|
|
case 5:
|
|
number1 = (LONGLONG) pVol1->FreeSpacePercent();
|
|
number2 = (LONGLONG) pVol2->FreeSpacePercent();
|
|
isNumber = TRUE;
|
|
break;
|
|
|
|
default:
|
|
Message(TEXT("ListViewCompareFunc: Unrecognized column number"), E_FAIL, 0);
|
|
break;
|
|
}
|
|
|
|
if (isNumber){
|
|
if (number1 < number2)
|
|
iResult = -1;
|
|
else if (number1 > number2)
|
|
iResult = 1;
|
|
else
|
|
iResult = 0;
|
|
}
|
|
else{
|
|
iResult = lstrcmpi(lpString1, lpString2);
|
|
}
|
|
|
|
//Now, if the strings are equal, compare the cDisplayLabel fields
|
|
if (!iResult)
|
|
iResult = lstrcmpi(pVol1->DisplayLabel(), pVol2->DisplayLabel());
|
|
|
|
if (isDescending)
|
|
iResult = -iResult;
|
|
}
|
|
|
|
return iResult;
|
|
}
|