1 #include "Unfrag.h"
2 #include "MainDialog.h"
3 #include "resource.h"
4 #include "Fraginator.h"
5 #include "Defragment.h"
6 #include "ReportDialog.h"
7
8
9 vector<wstring> DrivesList;
10 LRESULT AnalyzeID;
11 LRESULT FastID;
12 LRESULT ExtensiveID;
13 bool QuitWhenDone;
14 bool Stopping;
15
16
17 LRESULT PriHighID;
18 LRESULT PriAboveNormID;
19 LRESULT PriNormalID;
20 LRESULT PriBelowNormID;
21 LRESULT PriIdleID;
22
23
24 static void InitDialog (HWND Dlg);
25 void UpdateDefragInfo (HWND Dlg);
26 void UpdatePriority (HWND Dlg);
27 wstring GetDefaultTitle (void);
28 wstring GetDefragTitle (void);
29 void SetDisables (HWND Dlg);
30 INT_PTR CALLBACK MainDialogProc (HWND Dlg, UINT Msg, WPARAM WParam, LPARAM LParam);
31
32
InitDialog(HWND Dlg)33 static void InitDialog (HWND Dlg)
34 {
35 // Make internal list
36 DWORD DriveMask;
37 HWND DlgItem;
38 size_t d;
39
40 // Clear out wisecracks line for now
41 SetDlgItemText (Dlg, IDC_WISECRACKS, L"\"Defrag, baby!\"");
42
43 // Make list of logical drives
44 DrivesList.resize (0);
45 DriveMask = GetLogicalDrives ();
46
47 for (d = 0; d < 26; d++)
48 {
49 if (DriveMask & (1 << d))
50 {
51 wstring Name;
52
53 Name = (wchar_t)(L'A' + d);
54 Name += L':';
55 DrivesList.push_back (Name);
56 }
57 }
58
59 // Give list to dropdown list
60 DlgItem = GetDlgItem (Dlg, IDC_DRIVES_LIST);
61 SendMessage (DlgItem, CB_RESETCONTENT, 0, 0);
62 for (d = 0; d < DrivesList.size(); d++)
63 {
64 SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) DrivesList[d].c_str());
65 }
66
67 // Put in defrag methods
68 DlgItem = GetDlgItem (Dlg, IDC_METHODS_LIST);
69 SendMessage (DlgItem, CB_RESETCONTENT, 0, 0);
70 AnalyzeID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Analyze Only");
71 FastID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Fast Defrag");
72 ExtensiveID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Extensive Defrag");
73
74 // Set up process priorities
75 DlgItem = GetDlgItem (Dlg, IDC_PRIORITY_LIST);
76 SendMessage (Dlg, CB_RESETCONTENT, 0, 0);
77 PriHighID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"High");
78 PriAboveNormID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Above Normal");
79 PriNormalID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Normal");
80 PriBelowNormID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Below Normal");
81 PriIdleID = SendMessage (DlgItem, CB_ADDSTRING, 0, (LPARAM) L"Idle");
82 UpdatePriority (Dlg);
83
84 // Reset texts and progress meters
85 SendDlgItemMessage (Dlg, IDC_STATUS, WM_SETTEXT, 0, (LPARAM) L"");
86 SendDlgItemMessage (Dlg, IDC_PERCENT, WM_SETTEXT, 0, (LPARAM) L"");
87 SendDlgItemMessage (Dlg, IDC_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM (0, 10000));
88 SendDlgItemMessage (Dlg, IDC_PROGRESS, PBM_SETPOS, 0, 0);
89
90 return;
91 }
92
93
UpdateDefragInfo(HWND Dlg)94 void UpdateDefragInfo (HWND Dlg)
95 {
96 wchar_t PercentText[100];
97 static double OldPercent = 200.0f;
98 static wstring OldStatus = L"Non";
99 wstring NewStatus;
100 double NewPercent;
101
102 if (Defrag == NULL)
103 return;
104
105 NewPercent = Defrag->GetStatusPercent ();
106 if (NewPercent > 100.0f)
107 NewPercent = 100.0f;
108 if (NewPercent < 0.0f)
109 NewPercent = 0.0f;
110 if (NewPercent != OldPercent)
111 {
112 swprintf (PercentText, L"%6.2f%%", NewPercent);
113 SendDlgItemMessage (Dlg, IDC_PERCENT, WM_SETTEXT, 0, (LPARAM) PercentText);
114 SendDlgItemMessage (Dlg, IDC_PROGRESS, PBM_SETPOS,
115 (WPARAM) (int)(NewPercent * 100.0f), 0);
116 OldPercent = NewPercent;
117 }
118
119 NewStatus = Defrag->GetStatusString ();
120 if (NewStatus != OldStatus)
121 { // Change & characters to && to avoid underlining
122 wstring Status;
123 wstring::iterator it;
124
125 Status = NewStatus;
126 it = Status.begin ();
127 while (it < Status.end())
128 {
129 if (*it == L'&')
130 {
131 Status.insert (it, 1, L'&');
132 it++;
133 }
134
135 it++;
136 }
137
138 SendDlgItemMessage (Dlg, IDC_STATUS, WM_SETTEXT, 0,
139 (LPARAM) Status.c_str());
140
141 OldStatus = NewStatus;
142 }
143
144 return;
145 }
146
147
GetDefaultTitle(void)148 wstring GetDefaultTitle (void)
149 {
150 wstring DefaultText;
151
152 DefaultText = wstring(wstring(APPNAME_GUI) + wstring(L" v") + wstring(APPVER_STR) +
153 wstring(L" (C) 2000 by Rick Brewster"));
154
155 return (DefaultText);
156 }
157
158
GetDefragTitle(void)159 wstring GetDefragTitle (void)
160 {
161 wstring DefragText;
162 wchar_t Percent[10];
163
164 swprintf (Percent, L"%.2f%%", Defrag->GetStatusPercent());
165
166 DefragText = GetDefaultTitle ();
167 if (Defrag != NULL)
168 {
169 DefragText = wstring(Percent) + wstring (L" - ") + Defrag->GetVolume().GetRootPath() +
170 wstring (L" - ") + DefragText;
171 }
172
173 return (DefragText);
174 }
175
176
SetDisables(HWND Dlg)177 void SetDisables (HWND Dlg)
178 {
179 // If a defrag is in process, set L'Start' button to say L'Stop' and disable
180 // the Select Drive and Select Action controls
181 if (Defrag != NULL && !Defrag->IsDoneYet() && !Defrag->HasError())
182 {
183 SendMessage (GetDlgItem (Dlg, IDC_STARTSTOP), WM_SETTEXT, 0, (LPARAM) L"Stop");
184 EnableWindow (GetDlgItem (Dlg, IDC_DRIVES_LIST), FALSE);
185 EnableWindow (GetDlgItem (Dlg, IDC_METHODS_LIST), FALSE);
186 }
187 else
188 {
189 SendMessage (GetDlgItem (Dlg, IDC_STARTSTOP), WM_SETTEXT, 0, (LPARAM) L"Start");
190 EnableWindow (GetDlgItem (Dlg, IDC_STARTSTOP), TRUE);
191 EnableWindow (GetDlgItem (Dlg, IDC_QUIT), TRUE);
192 EnableWindow (GetDlgItem (Dlg, IDC_DRIVES_LIST), TRUE);
193 EnableWindow (GetDlgItem (Dlg, IDC_METHODS_LIST), TRUE);
194 }
195
196 return;
197 }
198
199
UpdatePriority(HWND Dlg)200 void UpdatePriority (HWND Dlg)
201 {
202 LRESULT Id;
203 DWORD Priority;
204
205 Id = SendDlgItemMessage (Dlg, IDC_PRIORITY_LIST, CB_GETCURSEL, 0, 0);
206
207 if (Id == PriHighID)
208 Priority = HIGH_PRIORITY_CLASS;
209 else
210 if (Id == PriAboveNormID)
211 Priority = ABOVE_NORMAL_PRIORITY_CLASS;
212 else
213 if (Id == PriNormalID)
214 Priority = NORMAL_PRIORITY_CLASS;
215 else
216 if (Id == PriBelowNormID)
217 Priority = BELOW_NORMAL_PRIORITY_CLASS;
218 else
219 if (Id == PriIdleID)
220 Priority = IDLE_PRIORITY_CLASS;
221 else
222 return;
223
224 SetPriorityClass (GetCurrentProcess(), Priority);
225 return;
226 }
227
228
229 // Save settings (ie, process priority and defrag type options)
GetRegKeys(HKEY * RegKeyResult)230 bool GetRegKeys (HKEY *RegKeyResult)
231 {
232 HKEY RegKey;
233 LONG Error;
234
235 Error = RegCreateKeyEx
236 (
237 HKEY_CURRENT_USER,
238 L"Software\\Fraginator",
239 0,
240 NULL,
241 REG_OPTION_NON_VOLATILE,
242 KEY_ALL_ACCESS,
243 NULL,
244 &RegKey,
245 NULL
246 );
247
248 if (Error != ERROR_SUCCESS)
249 return (false);
250
251 *RegKeyResult = RegKey;
252 return (true);
253 }
254
255
DoneRegKey(HKEY RegKey)256 bool DoneRegKey (HKEY RegKey)
257 {
258 RegCloseKey (RegKey);
259 return (true);
260 }
261
262
SaveSettings(HWND Dlg)263 void SaveSettings (HWND Dlg)
264 {
265 LRESULT DefragID;
266 DWORD DefragVal;
267 LRESULT PriID;
268 DWORD PriVal;
269 HKEY RegKey;
270
271 DefragID = SendDlgItemMessage (Dlg, IDC_METHODS_LIST, CB_GETCURSEL, 0, 0);
272 PriID = SendDlgItemMessage (Dlg, IDC_PRIORITY_LIST, CB_GETCURSEL, 0, 0);
273
274 // Action
275 if (DefragID == AnalyzeID)
276 DefragVal = (DWORD) DefragAnalyze;
277 else
278 if (DefragID == FastID)
279 DefragVal = (DWORD) DefragFast;
280 else
281 if (DefragID == ExtensiveID)
282 DefragVal = (DWORD) DefragExtensive;
283
284 // Process Priority
285 if (PriID == PriHighID)
286 PriVal = HIGH_PRIORITY_CLASS;
287 else
288 if (PriID == PriAboveNormID)
289 PriVal = ABOVE_NORMAL_PRIORITY_CLASS;
290 else
291 if (PriID == PriNormalID)
292 PriVal = NORMAL_PRIORITY_CLASS;
293 else
294 if (PriID == PriBelowNormID)
295 PriVal = BELOW_NORMAL_PRIORITY_CLASS;
296 else
297 if (PriID == PriIdleID)
298 PriVal = IDLE_PRIORITY_CLASS;
299
300 if (!GetRegKeys (&RegKey))
301 return;
302
303 RegSetValueEx
304 (
305 RegKey,
306 L"Default Action",
307 0,
308 REG_DWORD,
309 (CONST BYTE *)&DefragVal,
310 sizeof (DefragVal)
311 );
312
313 RegSetValueEx
314 (
315 RegKey,
316 L"Process Priority",
317 0,
318 REG_DWORD,
319 (CONST BYTE *)&PriVal,
320 sizeof (PriVal)
321 );
322
323 DoneRegKey (RegKey);
324 return;
325 }
326
327
LoadSettings(HWND Dlg)328 void LoadSettings (HWND Dlg)
329 {
330 DefragType DType;
331 DWORD DTypeVal;
332 LRESULT DefragID;
333 DWORD PriVal;
334 LRESULT PriID;
335 HKEY RegKey;
336 DWORD RegType;
337 DWORD RegSize;
338 LONG Error;
339
340 if (!GetRegKeys (&RegKey))
341 return;
342
343 RegSize = sizeof (DTypeVal);
344 RegType = REG_DWORD;
345
346 Error = RegQueryValueEx
347 (
348 RegKey,
349 L"Default Action",
350 0,
351 &RegType,
352 (BYTE *)&DTypeVal,
353 &RegSize
354 );
355
356 if (Error != ERROR_SUCCESS)
357 DTypeVal = DefragAnalyze;
358
359 Error = RegQueryValueEx
360 (
361 RegKey,
362 L"Process Priority",
363 0,
364 &RegType,
365 (BYTE *)&PriVal,
366 &RegSize
367 );
368
369 DoneRegKey (RegKey);
370
371 if (Error != ERROR_SUCCESS)
372 PriVal = NORMAL_PRIORITY_CLASS;
373
374 DType = (DefragType) DTypeVal;
375 switch (DType)
376 {
377 default:
378 case DefragAnalyze:
379 DefragID = AnalyzeID;
380 break;
381
382 case DefragFast:
383 DefragID = FastID;
384 break;
385
386 case DefragExtensive:
387 DefragID = ExtensiveID;
388 break;
389 }
390
391 switch (PriVal)
392 {
393 case HIGH_PRIORITY_CLASS:
394 PriID = PriHighID;
395 break;
396
397 case ABOVE_NORMAL_PRIORITY_CLASS:
398 PriID = PriAboveNormID;
399 break;
400
401 default:
402 case NORMAL_PRIORITY_CLASS:
403 PriID = PriNormalID;
404 break;
405
406 case BELOW_NORMAL_PRIORITY_CLASS:
407 PriID = PriBelowNormID;
408 break;
409
410 case IDLE_PRIORITY_CLASS:
411 PriID = PriIdleID;
412 break;
413 }
414
415 SendDlgItemMessage (Dlg, IDC_PRIORITY_LIST, CB_SETCURSEL, PriID, 0);
416 SendDlgItemMessage (Dlg, IDC_METHODS_LIST, CB_SETCURSEL, DefragID, 0);
417 return;
418 }
419
420
421 #define IDLETIME 25
422 wstring OldWindowText = L"";
423
MainDialogProc(HWND Dlg,UINT Msg,WPARAM WParam,LPARAM LParam)424 INT_PTR CALLBACK MainDialogProc (HWND Dlg, UINT Msg, WPARAM WParam, LPARAM LParam)
425 {
426 static bool ReEntrance = false;
427
428 switch (Msg)
429 {
430 case WM_INITDIALOG:
431 Stopping = false;
432 SetWindowText (Dlg, GetDefaultTitle().c_str());
433 SetDisables (Dlg);
434 InitDialog (Dlg);
435 SetTimer (Dlg, 1, IDLETIME, NULL);
436 SetClassLong (Dlg, GCL_HICON, (LONG) LoadIcon (GlobalHInstance, MAKEINTRESOURCE(IDI_ICON)));
437 QuitWhenDone = false;
438 LoadSettings (Dlg);
439 UpdatePriority (Dlg);
440 return (1);
441
442
443 case WM_TIMER:
444 if (Defrag != NULL && !ReEntrance)
445 {
446 wstring NewTitle;
447
448 SendMessage (Dlg, WM_UPDATEINFO, 0, 0);
449
450 NewTitle = GetDefragTitle ();
451 if (NewTitle != OldWindowText)
452 {
453 OldWindowText = NewTitle;
454 SetWindowText (Dlg, NewTitle.c_str());
455 }
456
457 if (Defrag->IsDoneYet() || Defrag->HasError())
458 { // This is the code executed when defragging is finished (or stopped :)
459 if (Defrag->GetDefragType() == DefragAnalyze &&
460 !Defrag->HasError() &&
461 !Stopping)
462 { // Show report
463 ReEntrance = true;
464
465 DialogBoxParam (GlobalHInstance, MAKEINTRESOURCE (IDD_REPORT),
466 Dlg, ReportDialogProc, (LPARAM) Defrag);
467
468 ReEntrance = false;
469 }
470
471 delete Defrag;
472 Defrag = NULL;
473 SetDisables (Dlg);
474 SetWindowText (Dlg, GetDefaultTitle().c_str());
475
476 Stopping = false;
477
478 if (QuitWhenDone)
479 SendMessage (GetDlgItem (Dlg, IDC_QUIT), BM_CLICK, 0, 0);
480 }
481 }
482
483 SetTimer (Dlg, 1, IDLETIME, NULL);
484 return (0);
485
486
487 case WM_UPDATEINFO:
488 UpdateDefragInfo (Dlg);
489 return (1);
490
491
492 case WM_CLOSE:
493 SendMessage (GetDlgItem (Dlg, IDC_QUIT), BM_CLICK, 0, 0);
494 return (1);
495
496
497 case WM_COMMAND:
498 switch (LOWORD(WParam))
499 {
500 case IDC_PRIORITY_LIST:
501 UpdatePriority (Dlg);
502 return (1);
503
504
505 case ID_MAIN_HELP:
506 ShellExecute (Dlg, L"open", L"Fraginator.chm", L"", L".", SW_SHOW);
507 return (1);
508
509
510 case IDC_QUIT:
511 if (Defrag == NULL)
512 { // This is the code executing when quitting
513 SaveSettings (Dlg);
514 EndDialog (Dlg, 0);
515 }
516 else
517 { // Tell defragging to finish and disable our button
518 QuitWhenDone = true;
519 SendMessage (GetDlgItem (Dlg, IDC_STARTSTOP), BM_CLICK, 0, 0);
520 EnableWindow (GetDlgItem (Dlg, IDC_QUIT), FALSE);
521 }
522 return (1);
523
524
525 case IDC_STARTSTOP:
526 if (Defrag == NULL)
527 { // L"Start"
528 wchar_t Drive[10];
529 LRESULT ID;
530 DefragType Method;
531 HANDLE H;
532
533 if (Defrag != NULL)
534 return (1);
535
536 SendMessage (GetDlgItem (Dlg, IDC_DRIVES_LIST), WM_GETTEXT,
537 sizeof (Drive) - 1, (LPARAM) Drive);
538
539 if (wcslen(Drive) != 2 || Drive[1] != L':')
540 return (1);
541
542 ID = SendMessage (GetDlgItem (Dlg, IDC_METHODS_LIST), CB_GETCURSEL, 0, 0);
543 Method = DefragInvalid;
544 if (ID == AnalyzeID)
545 Method = DefragAnalyze;
546 else
547 if (ID == FastID)
548 Method = DefragFast;
549 else
550 if (ID == ExtensiveID)
551 Method = DefragExtensive;
552
553 if (Method != DefragInvalid)
554 {
555 Defrag = StartDefragThread (Drive, Method, H);
556 Defrag->SetDoLimitLength (false);
557 SetWindowText (Dlg, GetDefragTitle().c_str());
558 SetDisables (Dlg);
559 }
560 }
561 else
562 { // L"Stop"
563 Stopping = true;
564 Defrag->Stop ();
565 EnableWindow (GetDlgItem (Dlg, IDC_STARTSTOP), FALSE);
566 EnableWindow (GetDlgItem (Dlg, IDC_QUIT), FALSE);
567 }
568 return (1);
569 }
570 }
571
572 // Otherwise, return 0 to say we did not process the message.
573 return (0);
574 }
575