windows-nt/Source/XPSP1/NT/base/fs/utils/dfrg/dfrgui/dlgrpt.cpp
2020-09-26 16:20:57 +08:00

2966 lines
96 KiB
C++

//=============================================================================*
// COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
//=============================================================================*
// File: DlgRpt.cpp
//=============================================================================*
#include "stdafx.h"
#ifndef SNAPIN
#ifndef NOWINDOWSH
#include <windows.h>
#endif
#endif
#include "commdlg.h"
#include <commctrl.h>
#include <shlobj.h> // for SHGetSpecialFolderLocation()
#include "DfrgUI.h"
#include "DfrgCmn.h"
#include "DfrgCtl.h"
#include "DlgRpt.h"
#include "GetDfrgRes.h"
#include "DfrgHlp.h"
#include "TextBlock.h"
#include "VolList.h"
#include <locale.h>
#include "expand.h"
#define MAX_FRAGGED_FILE_COLUMNS 3
#define MAX_VOLUME_INFO_COLUMNS 3
static CVolume *pLocalVolume = NULL;
static HFONT hDlgFont;
static RECT rcButtonClose;
static RECT rcButtonDefrag;
static RECT rcButtonSave;
static RECT rcButtonPrint;
static RECT rButton;
static RECT rcOriginalDialogSize;
static RECT rcNewDialogSize;
static UINT minimumDialogWidth;
static UINT minimumDialogHeight;
static UINT maximumDialogWidth;
static UINT maximumDialogHeight;
static UINT totalButtonWidth;
static UINT m_ButtonTopBottomSpacer;
static UINT m_ButtonHeight;
static UINT m_ButtonWidth;
static UINT m_ButtonSpacer;
static UINT m_Margin;
static UINT m_ButtonFloat;
static UINT adjustedButtonWidthClose;
static UINT adjustedButtonWidthDefrag;
static UINT adjustedButtonWidthSave;
static UINT adjustedButtonWidthPrint;
static UINT uEditBoxWidth;
static UINT uEditBoxHeight;
static UINT adjustedButtonHeight;
static UINT wNormalHeight; // height of reduced dialog box (which
// extends just past the ID_MORE button vertically)
static UINT wExpandedHeight; // height of full size dialog box
static BOOL fExpanded = FALSE;
static UINT uFontHeight;
static UINT uVolumeListViewWidth;
//structure for the buttons
typedef struct{
TCHAR m_buttonText[200];
TCHAR m_buttonHelp[200];
BOOL m_buttonVisible;
} GENERICBUTTONARRAY;
static GENERICBUTTONARRAY genericButtonArray[5];
static BOOL
InitializeReport(
IN HWND hWndDialog
);
static BOOL
WriteTextReportInMemory(
CTextBlock &textBlock,
DWORD dwFlags
);
static UINT
WriteTextReportListView(
IN HWND hWndDialog,
IN CTextBlock &textBlock,
IN DWORD dwFlags
);
static void
InitializeFragListView(
IN HWND hWndDialog
);
static void
InitializeVolumeListView(
IN HWND hWndDialog
);
//Prints the text report and most fragged list on a printer.
static BOOL
PrintDriveData(
IN HWND hWndDialog
);
//Saves the text report and most fragged list to a text file.
static BOOL
SaveDriveData(
IN HWND hWndDialog
);
static void
InsertListViewItems(
IN HWND hWndDialog,
CVolume *pLocalVolume
);
static UINT
InsertVolumeListViewItems(
IN HWND hWndDialog, IN UINT iListItemNumber, IN UINT resourceIDText, IN UINT resourceIDSeperator,
IN TCHAR* pTextStr, BOOL bIndentText, UINT uLongestTextString
);
static UINT
InsertVolumeListViewItems(
IN HWND hWndDialog, IN UINT iListItemNumber, IN TCHAR* itemOneText, IN UINT resourceIDSeperator,
IN TCHAR* pTextStr, BOOL bIndentText, UINT uLongestTextString
);
static UINT
InsertVolumeListViewItems(
IN HWND hWndDialog, IN UINT iListItemNumber, IN UINT resourceIDText, IN UINT resourceIDSeperator,
IN TCHAR* pTextStr, IN UINT resourceIDPercent, BOOL bIndentText, UINT uLongestTextString
);
TCHAR*
InsertCommaIntoText(
IN TCHAR* stringBuffer
);
static void
ExitReport(
IN HWND hWndDialog
);
static BOOL CALLBACK
ReportDialogProc(
IN HWND hWndDialog,
IN UINT uMessage,
IN WPARAM wParam,
IN LPARAM lParam
);
//resize stuff
void SetButtonsandIcon(HWND hWndDialog);
void PositionButton(RECT* prcPos, HWND hWndDialog);
void PositionControls(HWND hWndDialog, RECT rDlg);
void GetButtonDimensions(HWND hWndDialog, BOOL bIsAnalysisReport);
void PositionButtons(HWND hWndDialog, RECT rDlg, BOOL bIsAnalysisReport);
UINT GetStringWidth(PTCHAR stringBuf, HDC WorkDC);
void ResizeDialog(HWND hWndDialog);
static UINT FindMaxEditboxStringWidth(VString vstring);
static UINT FindMaxEditboxStringHeight(VString vstring);
static void
ResizeVolumeListViewColumns(
IN HWND hWndDialog, IN UINT uWidthFirstColumn,
IN UINT uWidthSecondColumn, IN UINT uWidthThirdColumn);
// Creates a text report that can be dumped to the screen or file, or printer, etc.
// Passed into CreateTextReportInMemory to tell it what type of report to generate.
#define TEXT_REPORT 1
#define MOST_FRAGGED_REPORT 2
#define NULL_TERMINATE_REPORT 4
#define ASCII_REPORT 8
#define UNICODE_REPORT 16
#define CR_LF_REPORT 32
#define ADD_TABS_REPORT 64
#define PRINT_DEFRAG_TITLE 128
static BOOL
CreateTextReportInMemory(
CTextBlock &textBlock,
DWORD dwFlags = NULL
);
static BOOL
WriteFraggedReportInMemory(
CTextBlock &textBlock,
DWORD dwFlags
);
static BOOL isDescending = TRUE; // used by sort routine
// prototype for the list sort function
static int CALLBACK ListViewCompareFunc(
LPARAM lParam1,
LPARAM lParam2,
LPARAM lParamSort);
LONGLONG checkForNegativeValues(
LONGLONG lldatavalue
);
/*****************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
Raises the Defrag Report dialog
GLOBAL VARIABLES:
None
INPUT:
IN pLocalVolume - address of volume that has just completed Analyzing
RETURN:
TRUE - Worked OK
FALSE - Failure
*/
BOOL RaiseReportDialog(
CVolume *pVolume
)
{
LPCTSTR lpTemplateName;
pLocalVolume = pVolume;
isDescending = FALSE;
m_ButtonTopBottomSpacer = 12;
m_ButtonHeight = 26;
m_ButtonWidth = 84;
m_ButtonSpacer = 16;
m_Margin = 20;
m_ButtonFloat = 20;
minimumDialogWidth = 275;
minimumDialogHeight = 330;
// minimumNumberOfCaractersWide = 40;
// minimumNumberOfLinesLong = 2;
if (pLocalVolume->DefragMode() == ANALYZE){
lpTemplateName = MAKEINTRESOURCE(IDD_ANALYSIS_REPORT);
}
else {
lpTemplateName = MAKEINTRESOURCE(IDD_DEFRAG_REPORT);
}
INT_PTR ret = DialogBoxParam(
GetDfrgResHandle(),
lpTemplateName,
pLocalVolume->m_pDfrgCtl->m_hWndCD,
(DLGPROC)ReportDialogProc,
pLocalVolume->DefragMode());
if (ret == -1){
Message(TEXT("RaiseReportDialog - DialogBoxParam"), GetLastError(), TEXT("RaiseReportDialog"));
return FALSE;
}
return TRUE;
}
/********************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
The Report dialog callback
GLOBAL VARIABLES:
hFauItems
dwFragListSize
hFragFile
INPUT:
IN HWND hWndDialog, - handle to dialog
IN UINT uMessage, - window message
IN WPARAM wParam, - message flags
IN LPARAM lParam - message flags
RETURN:
TRUE - processed message
FALSE - message not processed.
*/
static BOOL CALLBACK
ReportDialogProc(
IN HWND hWndDialog,
IN UINT uMessage,
IN WPARAM wParam,
IN LPARAM lParam
)
{
switch(uMessage) {
case WM_INITDIALOG:
if(!InitializeReport(hWndDialog))
ExitReport(hWndDialog);
SetFocus(GetDlgItem(hWndDialog, IDCANCEL));
return FALSE;
break;
case WM_NOTIFY:
switch (((LPNMHDR) lParam)->code) {
// Process LVN_GETDISPINFO to supply information about callback items.
case LVN_GETDISPINFO:
{
Message(TEXT("ReportDialogProc: LVN_GETDISPINFO"), -1, NULL);
LV_DISPINFO* pnmv = (LV_DISPINFO*)lParam;
// Provide the item or subitem's text, if requested.
if (pnmv->item.mask & LVIF_TEXT) {
CFraggedFile *pFraggedFile = (CFraggedFile *) pnmv->item.lParam;
// copy the text from the array into the list column
switch (pnmv->item.iSubItem)
{
case 0:
_tcsnccpy(pnmv->item.pszText, pFraggedFile->cExtentCount(),
pnmv->item.cchTextMax);
break;
case 1:
_tcsnccpy(pnmv->item.pszText, pFraggedFile->cFileSize(),
pnmv->item.cchTextMax);
break;
case 2:
// if path is too long, truncate it and use elipse
if (pFraggedFile->FileNameLen() >= pnmv->item.cchTextMax) {
_tcsnccpy(pnmv->item.pszText, TEXT("\\..."), pnmv->item.cchTextMax);
_tcsnccat(pnmv->item.pszText,
pFraggedFile->FileNameTruncated(pnmv->item.cchTextMax - 5),
pnmv->item.cchTextMax);
}
// otherwise use full path
else {
_tcsnccpy(pnmv->item.pszText, pFraggedFile->FileName(),
pnmv->item.cchTextMax);
}
break;
}
}
break;
}
// Process LVN_COLUMNCLICK to sort items by column.
case LVN_COLUMNCLICK:
{
Message(TEXT("ReportDialogProc: LVN_COLUMNCLICK"), -1, NULL);
NM_LISTVIEW *pnm = (NM_LISTVIEW *) lParam;
ListView_SortItems(
pnm->hdr.hwndFrom,
ListViewCompareFunc,
(LPARAM) pnm->iSubItem);
isDescending = !isDescending;
break;
}
}
break;
case WM_CLOSE:
ExitReport(hWndDialog);
break;
case WM_COMMAND:
switch(LOWORD(wParam)) {
case IDC_VOLUME_INFORMATION:
{
//
// Don't select all of the text in the edit
// control.
//
if ( HIWORD( wParam ) == EN_SETFOCUS )
SendMessage( (HWND) lParam, EM_SETSEL, 0, 0 );
}
break;
case IDC_PRINT:
PrintDriveData(hWndDialog);
break;
case IDC_SAVE:
SaveDriveData(hWndDialog);
break;
case IDC_DEFRAGMENT:
pLocalVolume->Defragment();
ExitReport(hWndDialog);
break;
case IDCANCEL:
ExitReport(hWndDialog);
break;
case IDHELP:
// WinHelp (hWndDialog, cHelpFileName, HELP_CONTEXT, 65);
break;
default:
return FALSE;
}
break;
case WM_HELP:
switch((int)((LPHELPINFO)lParam)->iCtrlId){
case IDC_EDITBOX_TEXT:
case IDC_VOLUME_INFORMATION_TEXT:
case IDC_MOST_FRAGMENTED_TEXT:
break;
default:
{
HWND hHelpHandle = (HWND)((LPHELPINFO)lParam)->hItemHandle;
DWORD_PTR dwData;
if(pLocalVolume->DefragMode() == ANALYZE){
dwData = (DWORD_PTR) AnalysisRptHelpIDArray;
}
else{
dwData = (DWORD_PTR) DefragRptHelpIDArray;
}
EF(WinHelp(hHelpHandle, GetHelpFilePath(), HELP_WM_HELP, dwData));
break;
}
}
break;
case WM_CONTEXTMENU:
{
switch(GetDlgCtrlID((HWND)wParam)){
case 0:
EH(FALSE);
break;
case IDC_EDITBOX_TEXT:
case IDC_VOLUME_INFORMATION_TEXT:
case IDC_MOST_FRAGMENTED_TEXT:
break;
default:
if(pLocalVolume->DefragMode() == ANALYZE){
EF(WinHelp (hWndDialog, GetHelpFilePath(), HELP_CONTEXTMENU, (DWORD_PTR)AnalysisRptHelpIDArray));
}
else{
EF(WinHelp (hWndDialog, GetHelpFilePath(), HELP_CONTEXTMENU, (DWORD_PTR)DefragRptHelpIDArray));
}
}
}
break;
default:
return FALSE;
}
return TRUE;
}
/****************************************************************************************************************/
// 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 REPORT_FRAGGED_FILE_DATA struct for that item (row)
// lParamSort - 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;
CFraggedFile *pRec1 = (CFraggedFile *)lParam1;
CFraggedFile *pRec2 = (CFraggedFile *)lParam2;
if (pRec1 && pRec2)
{
switch (lParamSort)
{
case 0:
number1 = pRec1->ExtentCount();
number2 = pRec2->ExtentCount();
isNumber = TRUE;
break;
case 1:
number1 = pRec1->FileSize();
number2 = pRec2->FileSize();
isNumber = TRUE;
break;
case 2:
lpString1 = pRec1->FileName();
lpString2 = pRec2->FileName();
isNumber = FALSE;
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{
if (lpString1 && lpString2) {
iResult = lstrcmpi(lpString1, lpString2);
}
}
if (isDescending)
iResult = -iResult;
}
return iResult;
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This function initializes data for the report dialog box
DATA STRUCTURES:
None.
GLOBALS:
hFauItems
hFragFile
dwFragListSize
INPUT:
hWndDialog - handle to the dialog box
RETURN:
None.
*/
static BOOL
InitializeReport(
IN HWND hWndDialog
)
{
RECT rDlg;
// set up the font
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);
setlocale(LC_ALL, ".OCP");
//get the maximum size of the screen
maximumDialogWidth = GetSystemMetrics(SM_CXFULLSCREEN);
maximumDialogHeight = GetSystemMetrics(SM_CYFULLSCREEN);
::SystemParametersInfo (SPI_GETNONCLIENTMETRICS, sizeof (ncm), &ncm, 0);
ncm.lfStatusFont.lfWeight = FW_NORMAL;
InitializeVolumeListView(hWndDialog);
// hDlgFont = ::CreateFontIndirect(&ncm.lfStatusFont);
hDlgFont = ::CreateFontIndirect(&ncm.lfMessageFont);
SendDlgItemMessage(hWndDialog, IDC_EDITBOX_TEXT, WM_SETFONT, (WPARAM) hDlgFont, 0L);
SendDlgItemMessage(hWndDialog, IDC_VOLUME_INFORMATION_TEXT, WM_SETFONT, (WPARAM) hDlgFont, 0L);
SendDlgItemMessage(hWndDialog, IDC_VOLUME_INFORMATION, WM_SETFONT, (WPARAM) hDlgFont, 0L);
SendDlgItemMessage(hWndDialog, IDC_MOST_FRAGMENTED_TEXT, WM_SETFONT, (WPARAM) hDlgFont, 0L);
SendDlgItemMessage(hWndDialog, IDC_MOST_FRAGMENTED, WM_SETFONT, (WPARAM) hDlgFont, 0L);
SendDlgItemMessage(hWndDialog, IDC_PRINT, WM_SETFONT, (WPARAM) hDlgFont, 0L);
SendDlgItemMessage(hWndDialog, IDC_SAVE, WM_SETFONT, (WPARAM) hDlgFont, 0L);
SendDlgItemMessage(hWndDialog, IDCANCEL, WM_SETFONT, (WPARAM) hDlgFont, 0L);
if(pLocalVolume->DefragMode() == ANALYZE)
{
SendDlgItemMessage(hWndDialog, IDC_DEFRAGMENT, WM_SETFONT, (WPARAM) hDlgFont, 0L);
}
// set the title of the dialog box
UINT titleTextID;
if(pLocalVolume->DefragMode() == ANALYZE){
titleTextID = IDS_ANALYSIS_REPORT_TITLE;
// also set the font of the defrag button
//SendDlgItemMessage(hWndDialog, IDC_DEFRAGMENT, WM_SETFONT, (WPARAM) hDlgFont, 0L);
}
else{
titleTextID = IDS_DEFRAG_REPORT_TITLE;
}
VString titleText(titleTextID, GetDfrgResHandle());
EF(SetWindowText(hWndDialog, titleText.GetBuffer()));
CTextBlock textBlock;
// Create a text report in memory that we can dump to the screen.
// EF(CreateTextReportInMemory(textBlock, ADD_TABS_REPORT));
// set the tab stops for the Volume information list view
UINT tabStopArray[3] = {15, 180, 190}; // 1=label, 2=equal sign
// EF(SendDlgItemMessage(hWndDialog, IDC_VOLUME_INFORMATION,
// EM_SETTABSTOPS, (WPARAM) 3, (LPARAM)tabStopArray));
// Write the report to the edit control.
// SetDlgItemText(hWndDialog, IDC_VOLUME_INFORMATION, textBlock.GetBuffer());
InitializeFragListView(hWndDialog);
InsertListViewItems(hWndDialog, pLocalVolume);
//what is the longest string loaded in the volume list view
UINT uLongestTextString = 0;
uLongestTextString = WriteTextReportListView(hWndDialog,textBlock, ADD_TABS_REPORT);
//calulate the Width of the Volume Information Columns and adjust
UINT uWidthFirstColumn = uLongestTextString * uFontHeight / 2;
UINT uWidthSecondColumn = 3 * uFontHeight / 2;
UINT uWidthThirdColumn = 12 * uFontHeight / 2;
uLongestTextString += 15; //add the length of the other two colums max should be 15
UINT uWidthOfVolumeListBox = uLongestTextString * uFontHeight / 2;
ResizeVolumeListViewColumns(hWndDialog, uWidthFirstColumn, uWidthSecondColumn, uWidthThirdColumn);
VString label1;
if(pLocalVolume->DefragMode() == ANALYZE){
// write the Analysis Complete text in the dialog
VString dlgText(IDS_ANALYSIS_COMPLETE_FOR, GetDfrgResHandle());
dlgText.AddChar(L' ');
dlgText += pLocalVolume->DisplayLabel();
dlgText.AddChar(L'\r');
dlgText.AddChar(L'\n');
if((pLocalVolume->m_TextData.PercentDiskFragged + pLocalVolume->m_TextData.FreeSpaceFragPercent) / 2 > 10){
//If the fragmentation on the disk exceeds 10% fragmentation, then recommend defragging.
label1.LoadString(IDS_LABEL_CHOOSE_DEFRAGMENT, GetDfrgResHandle());
}
else{
//Otherwise tell the user he doesn't need to defragment at this time.
label1.LoadString(IDS_LABEL_NO_CHOOSE_DEFRAGMENT, GetDfrgResHandle());
}
dlgText += label1;
EF(SetDlgItemText(hWndDialog, IDC_EDITBOX_TEXT, dlgText.GetBuffer()));
}
else{
TCHAR cString[200];
label1.LoadString(IDS_DEFRAG_REPORT_FOR, GetDfrgResHandle());
wsprintf(cString, TEXT("%s %s"),
label1.GetBuffer(),
pLocalVolume->DisplayLabel());
EF(SetDlgItemText(hWndDialog, IDC_EDITBOX_TEXT, cString));
SetFocus(GetDlgItem(hWndDialog, IDCANCEL));
}
//I have created the dialog, now it is time to make the size correct
//I am sizing it by calculating the size of the volume information listview
//and the size of the buttons and comparing that to the default size and taking
//the largest value.
//first calculate the list view width
uFontHeight = -ncm.lfMessageFont.lfHeight;
uVolumeListViewWidth = uLongestTextString * uFontHeight / 2; //the width of the list view in pixels
//second calculate the width of the buttons
if(pLocalVolume->DefragMode() == ANALYZE)
{
GetButtonDimensions(hWndDialog, TRUE);
} else
{
GetButtonDimensions(hWndDialog, FALSE);
}
//now decide which one is bigger
if(minimumDialogWidth < totalButtonWidth)
{
minimumDialogWidth = totalButtonWidth;
}
if(minimumDialogWidth < uVolumeListViewWidth)
{
minimumDialogWidth = uVolumeListViewWidth;
}
//calculate the final Height and Width of things
//now we can move everything around and make it look cool...
GetWindowRect(hWndDialog, &rDlg);
//calculate to final size of the dialog and adjust if necessary
UINT dialogBoxFinalWidth = rDlg.right - rDlg.left;// + 3 * m_Margin + iconSize;
minimumDialogHeight = (16 * dialogBoxFinalWidth) /10;
UINT dialogBoxFinalHeight = rDlg.bottom - rDlg.top;
dialogBoxFinalWidth = __max(dialogBoxFinalWidth,minimumDialogWidth);
dialogBoxFinalHeight = __max(dialogBoxFinalHeight,minimumDialogHeight);
//check to see if the dialogBoxFinalWidth/Height is greater than the screen and adjust
dialogBoxFinalWidth = __min(dialogBoxFinalWidth,maximumDialogWidth);
dialogBoxFinalHeight = __min(dialogBoxFinalHeight,maximumDialogHeight);
//resize the dialog by moving it to make sure that the minimum size is used if necessary
MoveWindow(hWndDialog,rDlg.left,rDlg.top,dialogBoxFinalWidth,dialogBoxFinalHeight, TRUE);
GetWindowRect(hWndDialog, &rDlg);
UINT iNumberofLinesLong = 0;
UINT iNumberofCharactersWide = 0;
//adjust the size of the edit box IDC_EDITBOX_TEXT
TCHAR dlgText[256];
VString dlgString;
GetDlgItemText(hWndDialog, IDC_EDITBOX_TEXT, dlgText, 256);
dlgString += dlgText;
iNumberofCharactersWide = FindMaxEditboxStringWidth(dlgString);
uEditBoxWidth = rDlg.right - rDlg.left - (2 * m_Margin); //if no characters make it the total width
if(iNumberofCharactersWide == 0)
{
iNumberofLinesLong = 1; //and put one line in it
} else
{
iNumberofCharactersWide +=5; //add little extra space
iNumberofLinesLong = FindMaxEditboxStringHeight(dlgString);
}
uEditBoxHeight = (iNumberofLinesLong * uFontHeight * 15) / 10; //the height of editbox in pixels
UINT uHeightOfFont = (uFontHeight * 15) / 10;
UINT uCurrentVerticalSpaceLocation = 0;
//resize the edit box
MoveWindow(GetDlgItem(hWndDialog, IDC_EDITBOX_TEXT), m_Margin, m_ButtonTopBottomSpacer, uEditBoxWidth, uEditBoxHeight, TRUE);
uCurrentVerticalSpaceLocation += m_ButtonTopBottomSpacer + uEditBoxHeight + 5;
//move the dividing line
MoveWindow(GetDlgItem(hWndDialog, IDC_DIVIDE_LINE), m_Margin, uCurrentVerticalSpaceLocation, rDlg.right - rDlg.left - (2 * m_Margin), 2, TRUE);
uCurrentVerticalSpaceLocation += m_ButtonTopBottomSpacer + 2;
//move the Volume Information Text
GetWindowRect(GetDlgItem(hWndDialog, IDC_VOLUME_INFORMATION_TEXT),&rDlg);
MoveWindow(GetDlgItem(hWndDialog, IDC_VOLUME_INFORMATION_TEXT), m_Margin, uCurrentVerticalSpaceLocation, uEditBoxWidth, uHeightOfFont, TRUE);
uCurrentVerticalSpaceLocation += m_ButtonTopBottomSpacer + uHeightOfFont;
//move and resize the Volume Information
GetWindowRect(GetDlgItem(hWndDialog, IDC_VOLUME_INFORMATION),&rDlg);
MoveWindow(GetDlgItem(hWndDialog, IDC_VOLUME_INFORMATION), m_Margin, uCurrentVerticalSpaceLocation, dialogBoxFinalWidth - (2 * m_Margin), ((dialogBoxFinalHeight - (2 * m_Margin)) / 6) , TRUE);
uCurrentVerticalSpaceLocation += m_ButtonTopBottomSpacer + ((dialogBoxFinalHeight - (2 * m_Margin)) / 6);
//move the Most Fragmented Information Text
GetWindowRect(GetDlgItem(hWndDialog, IDC_MOST_FRAGMENTED_TEXT),&rDlg);
MoveWindow(GetDlgItem(hWndDialog, IDC_MOST_FRAGMENTED_TEXT), m_Margin, uCurrentVerticalSpaceLocation, uEditBoxWidth, uHeightOfFont, TRUE);
uCurrentVerticalSpaceLocation += m_ButtonTopBottomSpacer + uHeightOfFont;
//move the Most Fragmented Information
GetWindowRect(GetDlgItem(hWndDialog, IDC_MOST_FRAGMENTED),&rDlg);
MoveWindow(GetDlgItem(hWndDialog, IDC_MOST_FRAGMENTED), m_Margin, uCurrentVerticalSpaceLocation, dialogBoxFinalWidth - (2 * m_Margin), ((dialogBoxFinalHeight - (2 * m_Margin)) / 4), TRUE);
uCurrentVerticalSpaceLocation += m_ButtonTopBottomSpacer + ((dialogBoxFinalHeight - (2 * m_Margin)) / 4);
//calculate the new dialogBoxFinalHeight based on the size of the controls
//don't forget the title bar estimated to be (2 * uHeightOfFont)
dialogBoxFinalHeight = //__min((UINT)dialogBoxFinalHeight,
uCurrentVerticalSpaceLocation + (2 * uHeightOfFont) + (2 * m_ButtonTopBottomSpacer) + m_ButtonHeight;
//resize the dialog box
GetWindowRect(hWndDialog,&rDlg);
MoveWindow(hWndDialog,rDlg.left,rDlg.top,dialogBoxFinalWidth,dialogBoxFinalHeight, TRUE);
GetWindowRect(hWndDialog,&rDlg);
if(pLocalVolume->DefragMode() == ANALYZE)
{
PositionButtons(hWndDialog, rDlg, TRUE);
} else
{
PositionButtons(hWndDialog, rDlg, FALSE);
}
return TRUE;
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This will write a report telling how many fragmented files are on the drive, etc., into a memory buffer.
DATA STRUCTURES:
None.
GLOBALS:
INPUT:
hText - The handle to the memory to write the report to.
pText - A pointer to the same.
pTextEnd - A pointer to the end of the buffer.
dwFlags - Contains flags specifying how to generate the report, (unicode vs. ascii, and cr lf instead of newline.)
RETURN:
TRUE - Success.
FALSE - Fatal error.
*/
static BOOL
WriteTextReportInMemory(
CTextBlock &textBlock,
DWORD dwFlags
)
{
setlocale(LC_ALL, ".OCP");
// Get a pointer to the text data structure.
TEXT_DATA *pTextData = &(pLocalVolume->m_TextData);
// check all the values of textdata to make sure no negative values
//to fix bug number 35764
pTextData->DiskSize = checkForNegativeValues(pTextData->DiskSize);
pTextData->BytesPerCluster = checkForNegativeValues(pTextData->BytesPerCluster);
pTextData->UsedSpace = checkForNegativeValues(pTextData->UsedSpace);
pTextData->FreeSpace = checkForNegativeValues(pTextData->FreeSpace);
pTextData->FreeSpacePercent = checkForNegativeValues(pTextData->FreeSpacePercent);
pTextData->UsableFreeSpace = checkForNegativeValues(pTextData->UsableFreeSpace);
pTextData->UsableFreeSpacePercent = checkForNegativeValues(pTextData->UsableFreeSpacePercent);
pTextData->PagefileBytes = checkForNegativeValues(pTextData->PagefileBytes);
pTextData->PagefileFrags = checkForNegativeValues(pTextData->PagefileFrags);
pTextData->TotalDirectories = checkForNegativeValues(pTextData->TotalDirectories);
pTextData->FragmentedDirectories = checkForNegativeValues(pTextData->FragmentedDirectories);
pTextData->ExcessDirFrags = checkForNegativeValues(pTextData->ExcessDirFrags);
pTextData->TotalFiles = checkForNegativeValues(pTextData->TotalFiles);
pTextData->AvgFileSize = checkForNegativeValues(pTextData->AvgFileSize);
pTextData->NumFraggedFiles = checkForNegativeValues(pTextData->NumFraggedFiles);
pTextData->NumExcessFrags = checkForNegativeValues(pTextData->NumExcessFrags);
pTextData->PercentDiskFragged = checkForNegativeValues(pTextData->PercentDiskFragged);
pTextData->AvgFragsPerFile = checkForNegativeValues(pTextData->AvgFragsPerFile);
pTextData->MFTBytes = checkForNegativeValues(pTextData->MFTBytes);
pTextData->InUseMFTRecords = checkForNegativeValues(pTextData->InUseMFTRecords);
pTextData->TotalMFTRecords = checkForNegativeValues(pTextData->TotalMFTRecords);
pTextData->MFTExtents = checkForNegativeValues(pTextData->MFTExtents);
pTextData->FreeSpaceFragPercent = checkForNegativeValues(pTextData->FreeSpaceFragPercent);
// set up the text block
textBlock.SetResourceHandle(GetDfrgResHandle());
// if no tabs, then set the fixed columns
if (dwFlags & ADD_TABS_REPORT){
textBlock.SetUseTabs(TRUE);
}
else{
textBlock.SetFixedColumnWidth(TRUE);
textBlock.SetColumnCount(5);
textBlock.SetColumnWidth(0, 4); // spacer
textBlock.SetColumnWidth(1, 43); // label
textBlock.SetColumnWidth(2, 2); // equal sign
textBlock.SetColumnWidth(3, 1); // data
textBlock.SetColumnWidth(4, 2); // percent sign
}
textBlock.SetUseCRLF(TRUE);
// print the title
if (dwFlags & PRINT_DEFRAG_TITLE){
textBlock.WriteToBuffer(IDS_PRODUCT_NAME);
textBlock.EndOfLine();
textBlock.EndOfLine();
}
// write out the display label (usually the drive letter/label)
textBlock.WriteToBuffer(IDS_LABEL_VOLUME);
textBlock.WriteToBuffer(L" %s", pLocalVolume->DisplayLabel());
textBlock.EndOfLine();
// if there are >1 mount points, print them all out
// yes, this will duplicate the same as the display label
// refresh the mount point list
#ifndef VER4
pLocalVolume->GetVolumeMountPointList();
if (pLocalVolume->MountPointCount() > 1){
for (UINT i=0; i<pLocalVolume->MountPointCount(); i++){
textBlock.WriteToBuffer(IDS_MOUNTED_VOLUME);
textBlock.WriteToBuffer(L": %s", pLocalVolume->MountPoint(i));
textBlock.EndOfLine();
}
}
#endif
///////////////////////////////////////////////////////////////////////////
// Volume Size
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_VOLUME_SIZE);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteByteCount(pTextData->DiskSize);
textBlock.EndOfLine();
// Cluster Size
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_CLUSTER_SIZE);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteByteCount(pTextData->BytesPerCluster);
textBlock.EndOfLine();
// Used Space
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_USED_SPACE);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteByteCount(pTextData->UsedSpace);
textBlock.EndOfLine();
// Free Space
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_FREE_SPACE);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteByteCount(pTextData->FreeSpace);
textBlock.EndOfLine();
// % Free Space
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_PERCENT_FREE_SPACE);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteToBuffer(L"%d ", (UINT) pTextData->FreeSpacePercent);
textBlock.WriteToBuffer(IDS_LABEL_PERCENT_SIGN);
textBlock.EndOfLine();
// Volume Fragmentation Header
textBlock.EndOfLine();
textBlock.WriteToBuffer(IDS_LABEL_VOLUME_FRAGMENTATION_HEADING);
textBlock.EndOfLine();
// % Total Fragmentation
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_TOTAL_FRAGMENTATION);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteToBuffer(L"%d ", (UINT) (pTextData->PercentDiskFragged + pTextData->FreeSpaceFragPercent) / 2);
textBlock.WriteToBuffer(IDS_LABEL_PERCENT_SIGN);
textBlock.EndOfLine();
// % File Fragmentation
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_FILE_FRAGMENTATION);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteToBuffer(L"%d ", (UINT) pTextData->PercentDiskFragged);
textBlock.WriteToBuffer(IDS_LABEL_PERCENT_SIGN);
textBlock.EndOfLine();
// % Free Space Fragmentation
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_FREE_SPACE_FRAGMENTATION);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteToBuffer(L"%d ", (UINT) pTextData->FreeSpaceFragPercent);
textBlock.WriteToBuffer(IDS_LABEL_PERCENT_SIGN);
textBlock.EndOfLine();
// File Fragmentation Header
textBlock.EndOfLine();
textBlock.WriteToBuffer(IDS_LABEL_FILE_FRAGMENTATION_HEADING);
textBlock.EndOfLine();
// Total Files
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_TOTAL_FILES);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
//textBlock.WriteToBuffer(L"%d", pTextData->TotalFiles);
textBlock.WriteToBufferLL(pTextData->TotalFiles);
textBlock.EndOfLine();
// Average Files Size
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_AVERAGE_FILE_SIZE);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteByteCount(pTextData->AvgFileSize);
textBlock.EndOfLine();
// Total fragmented files
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_TOTAL_FRAGMENTED_FILES);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
//textBlock.WriteToBuffer(L"%d", pTextData->NumFraggedFiles);
textBlock.WriteToBufferLL(pTextData->NumFraggedFiles);
textBlock.EndOfLine();
// Total excess fragments
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_TOTAL_EXCESS_FRAGMENTS);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
//textBlock.WriteToBuffer(L"%d", pTextData->NumExcessFrags);
textBlock.WriteToBufferLL(pTextData->NumExcessFrags);
textBlock.EndOfLine();
// Average Fragments per File (CHECK THE MATH AND THE UNITS ON THIS ONE!!!)
struct lconv *locals = localeconv();
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_AVERAGE_FRAGMENTS_PER_FILE);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteToBuffer(L"%d%c%02d",
(UINT)pTextData->AvgFragsPerFile/100,
((locals && (locals->decimal_point)) ? *(locals->decimal_point) : '.'),
(UINT)pTextData->AvgFragsPerFile%100);
textBlock.EndOfLine();
// Pagefile Fragmentation Header
textBlock.EndOfLine();
textBlock.WriteToBuffer(IDS_LABEL_PAGEFILE_FRAGMENTATION_HEADING);
textBlock.EndOfLine();
// Pagefile Size
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_PAGEFILE_SIZE);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteByteCount(pTextData->PagefileBytes);
textBlock.EndOfLine();
// Total Fragments
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_TOTAL_FRAGMENTS);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
//textBlock.WriteToBuffer(L"%d", pTextData->PagefileFrags);
textBlock.WriteToBufferLL(pTextData->PagefileFrags);
textBlock.EndOfLine();
// Directory Fragmentation Header
textBlock.EndOfLine();
textBlock.WriteToBuffer(IDS_LABEL_DIRECTORY_FRAGMENTATION_HEADING);
textBlock.EndOfLine();
// Total Directories
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_TOTAL_DIRECTORIES);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
//textBlock.WriteToBuffer(L"%d", pTextData->TotalDirectories);
textBlock.WriteToBufferLL(pTextData->TotalDirectories);
textBlock.EndOfLine();
// Fragmented Directories
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_FRAGMENTED_DIRECTORIES);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
//textBlock.WriteToBuffer(L"%d", pTextData->FragmentedDirectories);
textBlock.WriteToBufferLL(pTextData->FragmentedDirectories);
textBlock.EndOfLine();
// Excess directory fragments
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EXCESS_DIRECTORY_FRAGMENTS);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
//textBlock.WriteToBuffer(L"%d", pTextData->ExcessDirFrags);
textBlock.WriteToBufferLL(pTextData->ExcessDirFrags);
textBlock.EndOfLine();
//Only display MFT data if this is an NTFS drive.
if(wcscmp(pLocalVolume->FileSystem(), L"NTFS") == 0){
// MFT Fragmentation Header
textBlock.EndOfLine();
textBlock.WriteToBuffer(IDS_LABEL_MFT_FRAGMENTATION_HEADING);
textBlock.EndOfLine();
// Total MFT Size
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_TOTAL_MFT_SIZE);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteByteCount(pTextData->MFTBytes);
textBlock.EndOfLine();
// Number of MFT records
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_MFT_RECORD_COUNT);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteToBufferLL(pTextData->InUseMFTRecords);
textBlock.EndOfLine();
// Percent of MFT in use
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_PERCENT_MFT_IN_USE);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteToBuffer(L"%d ", (UINT) (100*pTextData->InUseMFTRecords/pTextData->TotalMFTRecords));
textBlock.WriteToBuffer(IDS_LABEL_PERCENT_SIGN);
textBlock.EndOfLine();
// Total MFT fragments
textBlock.WriteToBuffer(L"");
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_TOTAL_MFT_FRAGMENTS);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_LABEL_EQUAL_SIGN);
textBlock.WriteTab();
textBlock.WriteToBufferLL(pTextData->MFTExtents);
textBlock.EndOfLine();
}
return TRUE;
}
static UINT
WriteTextReportListView(
IN HWND hWndDialog,
IN CTextBlock &textBlock,
IN DWORD dwFlags
)
{
// Get a pointer to the text data structure.
TEXT_DATA *pTextData = &(pLocalVolume->m_TextData);
TCHAR buffer[256];
TCHAR tempBuffer[256];
UINT uIndexofListView = 0;
//what is the longest string loaded in the volume list view
UINT uLongestTextString = 0;
// check all the values of textdata to make sure no negative values
//to fix bug number 35764
pTextData->DiskSize = checkForNegativeValues(pTextData->DiskSize);
pTextData->BytesPerCluster = checkForNegativeValues(pTextData->BytesPerCluster);
pTextData->UsedSpace = checkForNegativeValues(pTextData->UsedSpace);
pTextData->FreeSpace = checkForNegativeValues(pTextData->FreeSpace);
pTextData->FreeSpacePercent = checkForNegativeValues(pTextData->FreeSpacePercent);
pTextData->UsableFreeSpace = checkForNegativeValues(pTextData->UsableFreeSpace);
pTextData->UsableFreeSpacePercent = checkForNegativeValues(pTextData->UsableFreeSpacePercent);
pTextData->PagefileBytes = checkForNegativeValues(pTextData->PagefileBytes);
pTextData->PagefileFrags = checkForNegativeValues(pTextData->PagefileFrags);
pTextData->TotalDirectories = checkForNegativeValues(pTextData->TotalDirectories);
pTextData->FragmentedDirectories = checkForNegativeValues(pTextData->FragmentedDirectories);
pTextData->ExcessDirFrags = checkForNegativeValues(pTextData->ExcessDirFrags);
pTextData->TotalFiles = checkForNegativeValues(pTextData->TotalFiles);
pTextData->AvgFileSize = checkForNegativeValues(pTextData->AvgFileSize);
pTextData->NumFraggedFiles = checkForNegativeValues(pTextData->NumFraggedFiles);
pTextData->NumExcessFrags = checkForNegativeValues(pTextData->NumExcessFrags);
pTextData->PercentDiskFragged = checkForNegativeValues(pTextData->PercentDiskFragged);
pTextData->AvgFragsPerFile = checkForNegativeValues(pTextData->AvgFragsPerFile);
pTextData->MFTBytes = checkForNegativeValues(pTextData->MFTBytes);
pTextData->InUseMFTRecords = checkForNegativeValues(pTextData->InUseMFTRecords);
pTextData->TotalMFTRecords = checkForNegativeValues(pTextData->TotalMFTRecords);
pTextData->MFTExtents = checkForNegativeValues(pTextData->MFTExtents);
pTextData->FreeSpaceFragPercent = checkForNegativeValues(pTextData->FreeSpaceFragPercent);
//Only display MFT data if this is an NTFS drive.
if(wcscmp(pLocalVolume->FileSystem(), L"NTFS") == 0)
{
// Total MFT fragments
swprintf(buffer, L"%I64d", pTextData->MFTExtents);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_TOTAL_MFT_FRAGMENTS,
IDS_LABEL_EQUAL_SIGN,InsertCommaIntoText(buffer),TRUE,uLongestTextString);
uIndexofListView++;
// Percent of MFT in use
swprintf(buffer, L"%d", 100*pTextData->InUseMFTRecords/pTextData->TotalMFTRecords);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_PERCENT_MFT_IN_USE,
IDS_LABEL_EQUAL_SIGN,buffer,TRUE,uLongestTextString);
uIndexofListView++;
// Number of MFT records
swprintf(buffer, L"%I64d", pTextData->InUseMFTRecords);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_MFT_RECORD_COUNT,
IDS_LABEL_EQUAL_SIGN,InsertCommaIntoText(buffer),TRUE,uLongestTextString);
uIndexofListView++;
// Total MFT Size
swprintf(buffer, L"%I64d", pTextData->MFTBytes);
InsertCommaIntoText(buffer);
textBlock.FormatNum(GetDfrgResHandle(), pTextData->MFTBytes, buffer);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_TOTAL_MFT_SIZE,
IDS_LABEL_EQUAL_SIGN,buffer,TRUE,uLongestTextString);
uIndexofListView++;
// MFT Fragmentation Header
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_MFT_FRAGMENTATION_HEADING,
NULL,L"",FALSE,uLongestTextString);
uIndexofListView++;
}
// Excess directory fragments
swprintf(buffer, L"%I64d", pTextData->ExcessDirFrags);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_EXCESS_DIRECTORY_FRAGMENTS,
IDS_LABEL_EQUAL_SIGN,InsertCommaIntoText(buffer),TRUE,uLongestTextString);
uIndexofListView++;
// Fragmented Directories
swprintf(buffer, L"%I64d", pTextData->FragmentedDirectories);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_FRAGMENTED_DIRECTORIES,
IDS_LABEL_EQUAL_SIGN,InsertCommaIntoText(buffer),TRUE,uLongestTextString);
uIndexofListView++;
// Total Directories
swprintf(buffer, L"%I64d", pTextData->TotalDirectories);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_TOTAL_DIRECTORIES,
IDS_LABEL_EQUAL_SIGN,InsertCommaIntoText(buffer),TRUE,uLongestTextString);
uIndexofListView++;
// Directory Fragmentation Header
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_DIRECTORY_FRAGMENTATION_HEADING
,NULL,L"",FALSE,uLongestTextString);
uIndexofListView++;
// Total Fragments
swprintf(buffer, L"%I64d", pTextData->PagefileFrags);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_TOTAL_FRAGMENTS,
IDS_LABEL_EQUAL_SIGN,InsertCommaIntoText(buffer),TRUE,uLongestTextString);
uIndexofListView++;
// Pagefile Size
swprintf(buffer, L"%I64d", pTextData->PagefileBytes);
InsertCommaIntoText(buffer);
textBlock.FormatNum(GetDfrgResHandle(), pTextData->PagefileBytes, buffer);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_PAGEFILE_SIZE,
IDS_LABEL_EQUAL_SIGN,buffer,TRUE,uLongestTextString);
uIndexofListView++;
// Pagefile Fragmentation Header
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_PAGEFILE_FRAGMENTATION_HEADING
,NULL,L"",FALSE,uLongestTextString);
uIndexofListView++;
// Average Fragments per File (CHECK THE MATH AND THE UNITS ON THIS ONE!!!)
struct lconv *locals = localeconv();
swprintf(buffer, L"%d%c%02d", (UINT)pTextData->AvgFragsPerFile/100,
((locals && (locals->decimal_point)) ? *(locals->decimal_point) : '.'),
(UINT)pTextData->AvgFragsPerFile%100);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_AVERAGE_FRAGMENTS_PER_FILE,
IDS_LABEL_EQUAL_SIGN,buffer,TRUE,uLongestTextString);
uIndexofListView++;
// Total excess fragments
swprintf(buffer, L"%I64d", pTextData->NumExcessFrags);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_TOTAL_EXCESS_FRAGMENTS,
IDS_LABEL_EQUAL_SIGN,InsertCommaIntoText(buffer),TRUE,uLongestTextString);
uIndexofListView++;
// Total fragmented files
swprintf(buffer, L"%I64d", pTextData->NumFraggedFiles);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_TOTAL_FRAGMENTED_FILES,
IDS_LABEL_EQUAL_SIGN,InsertCommaIntoText(buffer),TRUE,uLongestTextString);
uIndexofListView++;
// Average Files Size
swprintf(buffer, L"%I64d", pTextData->AvgFileSize);
InsertCommaIntoText(buffer);
textBlock.FormatNum(GetDfrgResHandle(), pTextData->AvgFileSize, buffer);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_AVERAGE_FILE_SIZE,
IDS_LABEL_EQUAL_SIGN,buffer,TRUE,uLongestTextString);
uIndexofListView++;
// Total Files
swprintf(buffer, L"%I64d", pTextData->TotalFiles);
InsertCommaIntoText(buffer);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_TOTAL_FILES
,IDS_LABEL_EQUAL_SIGN,buffer,TRUE,uLongestTextString);
uIndexofListView++;
// File Fragmentation Header
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_FILE_FRAGMENTATION_HEADING
,NULL,L"",FALSE,uLongestTextString);
uIndexofListView++;
// % Free Space Fragmentation
swprintf(buffer, L"%d", pTextData->FreeSpaceFragPercent);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_FREE_SPACE_FRAGMENTATION,
IDS_LABEL_EQUAL_SIGN,buffer,IDS_LABEL_PERCENT_SIGN,TRUE,uLongestTextString);
uIndexofListView++;
// % File Fragmentation
swprintf(buffer, L"%d", pTextData->PercentDiskFragged);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_FILE_FRAGMENTATION,
IDS_LABEL_EQUAL_SIGN,buffer,IDS_LABEL_PERCENT_SIGN,TRUE,uLongestTextString);
uIndexofListView++;
// % Total Fragmentation
swprintf(buffer, L"%d", (pTextData->PercentDiskFragged + pTextData->FreeSpaceFragPercent) / 2);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_TOTAL_FRAGMENTATION,
IDS_LABEL_EQUAL_SIGN,buffer,IDS_LABEL_PERCENT_SIGN,TRUE,uLongestTextString);
uIndexofListView++;
// Volume Fragmentation Header
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_VOLUME_FRAGMENTATION_HEADING
,NULL,L"",FALSE,uLongestTextString);
uIndexofListView++;
// % Free Space
swprintf(buffer, L"%d", pTextData->FreeSpacePercent);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_PERCENT_FREE_SPACE,
IDS_LABEL_EQUAL_SIGN,buffer,IDS_LABEL_PERCENT_SIGN,TRUE,uLongestTextString);
uIndexofListView++;
// Free Space
swprintf(buffer, L"%I64d", pTextData->FreeSpace);
InsertCommaIntoText(buffer);
textBlock.FormatNum(GetDfrgResHandle(), pTextData->FreeSpace, buffer);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_FREE_SPACE,IDS_LABEL_EQUAL_SIGN,
buffer,TRUE,uLongestTextString);
uIndexofListView++;
// Used Space
swprintf(buffer, L"%I64d", pTextData->UsedSpace);
InsertCommaIntoText(buffer);
textBlock.FormatNum(GetDfrgResHandle(), pTextData->UsedSpace, buffer);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_USED_SPACE,IDS_LABEL_EQUAL_SIGN,
buffer,TRUE,uLongestTextString);
uIndexofListView++;
// Cluster Size
swprintf(buffer, L"%I64d", pTextData->BytesPerCluster);
InsertCommaIntoText(buffer);
textBlock.FormatNum(GetDfrgResHandle(), pTextData->BytesPerCluster, buffer);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_CLUSTER_SIZE,IDS_LABEL_EQUAL_SIGN,
buffer,TRUE,uLongestTextString);
uIndexofListView++;
///////////////////////////////////////////////////////////////////////////
// Volume Size
swprintf(buffer, L"%I64d", pTextData->DiskSize);
InsertCommaIntoText(buffer);
textBlock.FormatNum(GetDfrgResHandle(), pTextData->DiskSize, buffer);
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_LABEL_VOLUME_SIZE,IDS_LABEL_EQUAL_SIGN,
buffer,TRUE,uLongestTextString);
uIndexofListView++;
// if there are >1 mount points, print them all out
// yes, this will duplicate the same as the display label
// refresh the mount point list
#ifndef VER4
pLocalVolume->GetVolumeMountPointList();
if (pLocalVolume->MountPointCount() > 1){
for (UINT i=0; i<pLocalVolume->MountPointCount(); i++){
LoadString(GetDfrgResHandle(), IDS_MOUNTED_VOLUME, tempBuffer, sizeof(tempBuffer)/sizeof(TCHAR));
swprintf(buffer, L"%s %s", tempBuffer, pLocalVolume->MountPoint(i));
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,buffer,
NULL,L"",FALSE,uLongestTextString);
uIndexofListView++;
}
}
#endif
// write out the display label (usually the drive letter/label)
LoadString(GetDfrgResHandle(), IDS_LABEL_VOLUME, tempBuffer, sizeof(tempBuffer)/sizeof(TCHAR));
swprintf(buffer, L"%s %s", tempBuffer,pLocalVolume->DisplayLabel());
uLongestTextString = InsertVolumeListViewItems(hWndDialog,uIndexofListView,buffer
,NULL,L"",FALSE,uLongestTextString);
uIndexofListView++;
// InsertVolumeListViewItems(hWndDialog,uIndexofListView,IDS_PRODUCT_NAME,NULL,L"",FALSE);
return uLongestTextString;
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This will write the fragmented file list into a memory buffer that can be displayed.
DATA STRUCTURES:
None.
GLOBALS:
INPUT:
hText - The handle to the memory to write the report to.
pText - A pointer to the same.
dwFlags - Contains flags specifying how to generate the report, (unicode vs. ascii, and cr lf instead of newline.)
RETURN:
TRUE - Success.
FALSE - Fatal error.
*/
static BOOL
WriteFraggedReportInMemory(
CTextBlock &textBlock,
DWORD dwFlags
)
{
const colWidth0 = 16;
const colWidth1 = 16;
const colWidth2 = 55;
// set up the text block
textBlock.SetResourceHandle(GetDfrgResHandle());
textBlock.SetUseCRLF(TRUE);
// print the title
if (dwFlags & PRINT_DEFRAG_TITLE){
textBlock.WriteToBuffer(IDS_PRODUCT_NAME);
textBlock.EndOfLine();
// write out the display label (usually the drive letter/label)
textBlock.WriteToBuffer(IDS_LABEL_VOLUME);
textBlock.WriteToBuffer(L" %s", pLocalVolume->DisplayLabel());
textBlock.EndOfLine();
// if there are >1 mount points, print them all out
// yes, this will duplicate the same as the display label
// refresh the mount point list
#ifndef VER4
pLocalVolume->GetVolumeMountPointList();
if (pLocalVolume->MountPointCount() > 1){
for (UINT i=0; i<pLocalVolume->MountPointCount(); i++){
textBlock.WriteToBuffer(IDS_MOUNTED_VOLUME);
textBlock.WriteToBuffer(L": %s", pLocalVolume->MountPoint(i));
textBlock.EndOfLine();
}
}
#endif
textBlock.EndOfLine();
}
else { // otherwise add a dividing line
textBlock.EndOfLine();
textBlock.WriteToBuffer(L"--------------------------------------------------------------------------------");
textBlock.EndOfLine();
}
// if no tabs, then set the fixed columns
if (dwFlags & ADD_TABS_REPORT){
textBlock.SetUseTabs(TRUE);
}
else{
textBlock.SetFixedColumnWidth(TRUE);
textBlock.SetColumnCount(3);
textBlock.SetColumnWidth(0, colWidth0); // fragments
textBlock.SetColumnWidth(1, colWidth1); // file size
textBlock.SetColumnWidth(2, colWidth2); // file name
}
// header
textBlock.WriteToBuffer(IDS_NUM_FRAGMENTS);
textBlock.WriteTab();
textBlock.WriteToBuffer(IDS_FRAGGED_FILESIZE);
textBlock.WriteTab();
if(pLocalVolume->DefragMode() == ANALYZE)
textBlock.WriteToBuffer(IDS_LABEL_MOST_FRAGMENTED_FILE);
else
textBlock.WriteToBuffer(IDS_FILE_NO_DEFRAG);
textBlock.EndOfLine();
//If there are no items in the list, print "None"
if(pLocalVolume->m_FraggedFileList.Size() == 0){
textBlock.WriteToBuffer(IDS_LABEL_NONE);
textBlock.EndOfLine();
}
else{
CFraggedFile *pFraggedFile;
for(UINT i=0; i<pLocalVolume->m_FraggedFileList.Size(); i++){
pFraggedFile = pLocalVolume->m_FraggedFileList.GetAt(i);
// write the data columns
textBlock.WriteToBuffer(pFraggedFile->cExtentCount());
textBlock.WriteTab();
textBlock.WriteToBuffer(pFraggedFile->cFileSize());
textBlock.WriteTab();
if (pFraggedFile->FileNameLen() >= 4 * MAX_PATH) {
textBlock.WriteToBuffer(L"\\...%s", pFraggedFile->FileNameTruncated(4 * MAX_PATH - 5));
}
else {
textBlock.WriteToBuffer(pFraggedFile->FileName());
}
textBlock.EndOfLine();
}
}
return TRUE;
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This function will create a text report that can be dumped into a dialog, saved to a file or printed.
Flags are passed in to determine what type of report should be generated.
Memory is allocated, filled in with the report, and the handle is returned and must be freed by the caller.
DATA STRUCTURES:
GLOBALS:
None.
INPUT:
dwFlags - MOST_FRAGGED_REPORT will create a most fragged list.
NULL_TERMINATE_REPORT will add a null terminator to the end of the report.
ASCII_REPORT will cause the report to be generated in ASCII
UNICODE_REPORT will cause the report to be generated in UNICODE (default).
CR_LF_REPORT will cause carriage returns and line feeds to be placed at the end of each line so
the text can be written to a file.
NO_TABS_REPORT will cause the report to contain spaces rather than tabs. Tabs should be used for a proportional font,
spaces for a fixed font.
***NOTE: Right now, only ASCII_REPORT works and is the default. UNICODE is not implemented yet in this report system.
RETURN:
A handle to the memory containing the report.
*/
static BOOL
CreateTextReportInMemory(
CTextBlock &textBlock,
DWORD dwFlags
)
{
// Create the basic text report that will tell how many fragged files, etc.
WriteTextReportInMemory(textBlock, dwFlags);
if(dwFlags & MOST_FRAGGED_REPORT){
//textBlock.EndOfLine();
//textBlock.WriteToBuffer
// (L"--------------------------------------------------------------------------------");
//textBlock.EndOfLine();
// Create the most fragged file list.
WriteFraggedReportInMemory(textBlock, dwFlags);
}
textBlock.WriteNULL();
return TRUE;
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This function saves the data from the drive report as a text file.
DATA STRUCTURES:
None.
GLOBALS:
INPUT:
RETURN:
None.
*/
static BOOL
SaveDriveData(
IN HWND hWndDialog
)
{
CTextBlock textBlock;
OPENFILENAME ofn = {0};
TCHAR cFile[MAX_PATH + 50];
TCHAR szFilter[300];
TEXT_DATA* pTextData = &(pLocalVolume->m_TextData);
DWORD commError = 0;
BOOL done = FALSE;
VString saveStatsLabel(IDS_LABEL_SAVE_DISK_STATS, GetDfrgResHandle());
VString textFilesLabel(IDS_LABEL_TEXT_FILES, GetDfrgResHandle());
VString allFilesLabel(IDS_LABEL_ALL_FILES, GetDfrgResHandle());
// get the My Documents path
LPITEMIDLIST pidl;
TCHAR myDocsPath[MAX_PATH];
SHGetSpecialFolderLocation(hWndDialog, CSIDL_PERSONAL, &pidl);
if (SHGetPathFromIDList(pidl, myDocsPath))
ofn.lpstrInitialDir = myDocsPath; // it was found
else
ofn.lpstrInitialDir = NULL; // My Docs dir not found - default to current dir
// Concoct a file name from the Drive letter if there is one
// otherwise use the display label
VString volume;
if (pLocalVolume->Drive()) {
volume.LoadString(IDS_LABEL_VOLUME, GetDfrgResHandle());
wsprintf(cFile, TEXT("%s%c.txt"), volume.GetBuffer(), pLocalVolume->Drive());
}
else if (_tcslen(pLocalVolume->VolumeLabel()) > 0) {
wsprintf(cFile, TEXT("%s.txt"), pLocalVolume->VolumeLabel());
}
else {
volume.LoadString(IDS_LABEL_MOUNTED_VOLUME, GetDfrgResHandle());
wsprintf(cFile, TEXT("%s.txt"), volume.GetBuffer());
}
#ifdef VER4
ofn.lStructSize = sizeof(OPENFILENAME);
#else
// sizeof doesn't work under nt5
// special size was placed in header by MS
ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
#endif
ofn.hwndOwner = pLocalVolume->m_pDfrgCtl->m_hWndCD;
ofn.hInstance = _Module.GetModuleInstance();
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 1;
ofn.lpstrFile = cFile;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrTitle = saveStatsLabel.GetBuffer();
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = NULL;
ofn.lCustData = 0;
ofn.Flags = OFN_EXPLORER|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
ofn.lpstrFilter = szFilter;
//IDS_ANY_FILES_FILTER - "Analysis Files"
//IDS_ALL_FILES_FILTER - "All Files"
wsprintf((PTCHAR)ofn.lpstrFilter, TEXT("%s (*.txt)"), textFilesLabel.GetBuffer());
ofn.lpstrFilter += lstrlen(ofn.lpstrFilter)+1;
lstrcpy((PTCHAR)ofn.lpstrFilter, TEXT("*.txt"));
ofn.lpstrFilter += lstrlen(ofn.lpstrFilter)+1;
wsprintf((PTCHAR)ofn.lpstrFilter, TEXT("%s (*.*)"), allFilesLabel.GetBuffer());
ofn.lpstrFilter += lstrlen(ofn.lpstrFilter)+1;
lstrcpy((PTCHAR)ofn.lpstrFilter, TEXT("*.*"));
ofn.lpstrFilter += lstrlen(ofn.lpstrFilter)+1;
*(PTCHAR)ofn.lpstrFilter = 0;
ofn.lpstrFilter = szFilter;
// Disable the report dialog box
EnableWindow(hWndDialog, FALSE);
do {
// Create the Save dialog box - it is a mutated Open file common dialog.
BOOL isOK = GetSaveFileName(&ofn);
// inspect this if the GetSaveFileName() function fails
if (!isOK){
commError = CommDlgExtendedError();
}
// the GetSaveFileName() function failed. Bummer.
if (isOK) {
// Create a text report in memory that we can dump to the screen.
if (CreateTextReportInMemory(textBlock, MOST_FRAGGED_REPORT)) {
TCHAR cExtension[MAX_PATH+2];
_tsplitpath(cFile, NULL, NULL, NULL, cExtension);
if (_tcsclen(cExtension) != 4){
_tcscat(cFile, _T(".txt"));
}
// save the data to a text file (this method puts the Unicode marker in the file)
if (textBlock.StoreFile(cFile, CREATE_ALWAYS)) {
// enable the report dialog box
EnableWindow(hWndDialog, TRUE);
SetFocus(hWndDialog);
return TRUE;
}
}
}
else {
if (0 == commError) {
// enable the report dialog box
EnableWindow(hWndDialog, TRUE);
SetFocus(hWndDialog);
// User hit cancel, so all's well
return TRUE;
}
}
//
// We were unable to save the report. Put up a message box, and let
// the user try again
//
VString errFormat(IDS_ERR_UNABLE_TO_SAVE_REPORT, GetDfrgResHandle());
LPTSTR lpErrorMessage = new TCHAR[errFormat.GetLength() + _tcslen(cFile) + 2];
wsprintf(lpErrorMessage, errFormat, (LPCTSTR) cFile);
done = (IDCANCEL == MessageBoxW(hWndDialog, lpErrorMessage, saveStatsLabel.GetBuffer(), MB_OKCANCEL | MB_ICONWARNING));
delete [] lpErrorMessage;
} while (!done);
// enable the report dialog box
EnableWindow(hWndDialog, TRUE);
SetFocus(hWndDialog);
return TRUE;
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This function prints the data from the drive report as a text file.
DATA STRUCTURES:
None.
GLOBALS:
INPUT:
RETURN:
None.
*/
static BOOL
PrintDriveData(
IN HWND hWndDialog
)
{
PRINTDLG pd = {0};
DOCINFO di = {0};
RECT Rect;
HBRUSH hBrush;
TEXT_DATA* pTextData = &(pLocalVolume->m_TextData);
pd.lStructSize = sizeof(PRINTDLG);
pd.hwndOwner = pLocalVolume->m_pDfrgCtl->m_hWndCD;
pd.hDevMode = (HANDLE)NULL;
pd.hDevNames = (HANDLE)NULL;
pd.nFromPage = 0;
pd.nToPage = 0;
pd.nMinPage = 0;
pd.nMaxPage = 0;
pd.nCopies = 0;
pd.hInstance = _Module.GetModuleInstance();
pd.Flags = PD_RETURNDC|PD_USEDEVMODECOPIES|PD_COLLATE|PD_NOSELECTION;//|PD_PRINTSETUP;
pd.lpfnSetupHook = (LPSETUPHOOKPROC)(FARPROC)NULL;
pd.lpSetupTemplateName = (LPTSTR)NULL;
pd.lpfnPrintHook = (LPPRINTHOOKPROC)(FARPROC)NULL;
pd.lpPrintTemplateName = (LPTSTR)NULL;
// Disable the report dialog box
EnableWindow(hWndDialog, FALSE);
// raise the system print dialog
BOOL isOK = PrintDlg(&pd);
// enable the report dialog box
EnableWindow(hWndDialog, TRUE);
SetFocus(hWndDialog);
if (!isOK)
return FALSE;
di.cbSize = sizeof(DOCINFO);
TCHAR docName[200];
EH_ASSERT(LoadString(GetDfrgResHandle(), IDS_DEFRAG_REPORT_DOC_NAME, docName, sizeof(docName)/sizeof(TCHAR)));
di.lpszDocName = docName;
di.lpszOutput = (LPTSTR)NULL;
di.fwType = 0;
StartDoc(pd.hDC, &di);
StartPage(pd.hDC);
Rect.top = 0.1 * GetDeviceCaps(pd.hDC, VERTRES);
Rect.bottom = 0.9 * GetDeviceCaps(pd.hDC, VERTRES);
Rect.left = 0.1 * GetDeviceCaps(pd.hDC, HORZRES);;
Rect.right = 0.9 * GetDeviceCaps(pd.hDC, HORZRES);
hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
EF_ASSERT(hBrush);
FillRect(pd.hDC, &Rect, hBrush);
// get the extended window styles
LONG styles = ::GetWindowLong(hWndDialog, GWL_EXSTYLE);
// check the window styles for a right to left layout
UINT uFormat = DT_LEFT;
if (styles & WS_EX_LAYOUTRTL){
uFormat = DT_RIGHT | DT_RTLREADING;
}
// Create the basic text report
CTextBlock page1text;
WriteTextReportInMemory(page1text, MOST_FRAGGED_REPORT|PRINT_DEFRAG_TITLE);
// if we have a short list of fragged files, put it all on one page
if (pLocalVolume->m_FraggedFileList.Size() <= 5){
// get the text report
WriteFraggedReportInMemory(page1text, MOST_FRAGGED_REPORT);
// write the report to the printer
DrawText(pd.hDC, page1text.GetBuffer(), wcslen(page1text.GetBuffer()), &Rect, uFormat);
}
else { // if we have a long list of fragged files, then do a page break
// write the text (upper) portion to the printer
DrawText(pd.hDC, page1text.GetBuffer(), wcslen(page1text.GetBuffer()), &Rect, uFormat);
// do a page break and clear the rectangle
EndPage(pd.hDC);
FillRect(pd.hDC, &Rect, hBrush);
// create the fragged file list report in memory
CTextBlock page2text;
WriteFraggedReportInMemory(page2text, MOST_FRAGGED_REPORT|PRINT_DEFRAG_TITLE);
// send the fragged file list to the printer, page 2
DrawText(pd.hDC, page2text.GetBuffer(), wcslen(page2text.GetBuffer()), &Rect, uFormat);
}
// end of page
if(EndPage(pd.hDC) <= 0){
AbortDoc(pd.hDC);
return FALSE;
}
// end of print job
EndDoc(pd.hDC);
DeleteDC(pd.hDC);
if(pd.hDevMode){
EH_ASSERT(GlobalFree(pd.hDevMode) == NULL);
}
if(pd.hDevNames){
EH_ASSERT(GlobalFree(pd.hDevNames) == NULL);
}
return TRUE;
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This function initializes data for the report dialog box
DATA STRUCTURES:
None.
GLOBALS:
INPUT:
hWndDialog - handle to the dialog box
RETURN:
None.
*/
static void
InitializeFragListView(
IN HWND hWndDialog
)
{
int iColumnWidth[MAX_FRAGGED_FILE_COLUMNS] = {65, 65, 223};
int iColumnID[MAX_FRAGGED_FILE_COLUMNS] = {
IDS_NUM_FRAGMENTS,
IDS_FRAGGED_FILESIZE,
IDS_FRAGGED_FILENAME
};
int iColumnFormat[MAX_FRAGGED_FILE_COLUMNS] = {
LVCFMT_RIGHT,
LVCFMT_RIGHT,
LVCFMT_LEFT
};
// Initialize the LVCOLUMN structure.
LVCOLUMN lvc = {0};
TCHAR cTemp[200];
lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM;
lvc.pszText = cTemp;
// Get handle to the Fragged listview
HWND hListView = GetDlgItem(hWndDialog, IDC_MOST_FRAGMENTED);
EV_ASSERT(hListView);
// Insert the columns into the Listview.
int col;
for (col = 0; col < MAX_FRAGGED_FILE_COLUMNS; col++) {
lvc.fmt = iColumnFormat[col];
lvc.iSubItem = col;
LoadString(
GetDfrgResHandle(),
iColumnID[col],
cTemp,
sizeof(cTemp)/sizeof(TCHAR));
// Insert the columns into the ListView.
if (ListView_InsertColumn(hListView, col, &lvc) == -1) {
Message(TEXT("InitializeFragListView - ListView_InsertColumn."), E_FAIL, 0);
return;
}
}
// Go back thru and update columns.
for (col = 0; col < MAX_FRAGGED_FILE_COLUMNS; col++) {
// Size column to header text.
if (!ListView_SetColumnWidth(hListView, col, LVSCW_AUTOSIZE_USEHEADER)) {
Message(TEXT("InitializeFragListView - ListView_SetColumnWidth."), E_FAIL, 0);
}
// Grow width if needed.
int tmpStrWidth = ListView_GetColumnWidth(hListView, col);
if (tmpStrWidth < iColumnWidth[col]) {
if (!ListView_SetColumnWidth(hListView, col, iColumnWidth[col])) {
Message(TEXT("InitializeFragListView - 2nd ListView_SetColumnWidth."), E_FAIL, 0);
}
}
}
// Tell the left column that he is RIGHT JUSTIFIED!!!
// The formatting sent with the InsertColumn does not
// stick for some reason.
// You can comment this code out and see if it is fixed if you wanna.
// Or maybe you can find the fix. But after 3 hours of trying, this
// was my solution...
lvc.mask = LVCF_FMT;
lvc.fmt = LVCFMT_RIGHT;
if (ListView_SetColumn(hListView, 0, &lvc) == -1) {
Message(TEXT("InitializeFragListView - ListView_SetColumn."), E_FAIL, 0);
return;
}
// make the listview hilite the entire row
ListView_SetExtendedListViewStyle(hListView, LVS_EX_FULLROWSELECT);
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This function initializes data for the report dialog box
DATA STRUCTURES:
None.
INPUT:
hWndDialog - handle to the dialog box
RETURN:
None.
*/
static void
InitializeVolumeListView(
IN HWND hWndDialog
)
{
int iColumnWidth[MAX_VOLUME_INFO_COLUMNS] = {200,5,50};
//not needed, no column labels
int iColumnID[MAX_VOLUME_INFO_COLUMNS] = {
NULL,
NULL,
NULL
};
int iColumnFormat[MAX_VOLUME_INFO_COLUMNS] = {
LVCFMT_LEFT,
LVCFMT_RIGHT,
LVCFMT_LEFT
};
// Initialize the LVCOLUMN structure.
LVCOLUMN lvc = {0};
TCHAR cTemp[200];
lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM;
lvc.pszText = cTemp;
// Get handle to the Fragged listview
HWND hListView = GetDlgItem(hWndDialog, IDC_VOLUME_INFORMATION);
EV_ASSERT(hListView);
// Insert the columns into the Listview.
int col = 0;
for (col = 0; col < MAX_VOLUME_INFO_COLUMNS; col++) {
lvc.fmt = iColumnFormat[col];
lvc.iSubItem = col;
// LoadString(
// GetDfrgResHandle(),
// iColumnID[col],
// cTemp,
// sizeof(cTemp)/sizeof(TCHAR));
// Insert the columns into the ListView.
if (ListView_InsertColumn(hListView, col, &lvc) == -1) {
Message(TEXT("InitializeFragListView - ListView_InsertColumn."), E_FAIL, 0);
return;
}
}
// Go back thru and update columns.
for (col = 0; col < MAX_VOLUME_INFO_COLUMNS; col++) {
// Size column to header text.
if (!ListView_SetColumnWidth(hListView, col, iColumnWidth[col])) {
Message(TEXT("InitializeFragListView - ListView_SetColumnWidth."), E_FAIL, 0);
}
// Grow width if needed.
int tmpStrWidth = ListView_GetColumnWidth(hListView, col);
if (tmpStrWidth < iColumnWidth[col])
{
if (!ListView_SetColumnWidth(hListView, col, iColumnWidth[col])) {
Message(TEXT("InitializeFragListView - 2nd ListView_SetColumnWidth."), E_FAIL, 0);
}
}
}
// Tell the left column that he is RIGHT JUSTIFIED!!!
// The formatting sent with the InsertColumn does not
// stick for some reason.
// You can comment this code out and see if it is fixed if you wanna.
// Or maybe you can find the fix. But after 3 hours of trying, this
// was my solution...
lvc.mask = LVCF_FMT;
lvc.fmt = LVCFMT_LEFT;
if (ListView_SetColumn(hListView, 0, &lvc) == -1) {
Message(TEXT("InitializeFragListView - ListView_SetColumn."), E_FAIL, 0);
return;
}
// make the listview hilite the entire row
ListView_SetExtendedListViewStyle(hListView, LVS_EX_FULLROWSELECT);
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This function initializes data for the report dialog box
DATA STRUCTURES:
None.
INPUT:
hWndDialog - handle to the dialog box
RETURN:
None.
*/
static void
ResizeVolumeListViewColumns(
IN HWND hWndDialog, IN UINT uWidthFirstColumn,
IN UINT uWidthSecondColumn, IN UINT uWidthThirdColumn
)
{
// Get handle to the Fragged listview
HWND hListView = GetDlgItem(hWndDialog, IDC_VOLUME_INFORMATION);
EV_ASSERT(hListView);
// Go back thru and update columns.
if (!ListView_SetColumnWidth(hListView, 0, LVSCW_AUTOSIZE))
{
Message(TEXT("InitializeFragListView - ListView_SetColumnWidth."), E_FAIL, 0);
}
if (!ListView_SetColumnWidth(hListView, 1, LVSCW_AUTOSIZE))
{
Message(TEXT("InitializeFragListView - ListView_SetColumnWidth."), E_FAIL, 0);
}
if (!ListView_SetColumnWidth(hListView, 2, LVSCW_AUTOSIZE))
{
Message(TEXT("InitializeFragListView - ListView_SetColumnWidth."), E_FAIL, 0);
}
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
Displays a pre-formated items on the pop-up list view screen.
DATA STRUCTURES:
None.
GLOBALS:
None.
INPUT:
IN HANDLE hListView,- handle to report dialog
RETURN:
None.
*/
static void
InsertListViewItems(
IN HWND hWndDialog,
CVolume *pLocalVolume
)
{
// Get handle to the Fragged listview
HWND hListView = GetDlgItem(hWndDialog, IDC_MOST_FRAGMENTED);
EV_ASSERT(hListView);
LVITEM lvi = {0};
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.pszText = LPSTR_TEXTCALLBACK; // will be populated by the callback
// Add each item to the listview.
for (UINT i=0; i<pLocalVolume->m_FraggedFileList.Size(); i++) {
lvi.iItem = i;
// address of fragged file object
lvi.lParam = (LPARAM) pLocalVolume->m_FraggedFileList.GetAt(i);
// Send the data to the list view box.
if (ListView_InsertItem(hListView, &lvi) == -1){
Message(TEXT("InsertListViewItems - ListView_InsertItem"), E_FAIL, 0);
return;
}
for (UINT iSubItem = 0; iSubItem < MAX_FRAGGED_FILE_COLUMNS; iSubItem++) {
ListView_SetItemText(
hListView,
lvi.iItem,
iSubItem,
LPSTR_TEXTCALLBACK);
}
}
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
Displays a pre-formated items on the pop-up list view screen.
DATA STRUCTURES:
None.
GLOBALS:
None.
INPUT:
IN HANDLE hListView,- handle to report dialog
RETURN:
None.
*/
static UINT
InsertVolumeListViewItems(
IN HWND hWndDialog, IN UINT iListItemNumber, IN UINT resourceIDText, IN UINT resourceIDSeperator,
IN TCHAR* pTextStr, BOOL bIndentText, UINT uLongestTextString
)
{
// Get handle to the Fragged listview
HWND hListView = GetDlgItem(hWndDialog, IDC_VOLUME_INFORMATION);
assert(hListView);
TCHAR buffer[256];
LVITEM lvi = {0};
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.pszText = LPSTR_TEXTCALLBACK; // will be populated by the callback
// lvi.item = iListItemNumber;
// Send the data to the list view box.
if (ListView_InsertItem(hListView, &lvi) == -1){
Message(TEXT("InsertVolumeListViewItems Failed"), E_FAIL, 0);
return 0;
}
TCHAR tempBuffer[300];
//load the resourceIDText
LoadString(GetDfrgResHandle(), resourceIDText, buffer, sizeof(buffer)/sizeof(TCHAR));
if(bIndentText)
{
swprintf(tempBuffer, L" %s", buffer);
} else
{
swprintf(tempBuffer, L"%s", buffer);
}
//need to make the string 30% longer and fill with spaces
UINT uTempStrLen = _tcslen(tempBuffer);
UINT uExtraStrLen = uTempStrLen * 3 / 10;
UINT i = 0;
if ((uTempStrLen + uExtraStrLen) < 255) //buffer already at maximum length
{
for(i=0;i<uExtraStrLen;i++)
{
_tcscat(tempBuffer, L" ");
}
}
uTempStrLen = _tcslen(tempBuffer);
if(uTempStrLen > uLongestTextString)
{
uLongestTextString = uTempStrLen;
}
ListView_SetItemText(
hListView,
lvi.iItem,
0,
tempBuffer);
//load the resourceIDSeperator
LoadString(GetDfrgResHandle(), resourceIDSeperator, buffer, sizeof(buffer)/sizeof(TCHAR));
ListView_SetItemText(
hListView,
lvi.iItem,
1,
buffer);
//load the pTextStr
ListView_SetItemText(
hListView,
lvi.iItem,
2,
pTextStr);
return uLongestTextString;
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
Displays a pre-formated items on the pop-up list view screen.
DATA STRUCTURES:
None.
GLOBALS:
None.
INPUT:
IN HANDLE hListView,- handle to report dialog
RETURN:
None.
*/
static UINT
InsertVolumeListViewItems(
IN HWND hWndDialog, IN UINT iListItemNumber, IN TCHAR* itemOneText, IN UINT resourceIDSeperator,
IN TCHAR* pTextStr, BOOL bIndentText, UINT uLongestTextString
)
{
// Get handle to the Fragged listview
HWND hListView = GetDlgItem(hWndDialog, IDC_VOLUME_INFORMATION);
assert(hListView);
TCHAR buffer[256];
LVITEM lvi = {0};
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.pszText = LPSTR_TEXTCALLBACK; // will be populated by the callback
// lvi.item = iListItemNumber;
// Send the data to the list view box.
if (ListView_InsertItem(hListView, &lvi) == -1){
Message(TEXT("InsertVolumeListViewItems Failed"), E_FAIL, 0);
return 0;
}
TCHAR tempBuffer[300];
//load the resourceIDText
if(bIndentText)
{
swprintf(tempBuffer, L" %s", itemOneText);
} else
{
swprintf(tempBuffer, L"%s", itemOneText);
}
UINT uTempStrLen = _tcslen(itemOneText);
if(uTempStrLen > uLongestTextString)
{
uLongestTextString = uTempStrLen;
}
//load the resourceIDText
ListView_SetItemText(
hListView,
lvi.iItem,
0,
itemOneText);
//load the resourceIDSeperator
LoadString(GetDfrgResHandle(), resourceIDSeperator, buffer, sizeof(buffer)/sizeof(TCHAR));
ListView_SetItemText(
hListView,
lvi.iItem,
1,
buffer);
//load the pTextStr
ListView_SetItemText(
hListView,
lvi.iItem,
2,
pTextStr);
return uLongestTextString;
}
static UINT
InsertVolumeListViewItems(
IN HWND hWndDialog, IN UINT iListItemNumber, IN UINT resourceIDText, IN UINT resourceIDSeperator,
IN TCHAR* pTextStr, IN UINT resourceIDPercent, BOOL bIndentText, UINT uLongestTextString
)
{
// Get handle to the Fragged listview
HWND hListView = GetDlgItem(hWndDialog, IDC_VOLUME_INFORMATION);
assert(hListView);
TCHAR buffer[256];
TCHAR tempbuffer[256];
LVITEM lvi = {0};
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.pszText = LPSTR_TEXTCALLBACK; // will be populated by the callback
// lvi.item = iListItemNumber;
// Send the data to the list view box.
if (ListView_InsertItem(hListView, &lvi) == -1){
Message(TEXT("InsertVolumeListViewItems Failed"), E_FAIL, 0);
return 0;
}
TCHAR tempBuffer[300];
//load the resourceIDText
LoadString(GetDfrgResHandle(), resourceIDText, buffer, sizeof(buffer)/sizeof(TCHAR));
if(bIndentText)
{
swprintf(tempBuffer, L" %s", buffer);
} else
{
swprintf(tempBuffer, L"%s", buffer);
}
UINT uTempStrLen = _tcslen(tempBuffer);
if(uTempStrLen > uLongestTextString)
{
uLongestTextString = uTempStrLen;
}
ListView_SetItemText(
hListView,
lvi.iItem,
0,
tempBuffer);
//load the resourceIDSeperator
LoadString(GetDfrgResHandle(), resourceIDSeperator, buffer, sizeof(buffer)/sizeof(TCHAR));
ListView_SetItemText(
hListView,
lvi.iItem,
1,
buffer);
LoadString(GetDfrgResHandle(), resourceIDPercent, buffer, sizeof(buffer)/sizeof(TCHAR));
swprintf(tempbuffer, L"%s %s", pTextStr,buffer);
//load the pTextStr
ListView_SetItemText(
hListView,
lvi.iItem,
2,
tempbuffer);
return uLongestTextString;
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This function deallocate resources for the report dialog
DATA STRUCTURES:
None.
INPUT:
hWndDialog - handle to the dialog box
RETURN:
None.
*/
static void
ExitReport(
IN HWND hWndDialog
)
{
::DeleteObject(hDlgFont);
EndDialog(hWndDialog, 0);
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This function deallocate resources for the report dialog
DATA STRUCTURES:
None.
INPUT:
hWndDialog - handle to the dialog box
RETURN:
None.
*/
TCHAR*
InsertCommaIntoText(
IN TCHAR* stringBuffer
)
{
TCHAR targetString[256];
TCHAR sourceString[256];
TCHAR tcThousandsSep[2] = {TEXT(','), 0};
_tcscpy(sourceString, stringBuffer);
if(_tcslen(sourceString) == 0) {
return TEXT("");
}
struct lconv *locals = localeconv();
if (locals && (locals->thousands_sep) && (*(locals->thousands_sep) != 0)) {
_stprintf(tcThousandsSep, TEXT("%C"), *(locals->thousands_sep));
}
UINT uGrouping = 0;
if (locals && (locals->grouping)) {
uGrouping = atoi(locals->grouping);
}
if(uGrouping == 0) {
uGrouping = 3; //default value if its not supported
}
// point the source pointer at the null terminator
PTCHAR pSource = sourceString + _tcslen(sourceString);
// put the target pointer at the end of the target buffer
PTCHAR pTarget = targetString + sizeof(targetString) / sizeof(TCHAR) - 1;
// write the null terminator
*pTarget = NULL;
for (UINT i=0; i<_tcslen(sourceString); i++){
if (i>0 && i%uGrouping == 0){
pTarget--;
*pTarget = tcThousandsSep[0];
}
pTarget--;
pSource--;
*pTarget = *pSource;
}
// if (stringBufferLength > _tcslen(pTarget)){
_tcscpy(stringBuffer, pTarget);
// }
// else{
// _tcscpy(stringBuffer, TEXT(""));
// }
return stringBuffer;
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This method resizes the buttons
DATA STRUCTURES:
genericButton structure.
INPUT:
hWndDialog - handle to the dialog box
RETURN:
None.
*/
void GetButtonDimensions(HWND hWndDialog, BOOL bIsAnalysisReport)
{
HDC OutputDC = GetDC(hWndDialog);
EV_ASSERT(OutputDC);
HDC WorkDC = ::CreateCompatibleDC(OutputDC);
EV_ASSERT(WorkDC);
::SelectObject(WorkDC, hDlgFont);
const bigButtonSpacer = 20;
adjustedButtonHeight = __max((UINT)(1.5 * uFontHeight), m_ButtonHeight);
//need to know the total width of the buttons before setting location
totalButtonWidth = 0;
TCHAR buffer[256];
//width of the Close button
SendDlgItemMessage(hWndDialog, IDCANCEL, WM_GETTEXT, (WPARAM) 255, (LPARAM) buffer);
adjustedButtonWidthClose = __max(m_ButtonSpacer + GetStringWidth(buffer, WorkDC), m_ButtonWidth);
totalButtonWidth += adjustedButtonWidthClose + 2 * m_ButtonSpacer;
//width of the Defragment button
if(bIsAnalysisReport) //need to include the Defragment button if we are using the analysis report
{
SendDlgItemMessage(hWndDialog, IDC_DEFRAGMENT, WM_GETTEXT, (WPARAM) 255, (LPARAM) buffer);
adjustedButtonWidthDefrag = __max(m_ButtonSpacer + GetStringWidth(buffer, WorkDC), m_ButtonWidth);
totalButtonWidth += adjustedButtonWidthDefrag + m_ButtonSpacer;
} else //add another close button to make the dialog wide enough
{
totalButtonWidth += adjustedButtonWidthClose + 2 * m_ButtonSpacer;
}
//width of the Save As button
SendDlgItemMessage(hWndDialog, IDC_SAVE, WM_GETTEXT, (WPARAM) 255, (LPARAM) buffer);
adjustedButtonWidthSave = __max(m_ButtonSpacer + GetStringWidth(buffer, WorkDC), m_ButtonWidth);
totalButtonWidth += adjustedButtonWidthSave + m_ButtonSpacer;
//width of the Print button
SendDlgItemMessage(hWndDialog, IDC_PRINT, WM_GETTEXT, (WPARAM) 255, (LPARAM) buffer);
adjustedButtonWidthPrint = __max(m_ButtonSpacer + GetStringWidth(buffer, WorkDC), m_ButtonWidth);
totalButtonWidth += adjustedButtonWidthPrint + m_ButtonSpacer;
minimumDialogWidth = __max(minimumDialogWidth,totalButtonWidth);
DeleteDC(OutputDC); // handle to device context
DeleteDC(WorkDC); // handle to device context
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This method positons the buttons
DATA STRUCTURES:
genericButton structure.
INPUT:
hWndDialog - handle to the dialog box
RETURN:
None.
*/
void PositionButtons(HWND hWndDialog, RECT rDlg, BOOL bIsAnalysisReport)
{
HDC OutputDC = GetDC(hWndDialog);
EV_ASSERT(OutputDC);
HDC WorkDC = ::CreateCompatibleDC(OutputDC);
EV_ASSERT(WorkDC);
::SelectObject(WorkDC, hDlgFont);
// Calculate Close Button position and size.
GetWindowRect(GetDlgItem(hWndDialog, IDCANCEL), &rcButtonClose);
rcButtonClose.right = rDlg.right - rDlg.left - m_ButtonFloat;
rcButtonClose.left = rcButtonClose.right - adjustedButtonWidthClose;
rcButtonClose.bottom = rDlg.bottom - rDlg.top - (1.75 * adjustedButtonHeight);
rcButtonClose.top = rcButtonClose.bottom - adjustedButtonHeight;
PositionButton(&rcButtonClose,GetDlgItem(hWndDialog, IDCANCEL));
if(bIsAnalysisReport)
{
GetWindowRect(GetDlgItem(hWndDialog, IDC_DEFRAGMENT), &rcButtonDefrag);
rcButtonDefrag.right = rcButtonClose.left - m_ButtonSpacer;
rcButtonDefrag.left = rcButtonDefrag.right - adjustedButtonWidthDefrag;
rcButtonDefrag.bottom = rDlg.bottom - rDlg.top - (1.75 * adjustedButtonHeight);
rcButtonDefrag.top = rcButtonDefrag.bottom - adjustedButtonHeight;
PositionButton(&rcButtonDefrag,GetDlgItem(hWndDialog, IDC_DEFRAGMENT));
//need to do the Save As button also
GetWindowRect(GetDlgItem(hWndDialog, IDC_SAVE), &rcButtonSave);
rcButtonSave.right = rcButtonDefrag.left - m_ButtonSpacer;
rcButtonSave.left = rcButtonSave.right - adjustedButtonWidthSave;
rcButtonSave.bottom = rDlg.bottom - rDlg.top - (1.75 * adjustedButtonHeight);
rcButtonSave.top = rcButtonSave.bottom - adjustedButtonHeight;
PositionButton(&rcButtonSave,GetDlgItem(hWndDialog, IDC_SAVE));
} else
{
//we position the Save Button next to the Close Button
GetWindowRect(GetDlgItem(hWndDialog, IDC_SAVE), &rcButtonSave);
rcButtonSave.right = rcButtonClose.left - m_ButtonSpacer;
rcButtonSave.left = rcButtonSave.right - adjustedButtonWidthSave;
rcButtonSave.bottom = rDlg.bottom - rDlg.top - (1.75 * adjustedButtonHeight);
rcButtonSave.top = rcButtonSave.bottom - adjustedButtonHeight;
PositionButton(&rcButtonSave,GetDlgItem(hWndDialog, IDC_SAVE));
}
GetWindowRect(GetDlgItem(hWndDialog, IDC_PRINT), &rcButtonPrint);
rcButtonPrint.right = rcButtonSave.left - m_ButtonSpacer;
rcButtonPrint.left = rcButtonPrint.right - adjustedButtonWidthPrint;
rcButtonPrint.bottom = rDlg.bottom - rDlg.top - (1.75 * adjustedButtonHeight);
rcButtonPrint.top = rcButtonPrint.bottom - adjustedButtonHeight;
PositionButton(&rcButtonPrint,GetDlgItem(hWndDialog, IDC_PRINT));
::DeleteDC(WorkDC);
::DeleteDC(OutputDC);
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This method positons the buttons
DATA STRUCTURES:
genericButton structure.
INPUT:
hWndDialog - handle to the dialog box
RETURN:
None.
*/
void PositionControls(HWND hWndDialog, RECT rDlg)
{
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This method repositions the buttons
DATA STRUCTURES:
genericButton structure.
INPUT:
hWndDialog - handle to the dialog box
RECT - Defining the location of where the button is going
RETURN:
None.
*/
void PositionButton(RECT* prcPos, HWND hWndDialog)
{
if (hWndDialog != NULL){
MoveWindow(hWndDialog,
prcPos->left,
prcPos->top,
prcPos->right - prcPos->left,
prcPos->bottom - prcPos->top,
TRUE);
}
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This method finds the longest string inside the VString terminated by a \n
DATA STRUCTURES:
genericButton structure.
INPUT:
PTCHAR - buffer that contains the string
HDC - Handle to a device context (DC) on the screen.
RETURN:
Width of the character.
*/
UINT GetStringWidth(PTCHAR stringBuf, HDC WorkDC)
{
if (!stringBuf){
return 0;
}
UINT iStringWidth = 0;
int iCharWidth = 0;
for (UINT i=0; i<_tcslen(stringBuf); i++){
if (::GetCharWidth32(
WorkDC,
stringBuf[i],
stringBuf[i],
&iCharWidth)) {
iStringWidth += iCharWidth;
}
}
return iStringWidth;
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This method resizes the dialog in response to the user resizing the dialog
DATA STRUCTURES:
None.
INPUT:
None.
RETURN:
None.
*/
void ResizeDialog(HWND hWndDialog)
{
UINT dialogBoxFinalWidth;
UINT dialogBoxFinalHeight;
//get the new dimensions of the dialog
GetWindowRect(hWndDialog, &rcNewDialogSize);
if((rcNewDialogSize.bottom - rcNewDialogSize.top) < (rcOriginalDialogSize.bottom - rcOriginalDialogSize.top) ||
(rcNewDialogSize.right - rcNewDialogSize.left) < (rcOriginalDialogSize.right - rcOriginalDialogSize.left))
{
dialogBoxFinalWidth = rcOriginalDialogSize.right - rcOriginalDialogSize.left;
dialogBoxFinalHeight = rcOriginalDialogSize.bottom - rcOriginalDialogSize.top;
//set back to original size
MoveWindow(hWndDialog, rcOriginalDialogSize.left, rcOriginalDialogSize.top, dialogBoxFinalWidth, dialogBoxFinalHeight, TRUE);
return;
}
//if its not smaller, it must be bigger or the same, no matter, reposition the stuff
m_ButtonFloat = ((rcNewDialogSize.right - rcNewDialogSize.left) - totalButtonWidth) / 2;
PositionButtons(hWndDialog, rcNewDialogSize,TRUE);
InvalidateRect(
hWndDialog, // handle of window with changed update region
&rcNewDialogSize, // address of rectangle coordinates
TRUE // erase-background flag
);
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This method finds the longest string inside the VString terminated by a \n
DATA STRUCTURES:
genericButton structure.
INPUT:
VString - string in the editbox
RETURN:
Longest line in the editbox terminated by a \n.
*/
UINT FindMaxEditboxStringWidth(VString vstring)
{
int iLongestLine = 0, iEndofString = 0, iCurrentSearchLocation = 0;
iEndofString = vstring.GetLength();
if(iEndofString == 0) //oops no string return 0
{
return(0);
}
while(iCurrentSearchLocation < iEndofString)
{
iCurrentSearchLocation = vstring.Find(TEXT("\n"));
if(iCurrentSearchLocation == -1) //I didnt find any more
{
if (0 == iLongestLine) {
iLongestLine = iEndofString;
}
break;
}
if(iCurrentSearchLocation > iLongestLine)
{
iLongestLine = iCurrentSearchLocation;
}
vstring = vstring.Mid(iCurrentSearchLocation+1); //sub string the original chopping off the front
iEndofString = vstring.GetLength();
iCurrentSearchLocation = 0;
}
return(iLongestLine);
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
This method counts the number of \n inside the VString for the editbox
DATA STRUCTURES:
genericButton structure.
INPUT:
VString - editbox string
RETURN:
Number of lines in the editbox.
*/
UINT FindMaxEditboxStringHeight(VString vstring)
{
int iNumberofLines = 0, iEndofString = 0, iCurrentSearchLocation = 0;
iEndofString = vstring.GetLength();
if(iEndofString == 0) //oops no string return 0
{
return(0);
}
while(iCurrentSearchLocation < iEndofString)
{
iCurrentSearchLocation = vstring.Find(TEXT("\n"));
if(iCurrentSearchLocation == -1) //I didnt find any more
{
break;
}
iNumberofLines++;
vstring = vstring.Mid(iCurrentSearchLocation+1); //sub string the original chopping off the front
iEndofString = vstring.GetLength();
iCurrentSearchLocation = 0;
}
return(++iNumberofLines); //add 1 more since the last line does not have a \n
}
/***************************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
DESCRIPTION:
checks for negative values and returns 0 for negative numbers.
DATA STRUCTURES:
none.
INPUT:
LONGLONG - lldatavalue
RETURN:
either lldatavalue or zero.
*/
LONGLONG checkForNegativeValues(LONGLONG lldatavalue)
{
if(lldatavalue > 0)
{
return(lldatavalue);
} else
{
return 0;
}
}