reactos/modules/rosapps/applications/fraginator/MainDialog.cpp

575 lines
15 KiB
C++

#include "Unfrag.h"
#include "MainDialog.h"
#include "resource.h"
#include "Fraginator.h"
#include "Defragment.h"
#include "ReportDialog.h"
vector<wstring> DrivesList;
LRESULT AnalyzeID;
LRESULT FastID;
LRESULT ExtensiveID;
bool QuitWhenDone;
bool Stopping;
LRESULT PriHighID;
LRESULT PriAboveNormID;
LRESULT PriNormalID;
LRESULT PriBelowNormID;
LRESULT PriIdleID;
static void InitDialog (HWND Dlg);
void UpdateDefragInfo (HWND Dlg);
void UpdatePriority (HWND Dlg);
wstring GetDefaultTitle (void);
wstring GetDefragTitle (void);
void SetDisables (HWND Dlg);
INT_PTR CALLBACK MainDialogProc (HWND Dlg, UINT Msg, WPARAM WParam, LPARAM LParam);
static void InitDialog (HWND Dlg)
{
// Make internal list
DWORD DriveMask;
HWND DlgItem;
size_t d;
// Clear out wisecracks line for now
SetDlgItemText (Dlg, IDC_WISECRACKS, L"\"Defrag, baby!\"");
// Make list of logical drives
DrivesList.resize (0);
DriveMask = GetLogicalDrives ();
for (d = 0; d < 26; d++)
{
if (DriveMask & (1 << d))
{
wstring Name;
Name = (wchar_t)(L'A' + d);
Name += L':';
DrivesList.push_back (Name);
}
}
// Give list to dropdown list
DlgItem = GetDlgItem (Dlg, IDC_DRIVES_LIST);
SendMessage (DlgItem, CB_RESETCONTENT, 0, 0);
for (d = 0; d < DrivesList.size(); d++)
{
SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) DrivesList[d].c_str());
}
// Put in defrag methods
DlgItem = GetDlgItem (Dlg, IDC_METHODS_LIST);
SendMessage (DlgItem, CB_RESETCONTENT, 0, 0);
AnalyzeID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Analyze Only");
FastID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Fast Defrag");
ExtensiveID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Extensive Defrag");
// Set up process priorities
DlgItem = GetDlgItem (Dlg, IDC_PRIORITY_LIST);
SendMessage (Dlg, CB_RESETCONTENT, 0, 0);
PriHighID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"High");
PriAboveNormID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Above Normal");
PriNormalID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Normal");
PriBelowNormID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Below Normal");
PriIdleID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Idle");
UpdatePriority (Dlg);
// Reset texts and progress meters
SendDlgItemMessage (Dlg, IDC_STATUS, WM_SETTEXT, 0, (LPARAM) L"");
SendDlgItemMessage (Dlg, IDC_PERCENT, WM_SETTEXT, 0, (LPARAM) L"");
SendDlgItemMessage (Dlg, IDC_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM (0, 10000));
SendDlgItemMessage (Dlg, IDC_PROGRESS, PBM_SETPOS, 0, 0);
return;
}
void UpdateDefragInfo (HWND Dlg)
{
wchar_t PercentText[100];
static double OldPercent = 200.0f;
static wstring OldStatus = L"Non";
wstring NewStatus;
double NewPercent;
if (Defrag == NULL)
return;
NewPercent = Defrag->GetStatusPercent ();
if (NewPercent > 100.0f)
NewPercent = 100.0f;
if (NewPercent < 0.0f)
NewPercent = 0.0f;
if (NewPercent != OldPercent)
{
swprintf (PercentText, L"%6.2f%%", NewPercent);
SendDlgItemMessage (Dlg, IDC_PERCENT, WM_SETTEXT, 0, (LPARAM) PercentText);
SendDlgItemMessage (Dlg, IDC_PROGRESS, PBM_SETPOS,
(WPARAM) (int)(NewPercent * 100.0f), 0);
OldPercent = NewPercent;
}
NewStatus = Defrag->GetStatusString ();
if (NewStatus != OldStatus)
{ // Change & characters to && to avoid underlining
wstring Status;
wstring::iterator it;
Status = NewStatus;
it = Status.begin ();
while (it < Status.end())
{
if (*it == L'&')
{
Status.insert (it, 1, L'&');
it++;
}
it++;
}
SendDlgItemMessage (Dlg, IDC_STATUS, WM_SETTEXT, 0,
(LPARAM) Status.c_str());
OldStatus = NewStatus;
}
return;
}
wstring GetDefaultTitle (void)
{
wstring DefaultText;
DefaultText = wstring(wstring(APPNAME_GUI) + wstring(L" v") + wstring(APPVER_STR) +
wstring(L" (C) 2000 by Rick Brewster"));
return (DefaultText);
}
wstring GetDefragTitle (void)
{
wstring DefragText;
wchar_t Percent[10];
swprintf (Percent, L"%.2f%%", Defrag->GetStatusPercent());
DefragText = GetDefaultTitle ();
if (Defrag != NULL)
{
DefragText = wstring(Percent) + wstring (L" - ") + Defrag->GetVolume().GetRootPath() +
wstring (L" - ") + DefragText;
}
return (DefragText);
}
void SetDisables (HWND Dlg)
{
// If a defrag is in process, set L'Start' button to say L'Stop' and disable
// the Select Drive and Select Action controls
if (Defrag != NULL && !Defrag->IsDoneYet() && !Defrag->HasError())
{
SendMessage (GetDlgItem (Dlg, IDC_STARTSTOP), WM_SETTEXT, 0, (LPARAM) L"Stop");
EnableWindow (GetDlgItem (Dlg, IDC_DRIVES_LIST), FALSE);
EnableWindow (GetDlgItem (Dlg, IDC_METHODS_LIST), FALSE);
}
else
{
SendMessage (GetDlgItem (Dlg, IDC_STARTSTOP), WM_SETTEXT, 0, (LPARAM) L"Start");
EnableWindow (GetDlgItem (Dlg, IDC_STARTSTOP), TRUE);
EnableWindow (GetDlgItem (Dlg, IDC_QUIT), TRUE);
EnableWindow (GetDlgItem (Dlg, IDC_DRIVES_LIST), TRUE);
EnableWindow (GetDlgItem (Dlg, IDC_METHODS_LIST), TRUE);
}
return;
}
void UpdatePriority (HWND Dlg)
{
LRESULT Id;
DWORD Priority;
Id = SendDlgItemMessage (Dlg, IDC_PRIORITY_LIST, CB_GETCURSEL, 0, 0);
if (Id == PriHighID)
Priority = HIGH_PRIORITY_CLASS;
else
if (Id == PriAboveNormID)
Priority = ABOVE_NORMAL_PRIORITY_CLASS;
else
if (Id == PriNormalID)
Priority = NORMAL_PRIORITY_CLASS;
else
if (Id == PriBelowNormID)
Priority = BELOW_NORMAL_PRIORITY_CLASS;
else
if (Id == PriIdleID)
Priority = IDLE_PRIORITY_CLASS;
else
return;
SetPriorityClass (GetCurrentProcess(), Priority);
return;
}
// Save settings (ie, process priority and defrag type options)
bool GetRegKeys (HKEY *RegKeyResult)
{
HKEY RegKey;
LONG Error;
Error = RegCreateKeyEx
(
HKEY_CURRENT_USER,
L"Software\\Fraginator",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&RegKey,
NULL
);
if (Error != ERROR_SUCCESS)
return (false);
*RegKeyResult = RegKey;
return (true);
}
bool DoneRegKey (HKEY RegKey)
{
RegCloseKey (RegKey);
return (true);
}
void SaveSettings (HWND Dlg)
{
LRESULT DefragID;
DWORD DefragVal;
LRESULT PriID;
DWORD PriVal;
HKEY RegKey;
DefragID = SendDlgItemMessage (Dlg, IDC_METHODS_LIST, CB_GETCURSEL, 0, 0);
PriID = SendDlgItemMessage (Dlg, IDC_PRIORITY_LIST, CB_GETCURSEL, 0, 0);
// Action
if (DefragID == AnalyzeID)
DefragVal = (DWORD) DefragAnalyze;
else
if (DefragID == FastID)
DefragVal = (DWORD) DefragFast;
else
if (DefragID == ExtensiveID)
DefragVal = (DWORD) DefragExtensive;
// Process Priority
if (PriID == PriHighID)
PriVal = HIGH_PRIORITY_CLASS;
else
if (PriID == PriAboveNormID)
PriVal = ABOVE_NORMAL_PRIORITY_CLASS;
else
if (PriID == PriNormalID)
PriVal = NORMAL_PRIORITY_CLASS;
else
if (PriID == PriBelowNormID)
PriVal = BELOW_NORMAL_PRIORITY_CLASS;
else
if (PriID == PriIdleID)
PriVal = IDLE_PRIORITY_CLASS;
if (!GetRegKeys (&RegKey))
return;
RegSetValueEx
(
RegKey,
L"Default Action",
0,
REG_DWORD,
(CONST BYTE *)&DefragVal,
sizeof (DefragVal)
);
RegSetValueEx
(
RegKey,
L"Process Priority",
0,
REG_DWORD,
(CONST BYTE *)&PriVal,
sizeof (PriVal)
);
DoneRegKey (RegKey);
return;
}
void LoadSettings (HWND Dlg)
{
DefragType DType;
DWORD DTypeVal;
LRESULT DefragID;
DWORD PriVal;
LRESULT PriID;
HKEY RegKey;
DWORD RegType;
DWORD RegSize;
LONG Error;
if (!GetRegKeys (&RegKey))
return;
RegSize = sizeof (DTypeVal);
RegType = REG_DWORD;
Error = RegQueryValueEx
(
RegKey,
L"Default Action",
0,
&RegType,
(BYTE *)&DTypeVal,
&RegSize
);
if (Error != ERROR_SUCCESS)
DTypeVal = DefragAnalyze;
Error = RegQueryValueEx
(
RegKey,
L"Process Priority",
0,
&RegType,
(BYTE *)&PriVal,
&RegSize
);
DoneRegKey (RegKey);
if (Error != ERROR_SUCCESS)
PriVal = NORMAL_PRIORITY_CLASS;
DType = (DefragType) DTypeVal;
switch (DType)
{
default:
case DefragAnalyze:
DefragID = AnalyzeID;
break;
case DefragFast:
DefragID = FastID;
break;
case DefragExtensive:
DefragID = ExtensiveID;
break;
}
switch (PriVal)
{
case HIGH_PRIORITY_CLASS:
PriID = PriHighID;
break;
case ABOVE_NORMAL_PRIORITY_CLASS:
PriID = PriAboveNormID;
break;
default:
case NORMAL_PRIORITY_CLASS:
PriID = PriNormalID;
break;
case BELOW_NORMAL_PRIORITY_CLASS:
PriID = PriBelowNormID;
break;
case IDLE_PRIORITY_CLASS:
PriID = PriIdleID;
break;
}
SendDlgItemMessage (Dlg, IDC_PRIORITY_LIST, CB_SETCURSEL, PriID, 0);
SendDlgItemMessage (Dlg, IDC_METHODS_LIST, CB_SETCURSEL, DefragID, 0);
return;
}
#define IDLETIME 25
wstring OldWindowText = L"";
INT_PTR CALLBACK MainDialogProc (HWND Dlg, UINT Msg, WPARAM WParam, LPARAM LParam)
{
static bool ReEntrance = false;
switch (Msg)
{
case WM_INITDIALOG:
Stopping = false;
SetWindowText (Dlg, GetDefaultTitle().c_str());
SetDisables (Dlg);
InitDialog (Dlg);
SetTimer (Dlg, 1, IDLETIME, NULL);
SetClassLong (Dlg, GCL_HICON, (LONG) LoadIcon (GlobalHInstance, MAKEINTRESOURCE(IDI_ICON)));
QuitWhenDone = false;
LoadSettings (Dlg);
UpdatePriority (Dlg);
return (1);
case WM_TIMER:
if (Defrag != NULL && !ReEntrance)
{
wstring NewTitle;
SendMessage (Dlg, WM_UPDATEINFO, 0, 0);
NewTitle = GetDefragTitle ();
if (NewTitle != OldWindowText)
{
OldWindowText = NewTitle;
SetWindowText (Dlg, NewTitle.c_str());
}
if (Defrag->IsDoneYet() || Defrag->HasError())
{ // This is the code executed when defragging is finished (or stopped :)
if (Defrag->GetDefragType() == DefragAnalyze &&
!Defrag->HasError() &&
!Stopping)
{ // Show report
ReEntrance = true;
DialogBoxParam (GlobalHInstance, MAKEINTRESOURCE (IDD_REPORT),
Dlg, ReportDialogProc, (LPARAM) Defrag);
ReEntrance = false;
}
delete Defrag;
Defrag = NULL;
SetDisables (Dlg);
SetWindowText (Dlg, GetDefaultTitle().c_str());
Stopping = false;
if (QuitWhenDone)
SendMessage (GetDlgItem (Dlg, IDC_QUIT), BM_CLICK, 0, 0);
}
}
SetTimer (Dlg, 1, IDLETIME, NULL);
return (0);
case WM_UPDATEINFO:
UpdateDefragInfo (Dlg);
return (1);
case WM_CLOSE:
SendMessage (GetDlgItem (Dlg, IDC_QUIT), BM_CLICK, 0, 0);
return (1);
case WM_COMMAND:
switch (LOWORD(WParam))
{
case IDC_PRIORITY_LIST:
UpdatePriority (Dlg);
return (1);
case ID_MAIN_HELP:
ShellExecute (Dlg, L"open", L"Fraginator.chm", L"", L".", SW_SHOW);
return (1);
case IDC_QUIT:
if (Defrag == NULL)
{ // This is the code executing when quitting
SaveSettings (Dlg);
EndDialog (Dlg, 0);
}
else
{ // Tell defragging to finish and disable our button
QuitWhenDone = true;
SendMessage (GetDlgItem (Dlg, IDC_STARTSTOP), BM_CLICK, 0, 0);
EnableWindow (GetDlgItem (Dlg, IDC_QUIT), FALSE);
}
return (1);
case IDC_STARTSTOP:
if (Defrag == NULL)
{ // L"Start"
wchar_t Drive[10];
LRESULT ID;
DefragType Method;
HANDLE H;
if (Defrag != NULL)
return (1);
SendMessage (GetDlgItem (Dlg, IDC_DRIVES_LIST), WM_GETTEXT,
sizeof (Drive) - 1, (LPARAM) Drive);
if (wcslen(Drive) != 2 || Drive[1] != L':')
return (1);
ID = SendMessage (GetDlgItem (Dlg, IDC_METHODS_LIST), CB_GETCURSEL, 0, 0);
Method = DefragInvalid;
if (ID == AnalyzeID)
Method = DefragAnalyze;
else
if (ID == FastID)
Method = DefragFast;
else
if (ID == ExtensiveID)
Method = DefragExtensive;
if (Method != DefragInvalid)
{
Defrag = StartDefragThread (Drive, Method, H);
Defrag->SetDoLimitLength (false);
SetWindowText (Dlg, GetDefragTitle().c_str());
SetDisables (Dlg);
}
}
else
{ // L"Stop"
Stopping = true;
Defrag->Stop ();
EnableWindow (GetDlgItem (Dlg, IDC_STARTSTOP), FALSE);
EnableWindow (GetDlgItem (Dlg, IDC_QUIT), FALSE);
}
return (1);
}
}
// Otherwise, return 0 to say we did not process the message.
return (0);
}