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