Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/windirstat.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbseifert <none@none>2003-10-30 09:08:04 +0300
committerbseifert <none@none>2003-10-30 09:08:04 +0300
commitf049e2df4b09dc19a7d76e2d33b8cfcb5370e9dc (patch)
treef2f04cd33835591b8e32953d093a1527a75f3464
parent98a363ad8bd075b1abd702b7d380692ec0c470d6 (diff)
Initial revision
-rw-r--r--README.txt105
-rw-r--r--TESTPLAN.txt265
-rw-r--r--common/commonhelpers.cpp139
-rw-r--r--common/commonhelpers.h32
-rw-r--r--common/cotaskmem.h69
-rw-r--r--common/mdexceptions.h167
-rw-r--r--wdsh0407/Table_of_Contents.hhc76
-rw-r--r--wdsh0407/actions.htm52
-rw-r--r--wdsh0407/configuration.htm33
-rw-r--r--wdsh0407/coupling.htm36
-rw-r--r--wdsh0407/deinstallation.htm21
-rw-r--r--wdsh0407/directorytree.htm65
-rw-r--r--wdsh0407/extensionlist.htm34
-rw-r--r--wdsh0407/faq.htm46
-rw-r--r--wdsh0407/format.css9
-rw-r--r--wdsh0407/gnufdl.htm389
-rw-r--r--wdsh0407/legend.htm59
-rw-r--r--wdsh0407/limits.htm29
-rw-r--r--wdsh0407/selectdrivesdialog.htm36
-rw-r--r--wdsh0407/sorting.htm34
-rw-r--r--wdsh0407/tree.jpgbin0 -> 3870 bytes
-rw-r--r--wdsh0407/treemap.htm46
-rw-r--r--wdsh0407/userdefinedcleanups.htm66
-rw-r--r--wdsh0407/wdsh0407.vcproj146
-rw-r--r--wdsh0407/whatisatree.htm67
-rw-r--r--wdsh0407/windirstat.hhp43
-rw-r--r--wdsh0407/windirstat.htm67
-rw-r--r--wdshelp/Table_of_Contents.hhc76
-rw-r--r--wdshelp/actions.htm50
-rw-r--r--wdshelp/configuration.htm30
-rw-r--r--wdshelp/coupling.htm35
-rw-r--r--wdshelp/deinstallation.htm21
-rw-r--r--wdshelp/directorytree.htm61
-rw-r--r--wdshelp/extensionlist.htm32
-rw-r--r--wdshelp/faq.htm45
-rw-r--r--wdshelp/format.css9
-rw-r--r--wdshelp/gnufdl.htm389
-rw-r--r--wdshelp/legend.htm56
-rw-r--r--wdshelp/limits.htm29
-rw-r--r--wdshelp/original_n_baum55.gifbin0 -> 31152 bytes
-rw-r--r--wdshelp/selectdrivesdialog.htm33
-rw-r--r--wdshelp/sorting.htm30
-rw-r--r--wdshelp/tree.jpgbin0 -> 3870 bytes
-rw-r--r--wdshelp/treemap.htm43
-rw-r--r--wdshelp/userdefinedcleanups.htm67
-rw-r--r--wdshelp/wdshelp.vcproj122
-rw-r--r--wdshelp/whatisatree.htm62
-rw-r--r--wdshelp/windirstat.hhp43
-rw-r--r--wdshelp/windirstat.htm63
-rw-r--r--wdsr0407/res/Toolbar.bmpbin0 -> 1678 bytes
-rw-r--r--wdsr0407/res/bitmap1.bmpbin0 -> 1462 bytes
-rw-r--r--wdsr0407/res/icon1.icobin0 -> 3638 bytes
-rw-r--r--wdsr0407/res/license.txt345
-rw-r--r--wdsr0407/res/windirstat.manifest22
-rw-r--r--wdsr0407/resource.h243
-rw-r--r--wdsr0407/wdsr0407.vcproj249
-rw-r--r--wdsr0407/windirstat.rc818
-rw-r--r--windirstat.sln75
-rw-r--r--windirstat/DeleteWarningDlg.cpp64
-rw-r--r--windirstat/DeleteWarningDlg.h46
-rw-r--r--windirstat/ModalApiShuttle.cpp61
-rw-r--r--windirstat/ModalApiShuttle.h60
-rw-r--r--windirstat/ModalSendMail.cpp124
-rw-r--r--windirstat/ModalSendMail.h47
-rw-r--r--windirstat/ModalShellApi.cpp100
-rw-r--r--windirstat/ModalShellApi.h52
-rw-r--r--windirstat/PageCleanups.cpp359
-rw-r--r--windirstat/PageCleanups.h100
-rw-r--r--windirstat/PageColors.cpp360
-rw-r--r--windirstat/PageColors.h102
-rw-r--r--windirstat/PageGeneral.cpp125
-rw-r--r--windirstat/PageGeneral.h53
-rw-r--r--windirstat/PageTreelist.cpp120
-rw-r--r--windirstat/PageTreelist.h57
-rw-r--r--windirstat/PageTreemap.cpp295
-rw-r--r--windirstat/PageTreemap.h100
-rw-r--r--windirstat/ReportBugDlg.cpp236
-rw-r--r--windirstat/ReportBugDlg.h70
-rw-r--r--windirstat/SelectDrivesDlg.cpp556
-rw-r--r--windirstat/SelectDrivesDlg.h133
-rw-r--r--windirstat/TreeListControl.cpp798
-rw-r--r--windirstat/TreeListControl.h160
-rw-r--r--windirstat/aboutdlg.cpp269
-rw-r--r--windirstat/aboutdlg.h75
-rw-r--r--windirstat/colorbutton.cpp137
-rw-r--r--windirstat/colorbutton.h72
-rw-r--r--windirstat/dirstatdoc.cpp1427
-rw-r--r--windirstat/dirstatdoc.h206
-rw-r--r--windirstat/dirstatview.cpp308
-rw-r--r--windirstat/dirstatview.h86
-rw-r--r--windirstat/getosplatformstring.cpp97
-rw-r--r--windirstat/getosplatformstring.h27
-rw-r--r--windirstat/globalhelpers.cpp505
-rw-r--r--windirstat/globalhelpers.h53
-rw-r--r--windirstat/graphview.cpp438
-rw-r--r--windirstat/graphview.h88
-rw-r--r--windirstat/helpmap.h24
-rw-r--r--windirstat/item.cpp1814
-rw-r--r--windirstat/item.h224
-rw-r--r--windirstat/layout.cpp115
-rw-r--r--windirstat/layout.h56
-rw-r--r--windirstat/mainframe.cpp933
-rw-r--r--windirstat/mainframe.h162
-rw-r--r--windirstat/mountpoints.cpp235
-rw-r--r--windirstat/mountpoints.h56
-rw-r--r--windirstat/myimagelist.cpp233
-rw-r--r--windirstat/myimagelist.h61
-rw-r--r--windirstat/options.cpp931
-rw-r--r--windirstat/options.h263
-rw-r--r--windirstat/osspecific.cpp212
-rw-r--r--windirstat/osspecific.h137
-rw-r--r--windirstat/ownerdrawnlistcontrol.cpp460
-rw-r--r--windirstat/ownerdrawnlistcontrol.h88
-rw-r--r--windirstat/pacman.cpp194
-rw-r--r--windirstat/pacman.h51
-rw-r--r--windirstat/res/Toolbar.bmpbin0 -> 1678 bytes
-rw-r--r--windirstat/res/bitmap1.bmpbin0 -> 1462 bytes
-rw-r--r--windirstat/res/icon1.icobin0 -> 3638 bytes
-rw-r--r--windirstat/res/license.txt345
-rw-r--r--windirstat/res/windirstat.manifest22
-rw-r--r--windirstat/resource.h243
-rw-r--r--windirstat/selectobject.h116
-rw-r--r--windirstat/set.h56
-rw-r--r--windirstat/sortinglistcontrol.cpp283
-rw-r--r--windirstat/sortinglistcontrol.h105
-rw-r--r--windirstat/stdafx.cpp26
-rw-r--r--windirstat/stdafx.h88
-rw-r--r--windirstat/typeview.cpp418
-rw-r--r--windirstat/typeview.h127
-rw-r--r--windirstat/windirstat.cpp558
-rw-r--r--windirstat/windirstat.h108
-rw-r--r--windirstat/windirstat.rc864
-rw-r--r--windirstat/windirstat.vcproj551
133 files changed, 23304 insertions, 0 deletions
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..3a88181
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,105 @@
+=============================================================================
+WinDirStat - Windows Directory Statistics
+(c) 2003 Bernhard Seifert (bseifert@users.sourceforge.net)
+=============================================================================
+
+This project, made up of
+setup, wdsh0407, wdshelp, wdsr0407, and windirstat
+
+is distributed under the terms of the GPL v2 (executables)
+respectively GNU FDL (help files).
+
+See Resource Files/license.txt and wdshelp/gnufdl.htm.
+
+The tree-GIF was found in http://www.world-in-motion.de - I hope, I
+don't violate any copyright (tell me).
+
+
+=============================================================================
+WinDirStat is a disk usage statistics viewer and cleanup tool for MS Windows
+(all current variants). It shows disk, file and directory sizes in a treelist
+as well as graphically in a treemap, much like KDirStat and Sequoiaview.
+
+
+=============================================================================
+WinDirStat is an application written in Visual C++ using MFC 7.0.
+It runs on MS Windows (9x, NT, 2000, XP).
+
+It shows where all your disk space is gone and helps you clean it up.
+
+Design and many details are based on KDirStat (kdirstat.sourceforge.net).
+WinDirStat is "a KDirStat re-programmed for MS Windows".
+
+The directory tree is simultanously shown as a treelist and as a treemap.
+One can effortlessly gain an impression of the proportions on the hard disk(s).
+
+Major features:
+* 3 views, Directory tree, Treemap and Extension list, coupled with each other,
+* Built-in cleanup actions including Open, Delete, Show Properties,
+* User defined cleanup actions (command line based),
+* Language can be set to English or German; further translations can be added
+ as resource DLLs,
+* Online-Help,
+* A little setup.exe which installs the files and shortcuts.
+
+
+
+=============================================================================
+This is a Microsoft Visual Studio.NET 2003 - Project.
+Apart from CString::AppendFormat() I didn't use any MFC 7.0 specific features.
+So this project can easily be ported to Visual Studio 6.0.
+
+Projects included in the workspace
+----------------------------------
+setup -> setup.exe
+wdsh0407 -> German Helpfile wdsh0407.chm
+wdshelp -> English Helpfile windirstat.chm
+wdsr0407 -> German Resource DLL wdsr0407.dll
+windirstat -> windirstat.exe (including English resources).
+
+The Microsoft redistributable file shfolder.dll is also included.
+
+I've commented
+- every source file
+- every class
+- every data member.
+
+I haven't commented most member functions, maybe because my working English
+is not so good (I mostly would have duplicated the function name).
+
+
+=============================================================================
+How to create a resource dll.
+
+* Determine the language id xx und sub-language id yy as defined in winnt.h.
+
+* Create a new project wdsrxxyy.dll: Visual C++ Project
+ - Win 32 Project - Dll - empty project.
+
+* Copy windirstat.rc, resource.h and res/*.* into the
+ wdsrxxyy-Folder respective the res-subfolder.
+
+* In the linker options - advanced set Resource Only DLL to Yes.
+
+* In Text Include 3 adjust the LANGUAGE
+
+* Remove the manifest and the Versioninfo
+
+* Translate the rc-File
+
+* Note that the string IDS_RESOURCEVERSION (currently = "Resource Version 1")
+ must not be changed, otherwise the resource dll is not accepted
+ by windirstat.exe.
+ This version string may be changed in future versions of windirstat, if
+ the resources must be changed, too.
+
+=============================================================================
+
+I'm distributing the ANSI variant. Feel free to build the UNICODE variant
+(will not run on Windows 9x).
+
+
+=============================================================================
+testplan.txt may be useful for future releases.
+
+---------------------------------- eof --------------------------------------
diff --git a/TESTPLAN.txt b/TESTPLAN.txt
new file mode 100644
index 0000000..cbca97f
--- /dev/null
+++ b/TESTPLAN.txt
@@ -0,0 +1,265 @@
+Windirstat 1.0 - Test Plan
+==========================
+
+Quick Overall Test
+------------------
+--> There are 6 files in the binary distribution of WinDirStat:
+ setup.exe, shfolder.dll, wsdh0407.chm, wdsr0407.dll, windirstat.chm, windirstat.exe.
+--> The version infos of the executbles point to the about box.
+
+Delete C:\program files\windirstat
+Delete all shortcuts to windirstat
+Delete HKCU\Software\seifert\windirstat
+
+Start setup.exe
+--> On German systems, the language is German
+ On other systems, the language is English.
+Using the default settings, proceed through the installation
+--> WinDirStat starts up
+ On German systems, in German
+ On other systems, in English.
+ The Select Drives Dialog comes up with the default "All local drives".
+Press OK.
+--> All local drives are scanned, with pacman animation.
+ Then the treemap and extension list are shown.
+Quit WinDirStat.
+--> In C:\program files\windirstat there are 4 files.
+--> There is a shortcut to windirstat.exe on the desktop (all users).
+--> There is a shortcut to windirstat exe in the Start menu (all users on NT, local user on W9x).
+--> There is a registry key in HKCU\Software\Seifert\windirstat.
+
+Critical Features
+-----------------
+Select the English Language and restart WinDirStat
+(the English version should be tested best).
+
+Drag+Drop a folder onto the desktop shortcut
+--> WinDirStat comes up with this folder as root.
+Drag+Drop an empty folder onto the desktop shortcut
+--> WinDirStat comes up with a black treemap.
+Insert an empty diskette into drive A:
+Select this drive as root
+--> WinDirStat comes up with a black treemap.
+Select some big drives
+During the scan quit WinDirStat
+--> WinDirStat quits silently.
+
+Copy some big directories to C:\temp (for deletion).
+For the following "during the scan" tests it is is good idea,
+to activate the "cross file system boundaries" option and
+mount e.g. C: to D:\mount\c and D: to C:\mount\d. Because
+of the circularity the scan will then last forever.
+
+Select some big drives
+During the scan refresh some items
+--> WinDirStat refreshs the items.
+During the scan expand and collapse folders
+During the scan open the about box
+--> The scan continues even with the about box open.
+During the scan delete a file under c:\temp (to the recycle bin)
+--> The extra warning comes up.
+Say No
+--> Nothing happens.
+Delete the file under C:\temp again
+--> The extra warning comes up again.
+Say Yes
+--> The Shell warning comes up. This dialog is modal to WinDirStat.
+Say No
+--> Nothing happens (the item is refeshed).
+Delete the file under C:\temp again
+--> The extra warning comes up again
+Say "Don't show this warning again"
+Say No.
+--> Nothing happens.
+Delete the file under C:\temp again
+--> The extra waring comes up again
+Say "Don't show this warning again"
+Say Yes.
+--> The Shell warning comes up. This dialog is modal to WinDirStat.
+Say Yes.
+--> The file is deleted, the view is refreshed.
+Delete another file under C:\temp.
+--> The Shell warning comes up. This dialog is modal to WinDirStat.
+Say No.
+
+--> The menu Clean Up shows Empty Recycle Bin with at least 1 item.
+--> This information corresponds to the properties of the recycle bin.
+During the scan do Clean Up->Empty Recycle Bin
+--> A Shell warning comes up. This dialog is modal to WinDirStat.
+Say No
+--> Nothing happens
+During the scan do Clean Up->Empty Recycle Bin again
+--> A Shell warning comes up. This dialog is modal to WinDirStat.
+Say Yes
+--> Your recycle bin is emptied, the recycler folders are refreshed,
+During the scan delete a big folder in C:\temp.
+Confirm the Shell warning with Yes.
+--> The deletion progress dialog is modal to WinDirStat.
+
+Deactivate the "cross file system boundaries" option.
+--> The 2 mount points are refreshed and empty. The scan completes.
+
+When the scan is complete, select a file deep in the tree.
+Repeatedly "select parent" and "re-select child" by keyboard, context menu and main menu.
+Repeatedly "select parent". Then select a different item.
+--> "re-select child" is disabled.
+Repeatedly "zoom in" and "zoom out" by keyboard, context menu and main menu.
+Zoom in some levels.
+Select an item outside of the zoom root.
+--> The zoom is place to the common ancestor of the item and the pervious zoom root.
+
+Delete folder in C:\temp.
+--> The item is refreshed. The treemap is dimmed and then rebuilt.
+
+Resize the main window.
+--> The treemap is dimmed and then rebuilt.
+
+F9
+--> Shows/hides the treemap
+
+F8
+--> Shows/hides the extension list
+
+F6
+--> Shows/hides <free space>
+--> The free space correspondes to the properties of the drive.
+
+F7
+--> Shows/hides <unknown>
+
+For NT and W9x DO
+ For each item type (My Computer, drive, folder, file, <Files>, <Freespace>, <Unknown>) DO
+ For each access method (Main menu, context menu, toolbar, shortcut)
+ Open Item
+ Copy Path
+ Explorer here
+ Command prompt here
+ Refresh selected
+ Delete to recycle bin
+ Delete (no way to undelete)
+ Properties
+ Send email to Owner
+ --> The action is either disabled or works as expected.
+ NEXT access method
+ NEXT item type
+NEXT platform
+
+
+Other Features
+--------------
+Play with the Select Drives Dialog
+--> It works as expected.
+--> A double click on a drive opens that drive alone.
+--> The selection is persistent.
+--> UNC Paths work.
+
+Online Help
+--> Is available in the selected Language
+--> Is accessible through three points: F1, Help about Treemaps, User defined Cleanups Help
+--> All hyperlinks on the first page work.
+
+About box
+--> 3 Tabs, all links work.
+
+Report Bug/Feedback
+Cancel.
+--> It disappears.
+Fill in some data. Press OK.
+--> The email client comes up modaly.
+
+Options-General
+--> works as expected.
+Options->Directory List
+--> works as expected.
+Options->Treemap
+--> works as expected.
+
+Change Column widths and column order
+--> The settings are persistent
+Change Sorting
+--> works as expected
+
+Change the size of the dialogs Select Drives,
+Report Bug, Aboutbox
+--> size is persistent, position is restored to center always
+
+Minimize WinDirStat and close it via the system menu.
+Start WinDirStat
+--> It opens up in the restored state.
+
+
+User defined Cleanups
+---------------------
+Test cleanup 1: 'CD & PAUSE' (NT), resp. 'CD > dir.txt' (W9x)
+Test cleanup 2: 'C: & CD 'program files' & CD windirstat & windirstat "%p"' (NT)
+ 'windirstat "%p"' (set a PATH to windirstat under W9x)
+Test cleanup 3: 'echo %p %n %sp %sn & PAUSE' (NT)
+ 'echo %p %n %sp %sn > echo.txt' (W9x)
+--> The 3 UDCs appear in the main menu and the directory tree context menu
+--> They work as expected
+--> They are accessible through their shortcuts
+FOR each option (Works for..., Recurse, Confirmation, Show Console, Wait, Refresh policy)
+ --> The option works as expected
+NEXT option
+--> The Up and Down button work as expected.
+Leave WinDirStat and start it again.
+--> The UDCs are still there.
+Disable the test cleanups.
+--> They disappear from the menus.
+
+
+Setup Options
+-------------
+Delete C:\program files\windirstat
+Delete all shortcuts to windirstat
+Delete HKCU\Software\seifert\windirstat
+
+Start setup.exe
+Cancel.
+--> setup quits.
+Start setup.exe
+Select the folder like C:\temp\windirstat (temp exists)
+--> No warning about non-existent directory
+Select the folder C:\temp\wds
+--> Warning, whether c:\temp\wds shall be created
+Say no.
+--> The wizard doesn't proceed.
+Say yes.
+--> The wizard proceeds. C:\temp\wds is created.
+Go back and select C:\programme\windirstat again.
+Deselect both shortcut options. Finish.
+--> windirstat is installed but without shortcuts.
+Start setup.exe
+Select only "create shortcut on desktop"
+--> Only one shortcut on the desktop is created.
+Start setup.exe
+Select only "create shortcut in the start menu".
+--> Shortcut in the Start->Programs-Menu is created.
+
+Special cases
+-------------
+Delete C:\program files\windirstat
+Delete all shortcuts to windirstat
+Delete HKCU\Software\seifert\windirstat
+
+Logon as a under-priviledged user.
+Perform setup.exe
+--> what happens?
+Start windirstat
+--> what happens?
+
+Set the color depth to 256 colors or start WinDirStat under Terminal Server.
+--> The extension list show only 8 colors, not 12.
+
+Start setup.exe from floppy disk.
+--> It works as expected.
+
+Start setup.exe from CD
+--> It works as expected.
+
+Start WinDirStat from CD
+--> It works fine.
+
+Set the Desktop design to "XP"
+--> All windirstat controls are XP-like.
+
diff --git a/common/commonhelpers.cpp b/common/commonhelpers.cpp
new file mode 100644
index 0000000..03735ff
--- /dev/null
+++ b/common/commonhelpers.cpp
@@ -0,0 +1,139 @@
+// commonhelpers.cpp - Implementation of common global helper functions
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
+#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#include <afxwin.h> // MFC core and standard components
+#include <atlbase.h> // CComPtr, USES_CONVERSION
+
+#include "mdexceptions.h"
+
+#include "commonhelpers.h"
+
+
+CString GetShellExecuteError(UINT u)
+{
+ CString s;
+
+ switch (u)
+ {
+ case 0: s=_T("The operating system is out of memory or resources."); break;
+ case ERROR_FILE_NOT_FOUND: s=_T("The specified file was not found."); break;
+ case ERROR_PATH_NOT_FOUND: s=_T("The specified path was not found."); break;
+ case ERROR_BAD_FORMAT: s=_T("The .exe file is invalid (non-Microsoft Win32 .exe or error in .exe image)."); break;
+ case SE_ERR_ACCESSDENIED: s=_T("The operating system denied access to the specified file."); break;
+ case SE_ERR_ASSOCINCOMPLETE:s=_T("The file name association is incomplete or invalid."); break;
+ case SE_ERR_DDEBUSY: s=_T("The Dynamic Data Exchange (DDE) transaction could not be completed because other DDE transactions were being processed."); break;
+ case SE_ERR_DDEFAIL: s=_T("The DDE transaction failed."); break;
+ case SE_ERR_DDETIMEOUT: s=_T("The DDE transaction could not be completed because the request timed out."); break;
+ case SE_ERR_DLLNOTFOUND: s=_T("The specified dynamic-link library (DLL) was not found."); break;
+ case SE_ERR_NOASSOC: s=_T("There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable."); break;
+ case SE_ERR_OOM: s=_T("There was not enough memory to complete the operation."); break;
+ case SE_ERR_SHARE: s=_T("A sharing violation occurred"); break;
+ default: s.Format(_T("Error Number %d"), u); break;
+ }
+
+ return s;
+}
+
+
+CString MyStrRetToString(const LPITEMIDLIST pidl, const STRRET *strret)
+{
+ // StrRetToStr() is not always available (e.g. on Windows 98).
+ // So we use an own function instead.
+ USES_CONVERSION;
+
+ CString s;
+
+ switch (strret->uType)
+ {
+ case STRRET_CSTR:
+ s= strret->cStr;
+ break;
+ case STRRET_OFFSET:
+ s= A2T((char *)pidl + strret->uOffset);
+ break;
+ case STRRET_WSTR:
+ s= W2T(strret->pOleStr);
+ break;
+ }
+
+ return s;
+}
+
+void MyShellExecute(HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFile, LPCTSTR lpParameters, LPCTSTR lpDirectory, INT nShowCmd) throw (CException *)
+{
+ CWaitCursor wc;
+
+ UINT h= (UINT)ShellExecute(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd);
+ if (h <= 32)
+ MdThrowStringExceptionF(_T("ShellExecute failed: %1!s!"), GetShellExecuteError(h));
+}
+
+
+CString GetBaseNameFromPath(LPCTSTR path)
+{
+ CString s= path;
+ int i= s.ReverseFind(_T('\\'));
+ if (i < 0)
+ return s;
+ return s.Mid(i + 1);
+}
+
+bool FileExists(LPCTSTR path)
+{
+ CFileFind finder;
+ BOOL b= finder.FindFile(path);
+ if (b)
+ {
+ finder.FindNextFile();
+ return !finder.IsDirectory();
+ }
+ else
+ {
+ return false;
+ }
+}
+
+CString LoadString(UINT resId)
+{
+ return MAKEINTRESOURCE(resId);
+}
+
+CString GetAppFileName()
+{
+ CString s;
+ VERIFY(GetModuleFileName(NULL, s.GetBuffer(_MAX_PATH), _MAX_PATH));
+ s.ReleaseBuffer();
+ return s;
+}
+
+CString GetAppFolder()
+{
+ CString s= GetAppFileName();
+ int i= s.ReverseFind(_T('\\'));
+ ASSERT(i >= 0);
+ s= s.Left(i);
+ return s;
+}
+
diff --git a/common/commonhelpers.h b/common/commonhelpers.h
new file mode 100644
index 0000000..76bec81
--- /dev/null
+++ b/common/commonhelpers.h
@@ -0,0 +1,32 @@
+// commonhelpers.h - Functions used by windirstat.exe and setup.exe
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+
+CString GetShellExecuteError(UINT u);
+void MyShellExecute(HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFile, LPCTSTR lpParameters, LPCTSTR lpDirectory, INT nShowCmd) throw (CException *);
+CString MyStrRetToString(const LPITEMIDLIST pidl, const STRRET *strret);
+CString GetBaseNameFromPath(LPCTSTR path);
+bool FileExists(LPCTSTR path);
+CString LoadString(UINT resId);
+CString GetAppFileName();
+CString GetAppFolder();
diff --git a/common/cotaskmem.h b/common/cotaskmem.h
new file mode 100644
index 0000000..bb141c4
--- /dev/null
+++ b/common/cotaskmem.h
@@ -0,0 +1,69 @@
+// cotaskmem.h
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// This general purpose header is published under GPL with
+// the friendly permission of D'accord (www.daccord.net).
+//
+// 08.09.1998 - JR
+
+#ifndef _COTASKMEM_H
+#define _COTASKMEM_H
+
+// return type for 'CCoTaskMem<char *>::operator ->' is not a UDT or reference to a UDT. Will produce errors if applied using infix notation
+#pragma warning(disable: 4284)
+
+//
+// CCoTaskMem<>. Some Windows APIs return memory which must be freed with CoTaskMemFree().
+// This template does that in its destructor.
+//
+template<class T>
+class CCoTaskMem
+{
+// construction
+public:
+ CCoTaskMem( T lp = 0 )
+ { p = lp; }
+ CCoTaskMem(const CCoTaskMem<T>&) // operator not allowed for CCoTaskMem
+ { _ASSERTE( 0 ); p = 0; }
+ ~CCoTaskMem()
+ { if( p ) CoTaskMemFree( p ); }
+
+ operator T() { return p; }
+ T& operator*() { _ASSERTE( p != NULL ); return p; }
+ //The assert on operator& usually indicates a bug. If this is really
+ //what is needed, however, take the address of the p member explicitly.
+ T* operator&()
+ { _ASSERTE( p == NULL ); return &p; }
+ T operator->()
+ { _ASSERTE( p != NULL ); return p; }
+ T operator = ( T lp )
+ { if( p != NULL ) CoTaskMemFree( p ); p = lp; return p;}
+ T operator=( const CCoTaskMem<T>& lp ) // operator not allowed for CCoTaskMem
+ { _ASSERTE( 0 ); return p;}
+
+#if _MSC_VER>1020
+ bool operator!() { return (p == NULL); }
+#else
+ BOOL operator!() { return (p == NULL) ? TRUE : FALSE; }
+#endif
+
+ T p;
+};
+
+#endif
diff --git a/common/mdexceptions.h b/common/mdexceptions.h
new file mode 100644
index 0000000..44c3466
--- /dev/null
+++ b/common/mdexceptions.h
@@ -0,0 +1,167 @@
+// mdexceptions.h
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// This general purpose header is derived from a file
+// created by www.daccord.net und published
+// here under GPL with friendly permission of D'accord.
+
+// Md is just a prefix.
+
+#ifndef MDEXCEPTIONS_H_INCLUDED
+#define MDEXCEPTIONS_H_INCLUDED
+
+#ifndef _INC_STDARG
+#include <stdarg.h>
+#endif
+
+#pragma warning(disable: 4290) // C++ Exception Specification ignored
+
+class CMdStringException: public CException
+{
+public:
+ CMdStringException(LPCTSTR pszText)
+ : m_sText(pszText) // pszText may be a MAKEINTRESOURCE
+ {}
+ virtual BOOL GetErrorMessage(LPTSTR lpszError, UINT nMaxError, PUINT pnHelpContext = NULL)
+ {
+ if (pnHelpContext != NULL)
+ *pnHelpContext= 0;
+ if (nMaxError != 0 && lpszError != NULL)
+ lstrcpyn(lpszError, m_sText, nMaxError);
+ return true;
+ }
+protected:
+ CString m_sText;
+};
+
+inline CString MdGetExceptionMessage(CException *pe)
+{
+ CString s;
+ BOOL b= pe->GetErrorMessage(s.GetBuffer(1024), 1024);
+ s.ReleaseBuffer();
+
+ if (!b)
+ s= _T("(no error message available)");
+
+ return s;
+}
+
+inline CString MdGetWinerrorText(HRESULT hr)
+{
+ CString sRet;
+ LPVOID lpMsgBuf;
+ DWORD dw= FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf, 0, NULL
+ );
+ if (dw == NULL)
+ {
+ CString s(MAKEINTRESOURCE(AFX_IDP_NO_ERROR_AVAILABLE));
+ sRet.Format(_T("%s (0x%08lx)"), s, hr);
+ }
+ else
+ {
+ sRet= (LPCTSTR)lpMsgBuf;
+ LocalFree(lpMsgBuf);
+ }
+ return sRet;
+}
+
+inline void MdThrowStringException(UINT resId) throw (CMdStringException *)
+{
+ throw new CMdStringException(MAKEINTRESOURCE(resId));
+}
+
+inline void MdThrowStringException(LPCTSTR pszText) throw (CMdStringException *)
+{
+ throw new CMdStringException(pszText);
+}
+
+inline void __MdFormatStringExceptionV(CString& rsText, LPCTSTR pszFormat, va_list vlist)
+{
+ CString sFormat(pszFormat); // may be a MAKEINTRESOURCE
+ rsText.FormatMessageV(sFormat, &vlist);
+}
+
+inline void AFX_CDECL MdThrowStringExceptionF(LPCTSTR pszFormat, ...)
+{
+ CString sText;
+
+ va_list vlist;
+ va_start(vlist, pszFormat);
+ __MdFormatStringExceptionV(sText, pszFormat, vlist);
+ va_end(vlist);
+
+ MdThrowStringException(sText);
+}
+
+inline void MdThrowStringExceptionV(LPCTSTR pszFormat, va_list vlist)
+{
+ CString sText;
+ __MdFormatStringExceptionV(sText, pszFormat, vlist);
+ MdThrowStringException(sText);
+}
+
+inline void AFX_CDECL MdThrowStringExceptionF(UINT nResIdFormat, ...)
+{
+ CString sText;
+
+ va_list vlist;
+ va_start(vlist, nResIdFormat);
+ __MdFormatStringExceptionV(sText, MAKEINTRESOURCE(nResIdFormat), vlist);
+ va_end(vlist);
+
+ MdThrowStringException(sText);
+}
+
+inline void MdThrowStringExceptionF(UINT nResIdFormat, va_list vlist)
+{
+ CString sText;
+ __MdFormatStringExceptionV(sText, MAKEINTRESOURCE(nResIdFormat), vlist);
+ MdThrowStringException(sText);
+}
+
+inline void MdThrowWinerror(DWORD dw, LPCTSTR pszPrefix =NULL) throw (CMdStringException *)
+{
+ CString sMsg= pszPrefix;
+ sMsg+= _T(": ") + MdGetWinerrorText(dw);
+ MdThrowStringException(sMsg);
+}
+
+inline void MdThrowHresult(HRESULT hr, LPCTSTR pszPrefix =NULL) throw (CMdStringException *)
+{
+ CString sMsg= pszPrefix;
+ sMsg+= _T(": ") + MdGetWinerrorText(hr);
+ MdThrowStringException(sMsg);
+}
+
+
+inline void MdThrowLastWinerror(LPCTSTR pszPrefix =NULL) throw (CMdStringException *)
+{
+ MdThrowWinerror(GetLastError(), pszPrefix);
+}
+
+inline void MdThrowFailed(HRESULT hr, LPCTSTR pszPrefix =NULL) throw (CMdStringException *)
+{
+ if (FAILED(hr))
+ MdThrowHresult(hr, pszPrefix);
+}
+
+#endif
diff --git a/wdsh0407/Table_of_Contents.hhc b/wdsh0407/Table_of_Contents.hhc
new file mode 100644
index 0000000..9c9817b
--- /dev/null
+++ b/wdsh0407/Table_of_Contents.hhc
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<OBJECT type="text/site properties">
+ <param name="ImageType" value="Folder">
+</OBJECT>
+<UL>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="WinDirStat">
+ <param name="Local" value="windirstat.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Was ist ein Verzeichnisbaum?">
+ <param name="Local" value="whatisatree.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Verzeichnisliste">
+ <param name="Local" value="directorytree.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Typenliste">
+ <param name="Local" value="extensionlist.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Baumkarte">
+ <param name="Local" value="treemap.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Kopplung der Ansichten">
+ <param name="Local" value="coupling.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Laufwerksauswahl-Dialog">
+ <param name="Local" value="selectdrivesdialog.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Aktionen">
+ <param name="Local" value="actions.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Benutzerdefinierte Aktionen">
+ <param name="Local" value="userdefinedcleanups.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Konfiguration">
+ <param name="Local" value="configuration.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Sortierung">
+ <param name="Local" value="sorting.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Zeichenerkl&auml;rung">
+ <param name="Local" value="legend.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="H&auml;ufig gestellte Fragen">
+ <param name="Local" value="faq.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Obergrenzen">
+ <param name="Local" value="limits.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Deinstallation">
+ <param name="Local" value="deinstallation.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="GNU Free Documentation License">
+ <param name="Local" value="gnufdl.htm">
+ </OBJECT>
+</UL>
+</BODY></HTML>
diff --git a/wdsh0407/actions.htm b/wdsh0407/actions.htm
new file mode 100644
index 0000000..26493a1
--- /dev/null
+++ b/wdsh0407/actions.htm
@@ -0,0 +1,52 @@
+<html>
+ <head>
+ <title>Aktionen</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Aktionen</h2>
+ <p>Auf ein markiertes Element können verschiedene Aufräumaktionen angewendet
+ werden. Die Aktionen sind erreichbar über das Hauptmenü, die Symbolleiste, die
+ Kontextmenüs und über Tastatur-Shortcuts.
+ </p>
+ <h3>Markierung aktualisieren</h3>
+ <p>Es kann sein, dass ein Element außerhalb von WinDirStat gelöscht oder verändert
+ wurde. "Aktualisieren" bewirkt, dass WinDirStat das Element neu einliest, so
+ dass die Anzeige in WinDirStat wieder mit den tatsächlichen Verhältnissen auf
+ der Festplatte übereinstimmt.
+ </p>
+ <h3>Pfad kopieren</h3>
+ <p>Kopiert den Pfad des markierten Elements in die Zwischenablage.</p>
+ <h3>Öffnen</h3>
+ <p>Öffnet die markierte Datei. Achtung: im Falle einer ausführbaren Datei (.exe)
+ heißt dies, dass das Programm gestartet wird.
+ </p>
+ <h3>Explorer hier starten</h3>
+ <p>Startet den Windows-Explorer so, dass er das markierte Element anzeigt.</p>
+ <h3>DOS-Prompt hier starten</h3>
+ <p>Startet die Kommandozeile im markierten Verzeichnis.</p>
+ <h3>Löschen (in den Papierkorb)</h3>
+ <p>Verschiebt das markierte Element in den Papierkorb. Danach werden das Element
+ und die Papierkorb-Verzeichnisse aktualisiert.</p>
+ <h3>Löschen (irreversibel)</h3>
+ <p>Löscht das markierte Element endgültig. Danach wird das Element aktualisiert.
+ Löschen Sie bitte nur Dateien und Verzeichnisse, von denen Sie wissen, dass
+ weder Sie noch das Bestriebssystem sie brauchen!
+ </p>
+ <h3>Eigenschaften</h3>
+ <p>Öffnet den 'Eigenschaften'-Dialog für die markierte Datei.</p>
+ <h3>E-Mail an den Eigentümer senden</h3>
+ <p>Erstellt einen textuellen Report über das markierte Verzeichnis zwecks
+ E-Mail-Versand an den Eigentümer. Ist gedacht für von mehreren Leuten benutzte
+ Netz-Laufwerke. Der Report enthält genau die Zeilen, die die Verzeichnisliste
+ gerade unter dem markierten Verzeichnis anzeigt, im selben "Klappstatus" und in
+ derselben Sortierung.
+ </p>
+ <h3>Benutzerdefinierte Aktionen</h3>
+ <p>Neben diesen eingebauten Aktionen können Sie eigene Aktionen frei <a href="userdefinedcleanups.htm">
+ definieren</a>.
+ </p>
+ </BODY>
+</html>
diff --git a/wdsh0407/configuration.htm b/wdsh0407/configuration.htm
new file mode 100644
index 0000000..2ba295e
--- /dev/null
+++ b/wdsh0407/configuration.htm
@@ -0,0 +1,33 @@
+<html>
+ <head>
+ <title>Konfiguration</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Konfiguration</h2>
+ <h3>Allgemein</h3>
+ <p><u>Dateisystemgrenzen überschreiten (nur NT und höher)</u>. Unter NTFS können
+ Volumes in Verzeichnissen gemountet werden. Standardmäßig stoppt WinDirStat mit
+ dem Einlesen an diesen Punkten, zeigt also nur die Belegung jeweils <i>einer</i>
+ Festplatte an. Hier können Sie dieses Verhalten ändern. (Mountpoints auf
+ UNC-Laufwerken werden nicht erkannt.)
+ </p>
+ <p><u>Sprache</u>. In dieser Combobox werden neben der eingebauten Sprache Englisch
+ diejenigen Sprachen angeboten, für die eine entsprechende wsdrxxxx.dll
+ existiert. Die Einstellung wird erst beim nächsten Start von WinDirStat
+ wirksam.</p>
+ <h3>Verzeichnisliste</h3>
+ <p>Farben für die Teilbaum-Anteil-Darstellung. Gitternetzlinien.
+ </p>
+ <h3>Baumkarte</h3>
+ <p>Parameter für den Kisseneffekt. Gitternetzlinien (probieren Sie die aus!). Farbe
+ des Markierungsrahmens.
+ </p>
+ <h3>Aktionen</h3>
+ <p>Hier werden die <a href="userdefinedcleanups.htm">benutzerdefinierten Aktionen</a>
+ konfiguriert.
+ </p>
+ </BODY>
+</html>
diff --git a/wdsh0407/coupling.htm b/wdsh0407/coupling.htm
new file mode 100644
index 0000000..abeb8d3
--- /dev/null
+++ b/wdsh0407/coupling.htm
@@ -0,0 +1,36 @@
+<html>
+ <head>
+ <title>Kopplung der Ansichten</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Kopplung der Ansichten</h2>
+ <p>Die eigentliche Stärke von WinDirStat besteht darin, dass die drei Ansichten,
+ Verzeichnisliste, Typenliste und Baumkarte, miteinander gekoppelt sind.
+ </p>
+ <h3>Verzeichnisliste -> Baumkarte</h3>
+ <p>Wird ein Element (Verzeichnis oder Datei) in der Verzeichnisliste <i>markiert</i>,
+ so zeigt auch die Baumkarte dieses Element an, indem sie es durch einen
+ farbigen Rahmen hervorhebt. So können Sie insbesondere die Größe von
+ Verzeichnissen beurteilen.
+ </p>
+ <h3>Baumkarte -> Verzeichnisliste</h3>
+ <p>Wenn Sie in die Baumkarte klicken, so treffen Sie mit der Maus ja immer eine
+ Datei (ein farbiges Rechteck). Daraufhin klappt, falls nötig, die
+ Verzeichnisliste entsprechend auf und markiert diese Datei. So können Sie,
+ indem Sie z.B. auf ein großes Rechteck klicken, Pfad und Attribute der
+ entsprechenden großen Datei in der Verzeichnisliste ablesen.
+ </p>
+ <p>Die Markierung in der Verzeichnisliste und der Baumkarte stimmt aufgrund der
+ gegenseitigen Kopplung also immer überein.
+ </p>
+ <h3>Verzeichnisliste+Baumkarte -> Typenliste</h3>
+ <p>Wird in der Verzeichnisliste (bzw. in der Baumkarte) eine <i>Datei</i> markiert,
+ so zeigt die Typenliste den Dateityp (die Dateinamenserweiterung) an. Der
+ Dateityp wird markiert und in den sichtbaren Bereich gescrollt. So können Sie
+ die Beschreibung und die Statistik zu diesem Typ ablesen.
+ </p>
+ </BODY>
+</html>
diff --git a/wdsh0407/deinstallation.htm b/wdsh0407/deinstallation.htm
new file mode 100644
index 0000000..2c3d4dd
--- /dev/null
+++ b/wdsh0407/deinstallation.htm
@@ -0,0 +1,21 @@
+<html>
+ <head>
+ <title>Deinstallation</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Deinstallation</h2>
+ <p>
+ <ul>
+ <li>
+ Das Verzeichnis C:\programme\windirstat löschen</li>
+ <li>
+ Die Verknüpfungen zu WinDirStat löschen</li>
+ <li>
+ <i>Für Experten</i>: HKCU\Software\seifert\windirstat löschen.</li>
+ </ul>
+ </p>
+ </BODY>
+</html>
diff --git a/wdsh0407/directorytree.htm b/wdsh0407/directorytree.htm
new file mode 100644
index 0000000..82f1b6d
--- /dev/null
+++ b/wdsh0407/directorytree.htm
@@ -0,0 +1,65 @@
+<html>
+ <head>
+ <title>Verzeichnisliste</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Verzeichnisliste</h2>
+ <p>Die Verzeichnisliste gleicht der Baum-Ansicht des Windows-Explorers mit dem
+ Unterschied, dass sie Verzeichnisse und Dateien absteigend nach Größe sortiert
+ darstellt. Oben sehen Sie die Verzeichnisse und Dateien, die am meisten Platz
+ verbrauchen. Klappen Sie ein Verzeichnis auf, so werden dessen
+ Unterverzeichnisse wiederum nach Größe sortiert angezeigt, und so weiter.
+ </p>
+ <h3>Spalten</h3>
+ <p>
+ <ul>
+ <li>
+ <u>Name</u>. Diese Spalte zeigt die Namen der Dateien und Verzeichnisse an und
+ ihre Baumstruktur.</li>
+ <li>
+ <u>Größe</u>. Für Dateien steht in dieser Spalte die Größe der Datei, in Bytes.
+ Für Verzeichnisse steht hier die Größe des Teilbaums, d.h. die Summe der Größen
+ aller Unterverzeichnisse und Dateien.</li>
+ <li>
+ <u>Teilbaum-Anteil</u>. Diese Spalte zeigt, wie sich die Größe eines Teilbaums
+ aus den Größen der Unterelemente zusammensetzt. Die Angaben sind immer nur
+ innerhalb <i>einer</i> Ebene vergleichbar und beziehen sich auf das
+ aufgeklappte Elternelement.<br>
+ [Während des Einlesens zeigt diese Spalte entweder den Pacman oder die Anzahl
+ der noch auszuführenden Leseaufträge für diesen Teilbaum.]
+ </li>
+ <li>
+ <u>Anteil</u>. Dieselbe Angabe wie "Teilbaum-Anteil", in Prozent.<br>
+ [Während des Einlesens zeigt diese Spalte die bisher für den Teilbaum
+ aufgewendete Zeit.]
+ </li>
+ <li>
+ <u>Dateien</u>. Anzahl der Dateien im Teilbaum.</li>
+ <li>
+ <u>Verzeichnisse</u>. Anzahl der Unterverzeichnisse im Teilbaum.</li>
+ <li>
+ <u>Einträge</u>. Anzahl der Einträge im Teilbaum. Summe aus "Dateien" und
+ "Unterverzeichnisse".</li>
+ <li>
+ <u>Letzte Änderung</u>. Datum der letzten im Teilbaum erfolgten Änderung.</li>
+ </ul>
+ </p>
+ <h3>Bedienung</h3>
+ <p>In der Spalte "Name" können Verzeichnisse mit einem Mausklick auf die kleinen
+ Kästchen mit + und - wie im Windows-Explorer auf- und zugeklappt werden. Mit
+ einem Klick auf einen Namen <i>markieren</i> Sie ein Element. Danach können Sie
+ mit den Pfeiltasten im Baum navigieren.
+ </p>
+ <p>In der Baumkarte wird das jeweils markierte Element durch eine Umrahmung
+ hervorgehoben.
+ </p>
+ <p>Markieren Sie eine Datei, so zeigt die Typenliste automatisch deren Typ an.
+ </p>
+ <p>Die <a href="sorting.htm">Sortierung</a> kann per Mausklick auf die
+ Spaltenüberschrift geändert werden.
+ </p>
+ </BODY>
+</html>
diff --git a/wdsh0407/extensionlist.htm b/wdsh0407/extensionlist.htm
new file mode 100644
index 0000000..91e8b6f
--- /dev/null
+++ b/wdsh0407/extensionlist.htm
@@ -0,0 +1,34 @@
+<html>
+ <head>
+ <title>Typenliste</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Typenliste</h2>
+ <p>Die Typenliste enthält sämtliche im Verzeichnisbaum vorkommenden
+ Dateitypen (Dateinamenserweiterungen). Für jeden Dateityp wird die
+ Summe der Dateigrößen in der Spalte "Bytes" angezeigt. Die Typenliste
+ ist standardmäßig absteigend nach dieser Spalte sortiert.
+ Oben stehen also diejenigen Dateitypen, die auf der Festplatte
+ zusammengenommen den meisten Platz einnehmen.
+ </p>
+ <p>Den 12 Dateitypen, die am meisten Platz belegen, sind 12 Farben
+ zugeordnet, allen anderen die Farbe Grau. In dieser Farbe werden
+ die Dateien in der Baumkarte dargestellt.
+ </p>
+ <h3>Spalten</h3>
+ <p>
+ <ul>
+ <li><u>Dateityp</u>. Symbol und Dateinamenserweiterung.</li>
+ <li><u>Farbe</u>. Die Farbe, in der dieser Typ in der Baumkarte dargestellt ist.</li>
+ <li><u>Beschreibung.</u> Beschreibung des Dateityps. Entspricht der Beschreibung,
+ wie sie der Windows-Explorer unter Extras-&gt;Ordneroptionen-&gt;Dateitypen anzeigt.</li>
+ <li><u>Bytes</u>. Gesamt-Volumen des Dateityps im Verzeichnisbaum. Summe der Größen
+ aller Dateien dieses Typs.</li>
+ <li><u>Dateien</u>. Anzahl der Dateien dieses Typs im Verzeichnisbaum.</li>
+ </ul>
+ </p>
+ </BODY>
+</html>
diff --git a/wdsh0407/faq.htm b/wdsh0407/faq.htm
new file mode 100644
index 0000000..e3387e4
--- /dev/null
+++ b/wdsh0407/faq.htm
@@ -0,0 +1,46 @@
+<html>
+ <head>
+ <title>Häufig gestellte Fragen</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
+ <LINK href="format.css" type="text/css" rel="stylesheet">
+ <style type="text/css">
+ <!--
+ h3 { margin-bottom:6pt; }
+ p { margin-top:0pt; }
+ -->
+ </style>
+ </head>
+ <BODY>
+ <h2>Häufig gestellte Fragen</h2>
+ <h3>F: Gibt die Baumkarte die Belegung der Harddisk-Sektoren wieder?</h3>
+ <p>A: Nein. Die Baumkartenansicht hat nichts zu tun mit den Harddisk-Sektoren. Die
+ Verteilung der Dateien auf Sektoren ist eine ganz andere. Im allgemeinen sind
+ große Dateien weit über die Harddisk verstreut. Die Baumkarte hingegen stellt
+ jede Datei als <i>ein</i> Rechteck dar.
+ </p>
+ <h3>F: Werden für die Leseaufträge Threads gestartet?</h3>
+ <p>A: Nein. WinDirStat ist - abgesehen von der Aboutbox, die in einem eigenen
+ Thread läuft - zutiefst single-threaded. Alle Arbeit geschieht in OnIdle().
+ </p>
+ <h3>F: Was hat es mit dem Eintrag &lt;Dateien&gt; auf sich?</h3>
+ <p>A: Siehe <A href="legend.htm">Zeichenerklärung</A>.
+ </p>
+ <h3>F: Was bedeutet das &gt;-Zeichen vor den Spaltenüberschriften?</h3>
+ <p>A: Die &gt;- und &lt;-Zeichen in den Spaltenüberschriften deuten die aktuelle <A href="sorting.htm">
+ Sortierung</A> an.
+ </p>
+ <h3>F: Wozu ist die Datei wdsr0407.dll da?</h3>
+ <p>A: Diese Datei enthält die deutsche Übersetzung von WinDirStat. 0407 ist die
+ Kennziffer für "Deutsch - Deutschland". Wenn diese Datei fehlt, dann ist
+ WinDirStat nur in der (eingebauten) Sprache Englisch verfügbar.
+ </p>
+ <h3>F: Die Größenangaben in KB und MB scheinen etwas zu klein zu sein.</h3>
+ <p>A: WinDirStat hält sich an die im Computerwesen übliche Konvention, dass "Kilo"
+ nicht für 1000 steht sondern für 1024. Es gilt also:<br>
+ 1 KB = 1024 Bytes<br>
+ 1 MB = 1024 KB = 1.048.576 Bytes<br>
+ 1 GB = 1024 MB = 1.048.576 KB = 1.073.741.824 Bytes.
+ </p>
+ </BODY>
+</html>
diff --git a/wdsh0407/format.css b/wdsh0407/format.css
new file mode 100644
index 0000000..cd51716
--- /dev/null
+++ b/wdsh0407/format.css
@@ -0,0 +1,9 @@
+BODY
+{
+ font-family:Arial,sans-serif;
+}
+
+LI
+{
+ margin-bottom:0.5cm;
+}
diff --git a/wdsh0407/gnufdl.htm b/wdsh0407/gnufdl.htm
new file mode 100644
index 0000000..894f7bf
--- /dev/null
+++ b/wdsh0407/gnufdl.htm
@@ -0,0 +1,389 @@
+<html>
+ <head>
+ <title>GNU Free Documentation License</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <H2><A href="http://www.gnu.org/licenses/fdl.html">GNU Free
+ Documentation License</A></H2>
+ <P>
+ Version 1.2, November 2002
+ <P><PRE>Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+ </PRE>
+ <P><STRONG>0. PREAMBLE</STRONG>
+ <P>
+ The purpose of this License is to make a manual, textbook, or other functional
+ and useful document "free" in the sense of freedom: to assure everyone the
+ effective freedom to copy and redistribute it, with or without modifying it,
+ either commercially or noncommercially. Secondarily, this License preserves for
+ the author and publisher a way to get credit for their work, while not being
+ considered responsible for modifications made by others.
+ <P>
+ This License is a kind of "copyleft", which means that derivative works of the
+ document must themselves be free in the same sense. It complements the GNU
+ General Public License, which is a copyleft license designed for free software.
+ <P>
+ We have designed this License in order to use it for manuals for free software,
+ because free software needs free documentation: a free program should come with
+ manuals providing the same freedoms that the software does. But this License is
+ not limited to software manuals; it can be used for any textual work,
+ regardless of subject matter or whether it is published as a printed book. We
+ recommend this License principally for works whose purpose is instruction or
+ reference.
+ <P><STRONG>1. APPLICABILITY AND DEFINITIONS</STRONG>
+ <P>
+ This License applies to any manual or other work, in any medium, that contains
+ a notice placed by the copyright holder saying it can be distributed under the
+ terms of this License. Such a notice grants a world-wide, royalty-free license,
+ unlimited in duration, to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member of the public
+ is a licensee, and is addressed as "you". You accept the license if you copy,
+ modify or distribute the work in a way requiring permission under copyright
+ law.
+ <P>
+ A "Modified Version" of the Document means any work containing the Document or
+ a portion of it, either copied verbatim, or with modifications and/or
+ translated into another language.
+ <P>
+ A "Secondary Section" is a named appendix or a front-matter section of the
+ Document that deals exclusively with the relationship of the publishers or
+ authors of the Document to the Document's overall subject (or to related
+ matters) and contains nothing that could fall directly within that overall
+ subject. (Thus, if the Document is in part a textbook of mathematics, a
+ Secondary Section may not explain any mathematics.) The relationship could be a
+ matter of historical connection with the subject or with related matters, or of
+ legal, commercial, philosophical, ethical or political position regarding them.
+ <P>
+ The "Invariant Sections" are certain Secondary Sections whose titles are
+ designated, as being those of Invariant Sections, in the notice that says that
+ the Document is released under this License. If a section does not fit the
+ above definition of Secondary then it is not allowed to be designated as
+ Invariant. The Document may contain zero Invariant Sections. If the Document
+ does not identify any Invariant Sections then there are none.
+ <P>
+ The "Cover Texts" are certain short passages of text that are listed, as
+ Front-Cover Texts or Back-Cover Texts, in the notice that says that the
+ Document is released under this License. A Front-Cover Text may be at most 5
+ words, and a Back-Cover Text may be at most 25 words.
+ <P>
+ A "Transparent" copy of the Document means a machine-readable copy, represented
+ in a format whose specification is available to the general public, that is
+ suitable for revising the document straightforwardly with generic text editors
+ or (for images composed of pixels) generic paint programs or (for drawings)
+ some widely available drawing editor, and that is suitable for input to text
+ formatters or for automatic translation to a variety of formats suitable for
+ input to text formatters. A copy made in an otherwise Transparent file format
+ whose markup, or absence of markup, has been arranged to thwart or discourage
+ subsequent modification by readers is not Transparent. An image format is not
+ Transparent if used for any substantial amount of text. A copy that is not
+ "Transparent" is called "Opaque".
+ <P>
+ Examples of suitable formats for Transparent copies include plain ASCII without
+ markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly
+ available DTD, and standard-conforming simple HTML, PostScript or PDF designed
+ for human modification. Examples of transparent image formats include PNG, XCF
+ and JPG. Opaque formats include proprietary formats that can be read and edited
+ only by proprietary word processors, SGML or XML for which the DTD and/or
+ processing tools are not generally available, and the machine-generated HTML,
+ PostScript or PDF produced by some word processors for output purposes only.
+ <P>
+ The "Title Page" means, for a printed book, the title page itself, plus such
+ following pages as are needed to hold, legibly, the material this License
+ requires to appear in the title page. For works in formats which do not have
+ any title page as such, "Title Page" means the text near the most prominent
+ appearance of the work's title, preceding the beginning of the body of the
+ text.
+ <P>
+ A section "Entitled XYZ" means a named subunit of the Document whose title
+ either is precisely XYZ or contains XYZ in parentheses following text that
+ translates XYZ in another language. (Here XYZ stands for a specific section
+ name mentioned below, such as "Acknowledgements", "Dedications",
+ "Endorsements", or "History".) To "Preserve the Title" of such a section when
+ you modify the Document means that it remains a section "Entitled XYZ"
+ according to this definition.
+ <P>
+ The Document may include Warranty Disclaimers next to the notice which states
+ that this License applies to the Document. These Warranty Disclaimers are
+ considered to be included by reference in this License, but only as regards
+ disclaiming warranties: any other implication that these Warranty Disclaimers
+ may have is void and has no effect on the meaning of this License.
+ <P><STRONG>2. VERBATIM COPYING</STRONG>
+ <P>
+ You may copy and distribute the Document in any medium, either commercially or
+ noncommercially, provided that this License, the copyright notices, and the
+ license notice saying this License applies to the Document are reproduced in
+ all copies, and that you add no other conditions whatsoever to those of this
+ License. You may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However, you may
+ accept compensation in exchange for copies. If you distribute a large enough
+ number of copies you must also follow the conditions in section 3.
+ <P>
+ You may also lend copies, under the same conditions stated above, and you may
+ publicly display copies.
+ <P><STRONG>3. COPYING IN QUANTITY</STRONG>
+ <P>
+ If you publish printed copies (or copies in media that commonly have printed
+ covers) of the Document, numbering more than 100, and the Document's license
+ notice requires Cover Texts, you must enclose the copies in covers that carry,
+ clearly and legibly, all these Cover Texts: Front-Cover Texts on the front
+ cover, and Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The front cover must
+ present the full title with all words of the title equally prominent and
+ visible. You may add other material on the covers in addition. Copying with
+ changes limited to the covers, as long as they preserve the title of the
+ Document and satisfy these conditions, can be treated as verbatim copying in
+ other respects.
+ <P>
+ If the required texts for either cover are too voluminous to fit legibly, you
+ should put the first ones listed (as many as fit reasonably) on the actual
+ cover, and continue the rest onto adjacent pages.
+ <P>
+ If you publish or distribute Opaque copies of the Document numbering more than
+ 100, you must either include a machine-readable Transparent copy along with
+ each Opaque copy, or state in or with each Opaque copy a computer-network
+ location from which the general network-using public has access to download
+ using public-standard network protocols a complete Transparent copy of the
+ Document, free of added material. If you use the latter option, you must take
+ reasonably prudent steps, when you begin distribution of Opaque copies in
+ quantity, to ensure that this Transparent copy will remain thus accessible at
+ the stated location until at least one year after the last time you distribute
+ an Opaque copy (directly or through your agents or retailers) of that edition
+ to the public.
+ <P>
+ It is requested, but not required, that you contact the authors of the Document
+ well before redistributing any large number of copies, to give them a chance to
+ provide you with an updated version of the Document.
+ <P><STRONG>4. MODIFICATIONS</STRONG>
+ <P>
+ You may copy and distribute a Modified Version of the Document under the
+ conditions of sections 2 and 3 above, provided that you release the Modified
+ Version under precisely this License, with the Modified Version filling the
+ role of the Document, thus licensing distribution and modification of the
+ Modified Version to whoever possesses a copy of it. In addition, you must do
+ these things in the Modified Version:
+ <P>
+ <UL>
+ <LI>
+ <STRONG>A.</STRONG>
+ Use in the Title Page (and on the covers, if any) a title distinct from that of
+ the Document, and from those of previous versions (which should, if there were
+ any, be listed in the History section of the Document). You may use the same
+ title as a previous version if the original publisher of that version gives
+ permission.
+ <LI>
+ <STRONG>B.</STRONG>
+ List on the Title Page, as authors, one or more persons or entities responsible
+ for authorship of the modifications in the Modified Version, together with at
+ least five of the principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you from this
+ requirement.
+ <LI>
+ <STRONG>C.</STRONG>
+ State on the Title page the name of the publisher of the Modified Version, as
+ the publisher.
+ <LI>
+ <STRONG>D.</STRONG>
+ Preserve all the copyright notices of the Document.
+ <LI>
+ <STRONG>E.</STRONG>
+ Add an appropriate copyright notice for your modifications adjacent to the
+ other copyright notices.
+ <LI>
+ <STRONG>F.</STRONG>
+ Include, immediately after the copyright notices, a license notice giving the
+ public permission to use the Modified Version under the terms of this License,
+ in the form shown in the Addendum below.
+ <LI>
+ <STRONG>G.</STRONG>
+ Preserve in that license notice the full lists of Invariant Sections and
+ required Cover Texts given in the Document's license notice.
+ <LI>
+ <STRONG>H.</STRONG>
+ Include an unaltered copy of this License.
+ <LI>
+ <STRONG>I.</STRONG>
+ Preserve the section Entitled "History", Preserve its Title, and add to it an
+ item stating at least the title, year, new authors, and publisher of the
+ Modified Version as given on the Title Page. If there is no section Entitled
+ "History" in the Document, create one stating the title, year, authors, and
+ publisher of the Document as given on its Title Page, then add an item
+ describing the Modified Version as stated in the previous sentence.
+ <LI>
+ <STRONG>J.</STRONG>
+ Preserve the network location, if any, given in the Document for public access
+ to a Transparent copy of the Document, and likewise the network locations given
+ in the Document for previous versions it was based on. These may be placed in
+ the "History" section. You may omit a network location for a work that was
+ published at least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.
+ <LI>
+ <STRONG>K.</STRONG>
+ For any section Entitled "Acknowledgements" or "Dedications", Preserve the
+ Title of the section, and preserve in the section all the substance and tone of
+ each of the contributor acknowledgements and/or dedications given therein.
+ <LI>
+ <STRONG>L.</STRONG>
+ Preserve all the Invariant Sections of the Document, unaltered in their text
+ and in their titles. Section numbers or the equivalent are not considered part
+ of the section titles.
+ <LI>
+ <STRONG>M.</STRONG>
+ Delete any section Entitled "Endorsements". Such a section may not be included
+ in the Modified Version.
+ <LI>
+ <STRONG>N.</STRONG>
+ Do not retitle any existing section to be Entitled "Endorsements" or to
+ conflict in title with any Invariant Section.
+ <LI>
+ <STRONG>O.</STRONG> Preserve any Warranty Disclaimers.
+ </LI>
+ </UL>
+ <P>
+ If the Modified Version includes new front-matter sections or appendices that
+ qualify as Secondary Sections and contain no material copied from the Document,
+ you may at your option designate some or all of these sections as invariant. To
+ do this, add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any other section
+ titles.
+ <P>
+ You may add a section Entitled "Endorsements", provided it contains nothing but
+ endorsements of your Modified Version by various parties--for example,
+ statements of peer review or that the text has been approved by an organization
+ as the authoritative definition of a standard.
+ <P>
+ You may add a passage of up to five words as a Front-Cover Text, and a passage
+ of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts
+ in the Modified Version. Only one passage of Front-Cover Text and one of
+ Back-Cover Text may be added by (or through arrangements made by) any one
+ entity. If the Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity you are
+ acting on behalf of, you may not add another; but you may replace the old one,
+ on explicit permission from the previous publisher that added the old one.
+ <P>
+ The author(s) and publisher(s) of the Document do not by this License give
+ permission to use their names for publicity for or to assert or imply
+ endorsement of any Modified Version.
+ <P><STRONG>5. COMBINING DOCUMENTS</STRONG>
+ <P>
+ You may combine the Document with other documents released under this License,
+ under the terms defined in section 4 above for modified versions, provided that
+ you include in the combination all of the Invariant Sections of all of the
+ original documents, unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all their Warranty
+ Disclaimers.
+ <P>
+ The combined work need only contain one copy of this License, and multiple
+ identical Invariant Sections may be replaced with a single copy. If there are
+ multiple Invariant Sections with the same name but different contents, make the
+ title of each such section unique by adding at the end of it, in parentheses,
+ the name of the original author or publisher of that section if known, or else
+ a unique number. Make the same adjustment to the section titles in the list of
+ Invariant Sections in the license notice of the combined work.
+ <P>
+ In the combination, you must combine any sections Entitled "History" in the
+ various original documents, forming one section Entitled "History"; likewise
+ combine any sections Entitled "Acknowledgements", and any sections Entitled
+ "Dedications". You must delete all sections Entitled "Endorsements."
+ <P><STRONG>6. COLLECTIONS OF DOCUMENTS</STRONG>
+ <P>
+ You may make a collection consisting of the Document and other documents
+ released under this License, and replace the individual copies of this License
+ in the various documents with a single copy that is included in the collection,
+ provided that you follow the rules of this License for verbatim copying of each
+ of the documents in all other respects.
+ <P>
+ You may extract a single document from such a collection, and distribute it
+ individually under this License, provided you insert a copy of this License
+ into the extracted document, and follow this License in all other respects
+ regarding verbatim copying of that document.
+ <P><STRONG>7. AGGREGATION WITH INDEPENDENT WORKS</STRONG>
+ <P>
+ A compilation of the Document or its derivatives with other separate and
+ independent documents or works, in or on a volume of a storage or distribution
+ medium, is called an "aggregate" if the copyright resulting from the
+ compilation is not used to limit the legal rights of the compilation's users
+ beyond what the individual works permit. When the Document is included in an
+ aggregate, this License does not apply to the other works in the aggregate
+ which are not themselves derivative works of the Document.
+ <P>
+ If the Cover Text requirement of section 3 is applicable to these copies of the
+ Document, then if the Document is less than one half of the entire aggregate,
+ the Document's Cover Texts may be placed on covers that bracket the Document
+ within the aggregate, or the electronic equivalent of covers if the Document is
+ in electronic form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+ <P><STRONG>8. TRANSLATION</STRONG>
+ <P>
+ Translation is considered a kind of modification, so you may distribute
+ translations of the Document under the terms of section 4. Replacing Invariant
+ Sections with translations requires special permission from their copyright
+ holders, but you may include translations of some or all Invariant Sections in
+ addition to the original versions of these Invariant Sections. You may include
+ a translation of this License, and all the license notices in the Document, and
+ any Warranty Disclaimers, provided that you also include the original English
+ version of this License and the original versions of those notices and
+ disclaimers. In case of a disagreement between the translation and the original
+ version of this License or a notice or disclaimer, the original version will
+ prevail.
+ <P>
+ If a section in the Document is Entitled "Acknowledgements", "Dedications", or
+ "History", the requirement (section 4) to Preserve its Title (section 1) will
+ typically require changing the actual title.
+ <P><STRONG>9. TERMINATION</STRONG>
+ <P>
+ You may not copy, modify, sublicense, or distribute the Document except as
+ expressly provided for under this License. Any other attempt to copy, modify,
+ sublicense or distribute the Document is void, and will automatically terminate
+ your rights under this License. However, parties who have received copies, or
+ rights, from you under this License will not have their licenses terminated so
+ long as such parties remain in full compliance.
+ <P><STRONG>10. FUTURE REVISIONS OF THIS LICENSE</STRONG>
+ <P>
+ The Free Software Foundation may publish new, revised versions of the GNU Free
+ Documentation License from time to time. Such new versions will be similar in
+ spirit to the present version, but may differ in detail to address new problems
+ or concerns. See http://www.gnu.org/copyleft/.
+ <P>
+ Each version of the License is given a distinguishing version number. If the
+ Document specifies that a particular numbered version of this License "or any
+ later version" applies to it, you have the option of following the terms and
+ conditions either of that specified version or of any later version that has
+ been published (not as a draft) by the Free Software Foundation. If the
+ Document does not specify a version number of this License, you may choose any
+ version ever published (not as a draft) by the Free Software Foundation.
+ <P>
+ <H2>How to use this License for your documents</H2>
+ <P>
+ To use this License in a document you have written, include a copy of the
+ License in the document and put the following copyright and license notices
+ just after the title page:
+ <P><PRE>Copyright (c) YEAR YOUR NAME.
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2
+or any later version published by the Free Software Foundation;
+with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+Texts. A copy of the license is included in the section entitled "GNU
+Free Documentation License".
+ </PRE>
+ <P>
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace
+ the "with...Texts." line with this:
+ <P><PRE>with the Invariant Sections being LIST THEIR TITLES, with the
+Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+ </PRE>
+ <P>
+ If you have Invariant Sections without Cover Texts, or some other combination
+ of the three, merge those two alternatives to suit the situation.
+ <P>
+ If your document contains nontrivial examples of program code, we recommend
+ releasing these examples in parallel under your choice of free software
+ license, such as the GNU General Public License, to permit their use in free
+ software.
+ <P>
+ </BODY>
+</html>
diff --git a/wdsh0407/legend.htm b/wdsh0407/legend.htm
new file mode 100644
index 0000000..e172646
--- /dev/null
+++ b/wdsh0407/legend.htm
@@ -0,0 +1,59 @@
+<html>
+ <head>
+ <title>Zeichenerklärung</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ <style type="text/css">
+ <!--
+ h3 { margin-bottom:6pt; }
+ p { margin-top:0pt; }
+ -->
+ </style>
+ </head>
+ <BODY>
+ <h2>Zeichenerklärung</h2>
+ <h3>&lt;Dateien&gt;</h3>
+ <p>Jedes Verzeichnis in der Verzeichnisliste hat im allgemeinen ein
+ Pseudo-Unterverzeichnis &lt;Dateien&gt;. Dort sind alle einfachen Dateien des
+ Verzeichnisses zusammengefasst. Also die Dateien, die direkt im Verzeichnis,
+ nicht in Unterverzeichnissen, liegen. Dies hat den Vorteil, dass die
+ Verzeichnisliste aufgeräumter und dass die Statistik aussagekräftiger ist. So
+ können Sie nämlich ablesen, welchen Platz die in einem Verzeichnis (nicht in
+ Unterverzeichnissen) liegenden Dateien zusammen einnehmen.
+ </p>
+ <p>Der &lt;Dateien&gt;-Pseudoeintrag entfällt, wenn es nur eine Datei im
+ Verzeichnis gibt, oder wenn das Verzeichnis keine Unterverzeichnisse hat.
+ </p>
+ <h3>&lt;Freier Platz&gt;</h3>
+ <p>Wenn Sie im Optionen-Menü "Freien Platz anzeigen" aktiviert haben, hat jedes
+ Laufwerk einen &lt;Freier Platz&gt;-Eintrag. Die Größe dieses Eintrags
+ entspricht der Menge des auf dem Laufwerk noch zur Verfügung stehenden freien
+ Platzes. In der Baumkarte hat dieser Eintrag eine dunkelgraue Farbe. Durch den
+ &lt;Freier Platz&gt;-Eintrag bekommt man einen Eindruck von der Relation
+ zwischen ingesamt belegtem und noch freien Plattenplatz. Diese Angabe
+ entspricht der Angabe "Freier Speicher" im
+ Windows-Explorer-Eigenschaften-Dialog für das Laufwerk.
+ </p>
+ <h3>&lt;Unbekannt&gt;</h3>
+ <p>Wenn Sie im Optionen-Menü "Unbekannten Platz anzeigen" aktiviert haben, hat
+ jedes Laufwerk einen &lt;Unbekannt&gt;-Eintrag. Damit hat es folgende
+ Bewandtnis. Einerseits kennt WinDirStat die Gesamtkapazität des Laufwerks und
+ den freien Plattenplatz. (Diese Werte entsprechen den Angaben im
+ Windows-Explorer-Eigenschaften-Dialog für das Laufwerk.) Andererseits hat
+ WinDirStat die Größen aller Dateien ermittelt und summiert. &lt;Unbekannt&gt;
+ ist nun die Differenz Gesamtkapazität minus freier Platz minus ermittelte
+ Summe. Dieser Rest kann aus mehreren Gründen größer als Null sein. Z.B.
+ kann es Verzeichnisse (z.B. "System Volume Information") geben, die man nicht
+ auslesen darf. Deren Größe fließt also in die von WinDirStat ermittelte Summe
+ nicht mit ein. In der Baumkarte hat der &lt;Unbekannt&gt;-Eintrag eine
+ leuchtend gelbe Farbe.
+ </p>
+ <h3>&lt; (in Spaltenüberschriften)</h3>
+ <p>deutet an, dass die Liste nach dieser Spalte aufsteigend <a href="sorting.htm">sortiert</a>
+ ist.</p>
+ <h3>&gt; (in Spaltenüberschriften)</h3>
+ <p>deutet an, dass die Liste nach dieser Spalte absteigend <a href="sorting.htm">sortiert</a>
+ ist.</p>
+ </BODY>
+</html>
diff --git a/wdsh0407/limits.htm b/wdsh0407/limits.htm
new file mode 100644
index 0000000..a0601b1
--- /dev/null
+++ b/wdsh0407/limits.htm
@@ -0,0 +1,29 @@
+<html>
+ <head>
+ <title>Obergrenzen</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Obergrenzen</h2>
+ <table border="1" bordercolor="black" cellspacing="0" cellpadding="20">
+ <tr>
+ <td>Anzahl direkte Unterelemente eines Verzeichnisses</td>
+ <td>2^31 (= 2.147.483.648)</td>
+ </tr>
+ <tr>
+ <td>Zum Einlesen aufgewendete Zeit</td>
+ <td>2^32 ms (= 49 Tage)</td>
+ </tr>
+ <tr>
+ <td>Dateigröße, Baumgröße</td>
+ <td>2^63 (= 8.388.608 TB)</td>
+ </tr>
+ <tr>
+ <td>Anzahl gleichzeitige Leseaufträge</td>
+ <td>2^63</td>
+ </tr>
+ </table>
+ </BODY>
+</html>
diff --git a/wdsh0407/selectdrivesdialog.htm b/wdsh0407/selectdrivesdialog.htm
new file mode 100644
index 0000000..66749e3
--- /dev/null
+++ b/wdsh0407/selectdrivesdialog.htm
@@ -0,0 +1,36 @@
+<html>
+ <head>
+ <title>Laufwerksauswahl-Dialog</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Laufwerksauswahl-Dialog</h2>
+ <p>Hier können Sie bestimmen, welche Laufwerke in die Statistik
+ aufgenommen werden sollen.
+ </p>
+ <p>Sie haben die Möglichkeit, eines oder mehrere Laufwerke aus der Liste
+ auszusuchen oder ein Verzeichnis auszuwählen.
+ </p>
+ <p>Die Liste zeigt alle vorhandenen Laufwerke (Festplatten, eingelegte
+ Floppy Disks oder CDs, Netzlaufwerke) an.</p>
+ <h3>Spalten</h3>
+ <p>
+ <ul>
+ <li><u>Name</u>. Name und Laufwerksbuchstabe des Laufwerks.</li>
+ <li><u>Gesamt</u>. Kapazität des Laufwerks.</li>
+ <li><u>Frei</u>. Freier Platz auf dem Laufwerk.</li>
+ <li><u>Belegt/Gesamt</u> Anteil der Belegung bezogen auf die Kapazität.</li>
+ <li><u>Belegt/Gesamt</u> Dasselbe in Prozent.</li>
+ </ul>
+ </p>
+ <h3>Bedienung</h3>
+ <p>Der Dialog hat drei "Radio"-Knöpfe: "Alle lokalen Laufwerke", "Einzelne Laufwerke"
+ und "Ein Verzeichnis". Die Voreinstellung ist "Alle lokalen Laufwerke", d.h. alle
+ Laufwerke, die keine Netzlaufwerke sind. Klicken
+ Sie einfach auf OK, um mit dem Einlesen zu beginnen.</p>
+ <p>Die Auswahl ist persistent, d.h. beim nächsten Öffnen des Dialogs erscheint
+ wieder dieselbe Auswahl, die Sie zuletzt vorgenommen hatten.</p>
+ </BODY>
+</html>
diff --git a/wdsh0407/sorting.htm b/wdsh0407/sorting.htm
new file mode 100644
index 0000000..3659322
--- /dev/null
+++ b/wdsh0407/sorting.htm
@@ -0,0 +1,34 @@
+<html>
+ <head>
+ <title>Sortierung</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Sortierung</h2>
+ <p>Sämtliche Listen in WinDirStat können Sie nach Belieben sortieren. Die aktuelle
+ Sortierung wird durch die Zeichen &lt; und &gt; in den Spaltenüberschriften
+ angedeutet. &lt; bedeutet aufsteigende Sortierung, &gt; bedeutet absteigende
+ Sortierung.
+ </p>
+ <p>Durch einen Mausklick auf eine Spaltenüberschrift setzen Sie die gewünschte
+ Sortierung.
+ </p>
+ <p>Eigentlich werden sogar zwei Spalten zur Sortierung herangezogen. Erstens
+ diejenige, auf die Sie zuletzt geklickt haben, und zweitens - wenn die Elemente
+ bezüglich dieser Spalte gleich sind - diejenige, nach der zuvor sortiert wurde.
+ </p>
+ <p>Beachten Sie, dass die Sortierung in der Verzeichnisliste natürlich die
+ Baumstruktur respektiert: Sortiert wird dort immer nur innerhalb derselben
+ Hierarchieebene.
+ </p>
+ <p></p>
+ <h3>Bemerkung</h3>
+ <p>Die Breite der Spalten und ihre Reihenfolge können per Drag 'n Drop eingestellt
+ werden. Die Spaltenbreiten und -reihenfolgen sind persistent, d.h.
+ werden beim Programmstart automatisch wieder so hergestellt, wie Sie sie
+ zuletzt eingestellt hatten.
+ </p>
+ </BODY>
+</html>
diff --git a/wdsh0407/tree.jpg b/wdsh0407/tree.jpg
new file mode 100644
index 0000000..e978839
--- /dev/null
+++ b/wdsh0407/tree.jpg
Binary files differ
diff --git a/wdsh0407/treemap.htm b/wdsh0407/treemap.htm
new file mode 100644
index 0000000..de47c74
--- /dev/null
+++ b/wdsh0407/treemap.htm
@@ -0,0 +1,46 @@
+<html>
+ <head>
+ <title>Baumkarte</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Baumkarte (engl. Treemap)</h2>
+ <p>Die Baumkarte zeigt auf einen Blick den gesamten Inhalt des <a href="whatisatree.htm">Verzeichnisbaums</a>.
+ </p>
+ <p>Sie stellt jede Datei dabei als ein farbiges Rechteck dar, dessen Fläche der
+ Größe der Datei entspricht.
+ </p>
+ Die Rechtecke sind so angeordnet, dass Verzeichnisse wiederum Rechtecke bilden,
+ die alle ihre Dateien und Unterverzeichnisse enthalten. Die Fläche dieser
+ Rechtecke entspricht also der Größe der Teilbäume.
+ </p>
+ <p>Die Farbe eines Rechtecks deutet den Typ der Datei an,
+ wie in der Typenliste angegeben.
+ </p>
+ <p>Der Kisseneffekt verdeutlicht dabei zusätzlich die Verzeichnisstruktur.</p>
+
+ <h3>Bedienung</h3>
+ <p>Sie erkennen mühelos die großen Rechtecke, d.h. die großen Dateien, auch wenn
+ diese weit unten im Verzeichnisbaum in Unterverzeichnissen versteckt sind.
+ Klicken Sie darauf: In der Verzeichnisliste klappt der Pfad zu dieser Datei
+ auf, und Sie können Ort, Namen und Attribute der Datei ablesen, sowie - wenn
+ Sie wollen - eine Aktion auf sie anwenden, z.B. die Datei löschen.
+ </p>
+ <p>Navigieren Sie in der Verzeichnisliste: die jeweilige Markierung wird in
+ der Baumkarte durch einen farbigen Rahmen hervorgehoben. Gewinnen Sie so
+ einen Eindruck von den Größenverhältnissen: Wie groß ist z.B. C:\windows
+ verglichen mit C:\programme?</p>
+ <p>Benutzen Sie zum Navigieren auch die Kontextmenü-Optionen "Zum Elternelement"
+ und "Zurück zum Kindelement".
+ </p>
+ <p>Zoomen. Die Option "Hineinzoomen" vergrößert die Baumkarte, so dass ein
+ Teilbaum in voller Größe dargestellt wird. Sie machen quasi einen
+ Schritt auf das markierte Element zu. Die Verzeichnisliste zeigt die Wurzel
+ dieses Teilbaums durch eine blaue Umrahmung an. Mit "Herauszoomen" treten Sie wieder
+ zurück und das das Elternelement wird wieder dargestellt.
+
+ </p>
+ </BODY>
+</html>
diff --git a/wdsh0407/userdefinedcleanups.htm b/wdsh0407/userdefinedcleanups.htm
new file mode 100644
index 0000000..b42e685
--- /dev/null
+++ b/wdsh0407/userdefinedcleanups.htm
@@ -0,0 +1,66 @@
+<html>
+ <head>
+ <title>Benutzerdefinierte Aktionen</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Benutzerdefinierte Aktionen</h2>
+ <p><i>Dieser Punkt ist für Experten.</i></p>
+ <p>Hier können Sie bis zu 10 Aktionen selbst definieren. Die Aktionen werden als <i>Kommandozeile</i>
+ spezifiziert.
+ </p>
+ <p>Selektieren Sie in der Liste einen Eintrag und setzen Sie ihn auf "Freigegeben".
+ Vergeben Sie einen Titel, der Titel erscheint in den Menüs.
+ </p>
+ <p>Formulieren Sie eine Kommandozeile. Benutzen Sie die "MSDOS-Eingabeaufforderung"
+ (Windows 9x, command.com) bzw. die "Eingabeaufforderung" (NT, cmd.exe), um
+ Hilfe zu möglichen Kommandos abzufragen und die Kommandozeile auszuprobieren.
+ </p>
+ <h3>Beispiele</h3>
+ <p>
+ <ul>
+ <li>
+ <pre>dir /b > dir.txt</pre>
+ Dateinamen in die Textdatei dir.txt schreiben.</li>
+ <li>
+ <pre>del *.bak</pre>
+ Alle *.bak-Dateien im aktuellen Verzeichnis löschen.</li>
+ <li>
+ <pre>del /s *.bak *.tmp</pre>
+ Alle *.bak- und *.tmp-Dateien in allen Unterverzeichnissen löschen (rekursiv).</li>
+ <li>
+ <pre>C:\programme\windirstat.exe "%p"</pre>
+ Ein zweites WinDirStat aufrufen mit dem Pfad des aktuellen Verzeichnisses.</li>
+ </ul>
+ </p>
+ <h3>Beispiele (nur NT und höher)</h3>
+ <p>
+ <ul>
+ <li>
+ <pre>echo %n & pause</pre>
+ Namen des aktuellen Verzeichnisses ausgeben.</li>
+ <li>
+ <pre>cd & pause</pre>
+ Aktuellen Pfad ausgeben und auf Tastendruck warten.</li>
+ <li>
+ <pre>cd .. && myzip "%n"</pre>
+ Aktuelles Verzeichnis komprimieren (mit dem hypothetischen Tool myzip).</li>
+ </ul>
+ </p>
+ <p>Die Bedeutung der Platzhalter %p, %n, %sp, %sn ist im Dialog angegeben.
+ Vergessen Sie nicht, sie ggf. in Anführungszeichen einzuschließen.</p>
+ <h3>Aufbau der Kommandozeile</h3>
+ <p>Angenommen, Sie geben die Kommandozeile
+ <pre>xyz</pre>
+ ein. WinDirStat versucht dann, folgenden Prozess zu starten:
+ <pre>%COMSPEC% /c xyz</pre>
+ </p>
+ <h3>Weitere Optionen</h3>
+ <p>Geben Sie an, auf welche Elemente die Aktion anwendbar sein soll.</p>
+ <p>Geben Sie an, ob die Aktion rekursiv auf alle Unterverzeichnisse angewendet
+ werden soll (depth first).</p>
+ <p>Die restlichen Optionen müssten klar sein.</p>
+ </BODY>
+</html>
diff --git a/wdsh0407/wdsh0407.vcproj b/wdsh0407/wdsh0407.vcproj
new file mode 100644
index 0000000..d13475e
--- /dev/null
+++ b/wdsh0407/wdsh0407.vcproj
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="wdsh0407"
+ ProjectGUID="{76695BEC-D0B6-44BC-8F2D-E9C45D239137}"
+ Keyword="MakeFileProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="0">
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="echo The help file will only be generated in release build."
+ ReBuildCommandLine="echo The help file will only be generated in release build."
+ CleanCommandLine="echo clean"
+ Output="wdsh0407.chm"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="0">
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="hhc &quot;$(ProjectDir)windirstat.hhp&quot; || cd ."
+ ReBuildCommandLine="hhc &quot;$(ProjectDir)windirstat.hhp&quot; || cd ."
+ CleanCommandLine="del ..\..\release\wdsh0407.chm"
+ Output="..\..\release\wdsh0407.chm"/>
+ </Configuration>
+ <Configuration
+ Name="Unicode Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="0">
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="echo The help file will only be generated in release build."
+ ReBuildCommandLine="echo The help file will only be generated in release build."
+ CleanCommandLine="echo clean"
+ Output="wdsh0407.chm"/>
+ </Configuration>
+ <Configuration
+ Name="Unicode Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="0">
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="hhc &quot;$(ProjectDir)windirstat.hhp&quot; || cd ."
+ ReBuildCommandLine="hhc &quot;$(ProjectDir)windirstat.hhp&quot; || cd ."
+ CleanCommandLine="del ..\..\release\wdsh0407.chm"
+ Output="..\..\release\wdsh0407.chm"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\actions.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\configuration.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\coupling.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\deinstallation.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\directorytree.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\extensionlist.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\faq.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\format.css">
+ </File>
+ <File
+ RelativePath=".\gnufdl.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\legend.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\limits.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\selectdrivesdialog.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\sorting.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\Table of Contents.hhc">
+ </File>
+ <File
+ RelativePath=".\treemap.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\userdefinedcleanups.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\whatisatree.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\windirstat.hhp">
+ </File>
+ <File
+ RelativePath=".\windirstat.htm"
+ DeploymentContent="TRUE">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/wdsh0407/whatisatree.htm b/wdsh0407/whatisatree.htm
new file mode 100644
index 0000000..613e133
--- /dev/null
+++ b/wdsh0407/whatisatree.htm
@@ -0,0 +1,67 @@
+<html>
+ <head>
+ <title>Was ist ein Verzeichnisbaum?</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
+ <LINK href="format.css" type="text/css" rel="stylesheet">
+ </head>
+ <BODY>
+ <h2>Was ist ein Verzeichnisbaum?</h2>
+ <p>Bei den meisten Computer-Betriebssystemen, so auch in Microsoft Windows, sind
+ die Daten auf der Festplatte hierarchisch organisiert.
+ </p>
+ <p>Einerseits gibt es die <i>Dateien</i>, die eine gewisse Größe haben und die
+ Nutzdaten enthalten. Jede Datei hat einen Namen. Unter Microsoft Windows gibt
+ die "Dateinamenserweiterung" Aufschluss über den Typ der Datei. Die Erweiterung
+ ".exe" z.B. deutet an, dass es sich bei der Datei um ein Programm handelt. Die
+ Erweiterung ".doc" deutet auf ein WinWord-Dokument hin, ".jpg" ist ein Foto,
+ usw. Unsinnigerweise blendet der Microsoft-Windows-Explorer allerdings
+ standardmäßig diese Dateinamenserweiterungen aus. Im Optionen-Menü des Windows
+ Explorers können Sie dieses Verhalten ändern.
+ </p>
+ <p>Andererseits gibt es die <i>Verzeichnisse</i>. Der Windows-Explorer und auch
+ WinDirStat stellen die Verzeichnisse als gelbe Aktenmappen dar. Auch
+ Verzeichnisse haben einen Namen, normalerweise aber ohne
+ Dateinamenserweiterung. Verzeichnisse dienen nur dazu, Dateien und andere
+ Verzeichnisse ("Unterverzeichnisse") zu enthalten. Dadurch, dass Verzeichnisse
+ Unterverzeichnisse enthalten können und diese wiederum Unterverzeichnisse,
+ entsteht auf der Festplatte eine hierarchische Struktur.
+ </p>
+ <p>
+ <img src="tree.jpg" width="99" height="105" align="left" vspace="20" hspace="20" />
+ Statt "hierarchische Struktur" sagt man auch einfach <i>Baumstruktur</i>. Denn
+ auch ein Baum ist ja hierarchisch aufgebaut: Der Stamm verzweigt sich in Äste,
+ die Äste verzweigen sich in Unteräste, Zweige und schließlich die Blätter. Im
+ Dateisystem entspricht das sogenannte Wurzelverzeichnis dem Stamm, die
+ Verzeichnisse entsprechen den Ästen, und die Dateien entsprechen den Blättern.
+ </p>
+ <p>Aus diesem Grund spricht man beim Dateisystem eines Computers von einem
+ "Verzeichnisbaum".
+ </p>
+ <p><br clear="all" />
+ Im Unterschied zu den meisten wirklichen Bäumen tragen auf der Festplatte auch
+ der Stamm und die Äste bereits Blätter. Und, ebenfalls im Unterschied zu
+ wirklichen Bäumen: die <u>Dateien</u> sind die eigentlich voluminösen Einheiten
+ (deren Größe sich in Megabytes oder Gigabytes bemisst), die eigentlichen
+ Verzeichnisse sind dagegen vernachlässigbar klein. Übrigens stellt man sich
+ abstrakte Bäume normalerweise umgedreht vor: die Wurzel oben und die Äste und
+ Blätter unten.
+ </p>
+ <p>Sägt man von einem Baum einen Ast ab und steckt ihn in die Erde, so wird er
+ selbst zu einem kleinen Baum (na ja, er sieht jedenfalls so aus): Jeder Ast ist
+ zusammen mit seinen Unterästen und Blättern selbst ein Baum, ein <i>Teilbaum</i>.
+ </p>
+ <p>Gern wird auch die Stammbaum-Metapher verwendet: Die Unterverzeichnisse und
+ Dateien eines Verzeichnisses heißen <i>Kind</i>-Elemente dieses Verzeichnisses.
+ Und ein Verzeichnis, in dem ein Unterverzeichnis bzw. eine Datei liegt, heißt
+ das <i>Eltern</i>-Element dieses Unterverzeichnisses bzw. der Datei. Das
+ Wurzelverzeichnis ist der Urahn aller Elemente des Verzeichnisbaums.
+ </p>
+ <p>Ein <i>Pfad</i> wie "C:\dokumente\briefe\entwürfe\liebesbrief.doc" deutet an,
+ dass sich auf der Festplatte C: im Wurzelverzeichnis "C:\" ein Verzeichnis
+ "dokumente" befindet, darunter das Unterverzeichnis "briefe", darunter das
+ Unterverzeichnis "entwürfe" und darin eine Datei "liebesbrief.doc". Der Pfad
+ ist also eine präzise Darstellung des Weges von der Wurzel bis zum Blatt.
+ </p>
+ </BODY>
+</html>
diff --git a/wdsh0407/windirstat.hhp b/wdsh0407/windirstat.hhp
new file mode 100644
index 0000000..69a9c3a
--- /dev/null
+++ b/wdsh0407/windirstat.hhp
@@ -0,0 +1,43 @@
+[OPTIONS]
+Compatibility=1.1 or later
+Compiled file=..\..\release\wdsh0407.chm
+Contents file=Table of Contents.hhc
+Default Window=main
+Default topic=windirstat.htm
+Display compile progress=No
+Full-text search=Yes
+Language=0x407 Deutsch (Deutschland)
+Title=WinDirStat
+
+[WINDOWS]
+main="WinDirStat","Table of Contents.hhc",,"windirstat.htm","windirstat.htm",,,,,0x63420,,0x3006,[22,19,816,782],0x108f0000,,,,,,0
+
+
+[FILES]
+windirstat.htm
+directorytree.htm
+extensionlist.htm
+treemap.htm
+actions.htm
+configuration.htm
+coupling.htm
+faq.htm
+gnufdl.htm
+legend.htm
+selectdrivesdialog.htm
+sorting.htm
+whatisatree.htm
+userdefinedcleanups.htm
+limits.htm
+deinstallation.htm
+
+[ALIAS]
+IDH_StartPage=windirstat.htm
+IDH_UserDefinedCleanups=userdefinedcleanups.htm
+IDH_Treemap=treemap.htm
+
+[MAP]
+#include ..\windirstat\helpmap.h
+
+[INFOTYPES]
+
diff --git a/wdsh0407/windirstat.htm b/wdsh0407/windirstat.htm
new file mode 100644
index 0000000..9570b7b
--- /dev/null
+++ b/wdsh0407/windirstat.htm
@@ -0,0 +1,67 @@
+<html>
+ <head>
+ <title>WinDirStat</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h1 style="margin-bottom:1pt">WinDirStat - Verzeichnisstatistik</h1>
+ <P style="font-size:70%;margin-top:2pt">Copyright (c) 2003 Bernhard Seifert.
+ Permission is granted to copy, distribute and/or modify this document under the
+ terms of the GNU Free Documentation License, Version 1.2 or any later version
+ published by the Free Software Foundation; with no Invariant Sections, no
+ Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included
+ in the section entitled "GNU Free Documentation License".
+ </P>
+ <p>(Windows Directory Statistics.) Zeigt an, wo all der Plattenplatz geblieben ist,
+ und hilft aufzuräumen.
+ </p>
+ <p style="color=#006000">Sie kennen das Problem: Die Festplatte ist fast voll, und
+ man weiß nicht, wo eigentlich die großen Dateien liegen, die den ganzen Platz
+ belegen. Sie können ja in Unter-Unterverzeichnissen versteckt sein. Dies mit
+ Hilfe des Windows-Explorers herauszubekommen, ist ermüdend: Man müsste im
+ Verzeichnisbaum immer wieder Verzeichnisse und Unterverzeichnisse aufklappen
+ und zuklappen oder die "Eigenschaften" der Verzeichnisse betrachten, wobei
+ immer nur die Größe <i>eines</i> Teilbaums gezählt wird. Es ist schwierig, sich
+ auf diese Weise ein Bild von der Festplattenbelegung zu machen. Hier hilft
+ WinDirStat. </i>
+ </p>
+ <p>Beim Start öffnet WinDirStat den <a href="selectdrivesdialog.htm">Laufwerksauswahl-Dialog</a>.
+ Bestätigen Sie diesen mit OK.
+ </p>
+ <p>
+ Dann liest WinDirStat einmal den gesamten <a href="whatisatree.htm">Verzeichnisbaum</a>
+ ein, was je nach Festplattengröße ein paar Minuten dauern kann, und stellt ihn
+ dann in drei praktischen Ansichten dar:
+ </p>
+ <table border="1" bordercolor="#007000" style="BORDER-RIGHT:3px solid; BORDER-TOP:3px solid; BORDER-LEFT:3px solid; WIDTH:373px; BORDER-BOTTOM:3px solid; BORDER-COLLAPSE:collapse; HEIGHT:226px">
+ <tr>
+ <td colspan="2" style="COLOR:#ffffff; HEIGHT:17px; BACKGROUND-COLOR:#007000">WinDirStat</td>
+ </tr>
+ <tr style="HEIGHT:80px">
+ <td align="center" style="WIDTH: 241px; HEIGHT: 70px"><a href="directorytree.htm">Verzeichnisliste</a></td>
+ <td align="center" style="HEIGHT: 70px"><a href="extensionlist.htm">Typenliste</a></td>
+ </tr>
+ <tr style="HEIGHT:100px">
+ <td colspan="2" align="center"><a href="treemap.htm">Baumkarte</a></td>
+ </tr>
+ </table>
+ <p>Die Ansichten sind miteinander <a href="coupling.htm">gekoppelt</a>.
+ </p>
+ <p>Die Festplatten können mithilfe verschiedener <a href="actions.htm">Aktionen</a>
+ aufgeräumt werden.
+ </p>
+ <p>Die Ansichten und die <a href="userdefinedcleanups.htm">benutzerdefinierten Aktionen</a>
+ können nach den persönlichen Bedürfnissen <a href="configuration.htm">konfiguriert</a>
+ werden.
+ </p>
+ <p><a href="sorting.htm">Sortierung</a></p>
+ <p><a href="legend.htm">Zeichenerklärung</a></p>
+ <p><a href="faq.htm">Häufig gestellte Fragen</a></p>
+ <p><a href="limits.htm">Obergrenzen</a></p>
+ <p><a href="deinstallation.htm">Deinstallation</a></p>
+ <P style="font-size:70%"><a href="gnufdl.htm">GNU Free Documentation License</a></P>
+ <P>&nbsp;</P>
+ </BODY>
+</html>
diff --git a/wdshelp/Table_of_Contents.hhc b/wdshelp/Table_of_Contents.hhc
new file mode 100644
index 0000000..f4b50db
--- /dev/null
+++ b/wdshelp/Table_of_Contents.hhc
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<OBJECT type="text/site properties">
+ <param name="ImageType" value="Folder">
+</OBJECT>
+<UL>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="WinDirStat">
+ <param name="Local" value="windirstat.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="What is a Directory Tree?">
+ <param name="Local" value="whatisatree.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Directory List">
+ <param name="Local" value="directorytree.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Extension List">
+ <param name="Local" value="extensionlist.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Treemap">
+ <param name="Local" value="treemap.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Coupling of the Views">
+ <param name="Local" value="coupling.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Select Drives Dialog">
+ <param name="Local" value="selectdrivesdialog.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Cleanups">
+ <param name="Local" value="actions.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="User Defined Cleanups">
+ <param name="Local" value="userdefinedcleanups.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Configuration">
+ <param name="Local" value="configuration.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Sorting">
+ <param name="Local" value="sorting.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Legend">
+ <param name="Local" value="legend.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Frequently Asked Questions">
+ <param name="Local" value="faq.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Limits">
+ <param name="Local" value="limits.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="Deinstallation">
+ <param name="Local" value="deinstallation.htm">
+ </OBJECT>
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="GNU Free Documentation License">
+ <param name="Local" value="gnufdl.htm">
+ </OBJECT>
+</UL>
+</BODY></HTML>
diff --git a/wdshelp/actions.htm b/wdshelp/actions.htm
new file mode 100644
index 0000000..f95283d
--- /dev/null
+++ b/wdshelp/actions.htm
@@ -0,0 +1,50 @@
+<html>
+ <head>
+ <title>Clenaups</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Cleanups</h2>
+ <p>Serveral clean up actions can be applied to a selected item. The cleanups are
+ accessible through the main menu, the tool bar and through keyboard shortcuts.
+ </p>
+ <h3>Refresh Selected</h3>
+ <p>Possibly an item has been deleted or modified outside of WinDirStat. "Refresh"
+ makes WinDirStat re-read the item, so that the display accords with the actual
+ conditions on the hard disk again.
+ </p>
+ <h3>Copy Path</h3>
+ <p>Copies the path of the selected item into the clipboard.</p>
+ <h3>Open</h3>
+ <p>Opens the selected file. Note that in case of an executable file (.exe), this
+ means that the program is started.
+ </p>
+ <h3>Explorer here</h3>
+ <p>Launches the Windows Explorer so that it shows the selected item.</p>
+ <h3>Command Prompt here</h3>
+ <p>Launches the DOS prompt in the selected directory.</p>
+ <h3>Delete (to Recycle Bin)</h3>
+ <p>Moves the selected item into the recycle bin. Then the item and the recycle bin
+ directories are refreshed.</p>
+ <h3>Delete (no way to undelete)</h3>
+ <p>Deletes the selected item irreversibly. Then the item is refreshed. Please
+ delete only files and directories, when you know that neither you nor the
+ system needs it any more!
+ </p>
+ <h3>Properties</h3>
+ <p>Opens the 'Properties' dialog for the selected file.</p>
+ <h3>Send Mail to Owner</h3>
+ <p>Generates a textual report about the selected directory, which can be sent a via
+ e-mail to its owner. This is intended for network drives, which are used by
+ several people. The report accurately contains the lines displayed in the
+ directory list underneath the selected item, in the same "expansion state" and
+ in the same sort order.
+ </p>
+ <h3>User Defined Cleanups</h3>
+ <p>In addition to these built-in clean ups you can freely <a href="userdefinedcleanups.htm">
+ define your own cleanups</a>.
+ </p>
+ </BODY>
+</html>
diff --git a/wdshelp/configuration.htm b/wdshelp/configuration.htm
new file mode 100644
index 0000000..7dd71c6
--- /dev/null
+++ b/wdshelp/configuration.htm
@@ -0,0 +1,30 @@
+<html>
+ <head>
+ <title>Configuration</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Configuration</h2>
+ <h3>General</h3>
+ <p><u>Cross file system boundaries (only NT and higher)</u>. Under NTFS volumes can
+ be mounted in directories. By default WinDirStat stops reading at these mount
+ points, i.e. it shows only the usage of <i>one</i> file system. Here you can
+ change this behavior. (No mount points are recognized on UNC drives.)
+ </p>
+ <p><u>Language</u>. In addition to the built-in language English, this combo box
+ offers those languages, for which a correspondig wsdrxxxx.dll exists. The
+ setting takes effect next time when WinDirStat is started.</p>
+ <h3>Directory List</h3>
+ <p>Colors for the subtree percentage presentation. Grid lines.
+ </p>
+ <h3>Treemap</h3>
+ <p>Parameters for the cushion shading. Grid lines (try this!). Color of the
+ selection rectangle.
+ </p>
+ <h3>Cleanups</h3>
+ <p>Here you can configure the <a href="userdefinedcleanups.htm">User Defined Cleanups</a>.
+ </p>
+ </BODY>
+</html>
diff --git a/wdshelp/coupling.htm b/wdshelp/coupling.htm
new file mode 100644
index 0000000..88941ae
--- /dev/null
+++ b/wdshelp/coupling.htm
@@ -0,0 +1,35 @@
+<html>
+ <head>
+ <title>Coupling of the Views</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Coupling of the Views</h2>
+ <p>The really strong point of WinDirStat is, that the three views, Directory List,
+ Extension List and Treemap, are coupled with each other.
+ </p>
+ <h3>Directory List -> Treemap</h3>
+ <p>When you <i>select</i> an item (directory or file) in the directory list, the
+ treemap also shows this item by highlighting it with a colored frame. In
+ particular you can see the size of directories.
+ </p>
+ <h3>Treemap -> Directory List</h3>
+ <p>When you click into the treemap, the mouse always hits a file (a colored
+ rectangle). After that the directory list expands (if necessary) the
+ appropriate nodes and selects this file. So you can, e.g. by clicking on a big
+ rectangle, see path and attributes of the corresponding big file in the
+ directory list.
+ </p>
+ <p>So, because of this mutual coupling, the selections in the directory list and in
+ the treemap are always the same.
+ </p>
+ <h3>Directory List + Treemap -> Extension List</h3>
+ <p>When you select a <i>file</i> in the directory list (or in the treemap), the
+ extension list shows the file type (the extension). The extension is selected
+ and scrolled into view. So you can see the description and the
+ statistics for this file type.
+ </p>
+ </BODY>
+</html>
diff --git a/wdshelp/deinstallation.htm b/wdshelp/deinstallation.htm
new file mode 100644
index 0000000..9c35d58
--- /dev/null
+++ b/wdshelp/deinstallation.htm
@@ -0,0 +1,21 @@
+<html>
+ <head>
+ <title>Deinstallation</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Deinstallation</h2>
+ <p>
+ <ul>
+ <li>
+ Remove the directory C:\program files\windirstat</li>
+ <li>
+ Remove the shortcuts for WinDirStat</li>
+ <li>
+ <i>For experts</i>: Remove HKCU\Software\seifert\windirstat.</li>
+ </ul>
+ </p>
+ </BODY>
+</html>
diff --git a/wdshelp/directorytree.htm b/wdshelp/directorytree.htm
new file mode 100644
index 0000000..cda7dca
--- /dev/null
+++ b/wdshelp/directorytree.htm
@@ -0,0 +1,61 @@
+<html>
+ <head>
+ <title>Directory List</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Directory List</h2>
+ <p>The directory list resembles the tree view of the Windows Explorer, with the
+ difference that it shows directories and files sorted by size descending. At
+ the top you see the directories and files, which use up most space. When you
+ expand a directory, its subdirectories are shown again sorted by size, and so
+ on.
+ </p>
+ <h3>Columns</h3>
+ <p>
+ <ul>
+ <li>
+ <u>Name</u>. This column shows the names of the files and directories and their
+ tree structure.</li>
+ <li>
+ <u>Size</u>. For files, this is the size of the file, in bytes. For
+ directories, this is the size of the subtree, that is the sum of the sizes of
+ all subdirectories and files.</li>
+ <li>
+ <u>Subtree Percentage</u>. This column shows, how the size of a subtree is
+ composed of the sizes of the sub-items. This information is comparable only
+ within <i>one</i> level and is always related to the expanded parent item.<br>
+ [During the scanning, this column shows either a pacman or the number of read
+ jobs to do for the subtree.]
+ </li>
+ <li>
+ <u>Percentage</u>. The same information as in "Subtree Percentage", in percent.<br>
+ [During the scanning, this column shows the time spent for the subtree so far.]
+ </li>
+ <li>
+ <u>Files</u>. Number of files in the subtree.</li>
+ <li>
+ <u>Subdirs</u>. Number of sub-directories in the subtree.</li>
+ <li>
+ <u>Items</u>. Number of items in the subtree. Sum of "Files" and "Subdirs".</li>
+ <li>
+ <u>Last Change</u>. Date of the last modification in the subtree.</li>
+ </ul>
+ </p>
+ <h3>Operation</h3>
+ <p>In the column "Name" you can expand and collapse the directories by a mouse
+ click on the little boxes with + and -, as in the Windows Explorer. A click on
+ a name <i>selects</i> an item. After that you can navigate in the tree with the
+ arrow keys.
+ </p>
+ <p>The treemap always highlights the selected item with a frame.
+ </p>
+ <p>If you select a file, the extension list automatically shows its type.
+ </p>
+ <p>The <a href="sorting.htm">sorting</a> can be set with a mouse click on a column
+ header.
+ </p>
+ </BODY>
+</html>
diff --git a/wdshelp/extensionlist.htm b/wdshelp/extensionlist.htm
new file mode 100644
index 0000000..9e8b3e5
--- /dev/null
+++ b/wdshelp/extensionlist.htm
@@ -0,0 +1,32 @@
+<html>
+ <head>
+ <title>Extension List</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Extension List</h2>
+ <p>The extension list contains all types (filename extensions) occurring in the
+ directory tree. For every file type the column "Bytes" shows the sum of the file
+ sizes. By default, the extension list is sorted descending by this column.
+ So at the top are those files types, which all in all take up most space
+ on the hard disk.
+ </p>
+ <p>12 colors are assigned to the 12 file types, which take up most space. The rest
+ is grey. The treemap shows the files in these colors.
+ </p>
+ <h3>Columns</h3>
+ <p>
+ <ul>
+ <li><u>Extension</u>. Icon and filename extension.</li>
+ <li><u>Color</u>. The color, which is used by the treemap to display the files of this type.</li>
+ <li><u>Description.</u> Description of the file type. Corresponds to the description
+ shown by the Windows Explorer.</li>
+ <li><u>Bytes</u>. Total volume of the file type in the directory tree.
+ Sum of the sizes of all files of this type.</li>
+ <li><u>Files</u>. Number of files of this type in the directory tree.</li>
+ </ul>
+ </p>
+ </BODY>
+</html>
diff --git a/wdshelp/faq.htm b/wdshelp/faq.htm
new file mode 100644
index 0000000..1debbf0
--- /dev/null
+++ b/wdshelp/faq.htm
@@ -0,0 +1,45 @@
+<html>
+ <head>
+ <title>Frequently Asked Questions</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
+ <LINK href="format.css" type="text/css" rel="stylesheet">
+ <style type="text/css">
+ <!--
+ h3 { margin-bottom:6pt; }
+ p { margin-top:0pt; }
+ -->
+ </style>
+ </head>
+ <BODY>
+ <h2>Frequently Asked Questions</h2>
+ <h3>Q: Does the treemap relate to the allocation of hard disk sectors?</h3>
+ <p>A: No. The treemap view has nothing to do with hard disk sectors.
+ Generally big files are scattered on the hard disk. The treemap on the other
+ hand shows each file as <i>one</i> rectangle.
+ </p>
+ <h3>Q: Does WinDirStat start threads for the read jobs?</h3>
+ <p>A: No. WinDirStat is - apart from the about box, which runs in an own thread
+ - deeply single-threaded. All work is done in OnIdle().
+ </p>
+ <h3>Q: What does the item &lt;Files&gt; mean?</h3>
+ <p>A: See <A href="legend.htm">Legend</A>.
+ </p>
+ <h3>Q: What does the &gt; symbol in front of the column captions mean?</h3>
+ <p>A: The &gt; and &lt; symbols in the column headers indicate the current
+ <A href="sorting.htm">sorting</A>.
+ </p>
+ <h3>Q: What is the file wdsr0407.dll for?</h3>
+ <p>A: This file contains the German translation of WinDirStat. 0407 is the
+ language identifier for "German - Germany". If this file is absent, then
+ WinDirStat is available in the (built-in) language English only.
+ </p>
+ <h3>Q: The size information in KB and MB seems to be a bit too small.</h3>
+ <p>A: WinDirStat sticks to the computing convention, that "kilo" doesn't stand
+ for 1000 but for 1024. So we have:<br>
+ 1 KB = 1024 Bytes<br>
+ 1 MB = 1024 KB = 1,048,576 Bytes<br>
+ 1 GB = 1024 MB = 1,048,576 KB = 1,073,741,824 Bytes.
+ </p>
+ </BODY>
+</html>
diff --git a/wdshelp/format.css b/wdshelp/format.css
new file mode 100644
index 0000000..cd51716
--- /dev/null
+++ b/wdshelp/format.css
@@ -0,0 +1,9 @@
+BODY
+{
+ font-family:Arial,sans-serif;
+}
+
+LI
+{
+ margin-bottom:0.5cm;
+}
diff --git a/wdshelp/gnufdl.htm b/wdshelp/gnufdl.htm
new file mode 100644
index 0000000..894f7bf
--- /dev/null
+++ b/wdshelp/gnufdl.htm
@@ -0,0 +1,389 @@
+<html>
+ <head>
+ <title>GNU Free Documentation License</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <H2><A href="http://www.gnu.org/licenses/fdl.html">GNU Free
+ Documentation License</A></H2>
+ <P>
+ Version 1.2, November 2002
+ <P><PRE>Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+ </PRE>
+ <P><STRONG>0. PREAMBLE</STRONG>
+ <P>
+ The purpose of this License is to make a manual, textbook, or other functional
+ and useful document "free" in the sense of freedom: to assure everyone the
+ effective freedom to copy and redistribute it, with or without modifying it,
+ either commercially or noncommercially. Secondarily, this License preserves for
+ the author and publisher a way to get credit for their work, while not being
+ considered responsible for modifications made by others.
+ <P>
+ This License is a kind of "copyleft", which means that derivative works of the
+ document must themselves be free in the same sense. It complements the GNU
+ General Public License, which is a copyleft license designed for free software.
+ <P>
+ We have designed this License in order to use it for manuals for free software,
+ because free software needs free documentation: a free program should come with
+ manuals providing the same freedoms that the software does. But this License is
+ not limited to software manuals; it can be used for any textual work,
+ regardless of subject matter or whether it is published as a printed book. We
+ recommend this License principally for works whose purpose is instruction or
+ reference.
+ <P><STRONG>1. APPLICABILITY AND DEFINITIONS</STRONG>
+ <P>
+ This License applies to any manual or other work, in any medium, that contains
+ a notice placed by the copyright holder saying it can be distributed under the
+ terms of this License. Such a notice grants a world-wide, royalty-free license,
+ unlimited in duration, to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member of the public
+ is a licensee, and is addressed as "you". You accept the license if you copy,
+ modify or distribute the work in a way requiring permission under copyright
+ law.
+ <P>
+ A "Modified Version" of the Document means any work containing the Document or
+ a portion of it, either copied verbatim, or with modifications and/or
+ translated into another language.
+ <P>
+ A "Secondary Section" is a named appendix or a front-matter section of the
+ Document that deals exclusively with the relationship of the publishers or
+ authors of the Document to the Document's overall subject (or to related
+ matters) and contains nothing that could fall directly within that overall
+ subject. (Thus, if the Document is in part a textbook of mathematics, a
+ Secondary Section may not explain any mathematics.) The relationship could be a
+ matter of historical connection with the subject or with related matters, or of
+ legal, commercial, philosophical, ethical or political position regarding them.
+ <P>
+ The "Invariant Sections" are certain Secondary Sections whose titles are
+ designated, as being those of Invariant Sections, in the notice that says that
+ the Document is released under this License. If a section does not fit the
+ above definition of Secondary then it is not allowed to be designated as
+ Invariant. The Document may contain zero Invariant Sections. If the Document
+ does not identify any Invariant Sections then there are none.
+ <P>
+ The "Cover Texts" are certain short passages of text that are listed, as
+ Front-Cover Texts or Back-Cover Texts, in the notice that says that the
+ Document is released under this License. A Front-Cover Text may be at most 5
+ words, and a Back-Cover Text may be at most 25 words.
+ <P>
+ A "Transparent" copy of the Document means a machine-readable copy, represented
+ in a format whose specification is available to the general public, that is
+ suitable for revising the document straightforwardly with generic text editors
+ or (for images composed of pixels) generic paint programs or (for drawings)
+ some widely available drawing editor, and that is suitable for input to text
+ formatters or for automatic translation to a variety of formats suitable for
+ input to text formatters. A copy made in an otherwise Transparent file format
+ whose markup, or absence of markup, has been arranged to thwart or discourage
+ subsequent modification by readers is not Transparent. An image format is not
+ Transparent if used for any substantial amount of text. A copy that is not
+ "Transparent" is called "Opaque".
+ <P>
+ Examples of suitable formats for Transparent copies include plain ASCII without
+ markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly
+ available DTD, and standard-conforming simple HTML, PostScript or PDF designed
+ for human modification. Examples of transparent image formats include PNG, XCF
+ and JPG. Opaque formats include proprietary formats that can be read and edited
+ only by proprietary word processors, SGML or XML for which the DTD and/or
+ processing tools are not generally available, and the machine-generated HTML,
+ PostScript or PDF produced by some word processors for output purposes only.
+ <P>
+ The "Title Page" means, for a printed book, the title page itself, plus such
+ following pages as are needed to hold, legibly, the material this License
+ requires to appear in the title page. For works in formats which do not have
+ any title page as such, "Title Page" means the text near the most prominent
+ appearance of the work's title, preceding the beginning of the body of the
+ text.
+ <P>
+ A section "Entitled XYZ" means a named subunit of the Document whose title
+ either is precisely XYZ or contains XYZ in parentheses following text that
+ translates XYZ in another language. (Here XYZ stands for a specific section
+ name mentioned below, such as "Acknowledgements", "Dedications",
+ "Endorsements", or "History".) To "Preserve the Title" of such a section when
+ you modify the Document means that it remains a section "Entitled XYZ"
+ according to this definition.
+ <P>
+ The Document may include Warranty Disclaimers next to the notice which states
+ that this License applies to the Document. These Warranty Disclaimers are
+ considered to be included by reference in this License, but only as regards
+ disclaiming warranties: any other implication that these Warranty Disclaimers
+ may have is void and has no effect on the meaning of this License.
+ <P><STRONG>2. VERBATIM COPYING</STRONG>
+ <P>
+ You may copy and distribute the Document in any medium, either commercially or
+ noncommercially, provided that this License, the copyright notices, and the
+ license notice saying this License applies to the Document are reproduced in
+ all copies, and that you add no other conditions whatsoever to those of this
+ License. You may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However, you may
+ accept compensation in exchange for copies. If you distribute a large enough
+ number of copies you must also follow the conditions in section 3.
+ <P>
+ You may also lend copies, under the same conditions stated above, and you may
+ publicly display copies.
+ <P><STRONG>3. COPYING IN QUANTITY</STRONG>
+ <P>
+ If you publish printed copies (or copies in media that commonly have printed
+ covers) of the Document, numbering more than 100, and the Document's license
+ notice requires Cover Texts, you must enclose the copies in covers that carry,
+ clearly and legibly, all these Cover Texts: Front-Cover Texts on the front
+ cover, and Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The front cover must
+ present the full title with all words of the title equally prominent and
+ visible. You may add other material on the covers in addition. Copying with
+ changes limited to the covers, as long as they preserve the title of the
+ Document and satisfy these conditions, can be treated as verbatim copying in
+ other respects.
+ <P>
+ If the required texts for either cover are too voluminous to fit legibly, you
+ should put the first ones listed (as many as fit reasonably) on the actual
+ cover, and continue the rest onto adjacent pages.
+ <P>
+ If you publish or distribute Opaque copies of the Document numbering more than
+ 100, you must either include a machine-readable Transparent copy along with
+ each Opaque copy, or state in or with each Opaque copy a computer-network
+ location from which the general network-using public has access to download
+ using public-standard network protocols a complete Transparent copy of the
+ Document, free of added material. If you use the latter option, you must take
+ reasonably prudent steps, when you begin distribution of Opaque copies in
+ quantity, to ensure that this Transparent copy will remain thus accessible at
+ the stated location until at least one year after the last time you distribute
+ an Opaque copy (directly or through your agents or retailers) of that edition
+ to the public.
+ <P>
+ It is requested, but not required, that you contact the authors of the Document
+ well before redistributing any large number of copies, to give them a chance to
+ provide you with an updated version of the Document.
+ <P><STRONG>4. MODIFICATIONS</STRONG>
+ <P>
+ You may copy and distribute a Modified Version of the Document under the
+ conditions of sections 2 and 3 above, provided that you release the Modified
+ Version under precisely this License, with the Modified Version filling the
+ role of the Document, thus licensing distribution and modification of the
+ Modified Version to whoever possesses a copy of it. In addition, you must do
+ these things in the Modified Version:
+ <P>
+ <UL>
+ <LI>
+ <STRONG>A.</STRONG>
+ Use in the Title Page (and on the covers, if any) a title distinct from that of
+ the Document, and from those of previous versions (which should, if there were
+ any, be listed in the History section of the Document). You may use the same
+ title as a previous version if the original publisher of that version gives
+ permission.
+ <LI>
+ <STRONG>B.</STRONG>
+ List on the Title Page, as authors, one or more persons or entities responsible
+ for authorship of the modifications in the Modified Version, together with at
+ least five of the principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you from this
+ requirement.
+ <LI>
+ <STRONG>C.</STRONG>
+ State on the Title page the name of the publisher of the Modified Version, as
+ the publisher.
+ <LI>
+ <STRONG>D.</STRONG>
+ Preserve all the copyright notices of the Document.
+ <LI>
+ <STRONG>E.</STRONG>
+ Add an appropriate copyright notice for your modifications adjacent to the
+ other copyright notices.
+ <LI>
+ <STRONG>F.</STRONG>
+ Include, immediately after the copyright notices, a license notice giving the
+ public permission to use the Modified Version under the terms of this License,
+ in the form shown in the Addendum below.
+ <LI>
+ <STRONG>G.</STRONG>
+ Preserve in that license notice the full lists of Invariant Sections and
+ required Cover Texts given in the Document's license notice.
+ <LI>
+ <STRONG>H.</STRONG>
+ Include an unaltered copy of this License.
+ <LI>
+ <STRONG>I.</STRONG>
+ Preserve the section Entitled "History", Preserve its Title, and add to it an
+ item stating at least the title, year, new authors, and publisher of the
+ Modified Version as given on the Title Page. If there is no section Entitled
+ "History" in the Document, create one stating the title, year, authors, and
+ publisher of the Document as given on its Title Page, then add an item
+ describing the Modified Version as stated in the previous sentence.
+ <LI>
+ <STRONG>J.</STRONG>
+ Preserve the network location, if any, given in the Document for public access
+ to a Transparent copy of the Document, and likewise the network locations given
+ in the Document for previous versions it was based on. These may be placed in
+ the "History" section. You may omit a network location for a work that was
+ published at least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.
+ <LI>
+ <STRONG>K.</STRONG>
+ For any section Entitled "Acknowledgements" or "Dedications", Preserve the
+ Title of the section, and preserve in the section all the substance and tone of
+ each of the contributor acknowledgements and/or dedications given therein.
+ <LI>
+ <STRONG>L.</STRONG>
+ Preserve all the Invariant Sections of the Document, unaltered in their text
+ and in their titles. Section numbers or the equivalent are not considered part
+ of the section titles.
+ <LI>
+ <STRONG>M.</STRONG>
+ Delete any section Entitled "Endorsements". Such a section may not be included
+ in the Modified Version.
+ <LI>
+ <STRONG>N.</STRONG>
+ Do not retitle any existing section to be Entitled "Endorsements" or to
+ conflict in title with any Invariant Section.
+ <LI>
+ <STRONG>O.</STRONG> Preserve any Warranty Disclaimers.
+ </LI>
+ </UL>
+ <P>
+ If the Modified Version includes new front-matter sections or appendices that
+ qualify as Secondary Sections and contain no material copied from the Document,
+ you may at your option designate some or all of these sections as invariant. To
+ do this, add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any other section
+ titles.
+ <P>
+ You may add a section Entitled "Endorsements", provided it contains nothing but
+ endorsements of your Modified Version by various parties--for example,
+ statements of peer review or that the text has been approved by an organization
+ as the authoritative definition of a standard.
+ <P>
+ You may add a passage of up to five words as a Front-Cover Text, and a passage
+ of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts
+ in the Modified Version. Only one passage of Front-Cover Text and one of
+ Back-Cover Text may be added by (or through arrangements made by) any one
+ entity. If the Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity you are
+ acting on behalf of, you may not add another; but you may replace the old one,
+ on explicit permission from the previous publisher that added the old one.
+ <P>
+ The author(s) and publisher(s) of the Document do not by this License give
+ permission to use their names for publicity for or to assert or imply
+ endorsement of any Modified Version.
+ <P><STRONG>5. COMBINING DOCUMENTS</STRONG>
+ <P>
+ You may combine the Document with other documents released under this License,
+ under the terms defined in section 4 above for modified versions, provided that
+ you include in the combination all of the Invariant Sections of all of the
+ original documents, unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all their Warranty
+ Disclaimers.
+ <P>
+ The combined work need only contain one copy of this License, and multiple
+ identical Invariant Sections may be replaced with a single copy. If there are
+ multiple Invariant Sections with the same name but different contents, make the
+ title of each such section unique by adding at the end of it, in parentheses,
+ the name of the original author or publisher of that section if known, or else
+ a unique number. Make the same adjustment to the section titles in the list of
+ Invariant Sections in the license notice of the combined work.
+ <P>
+ In the combination, you must combine any sections Entitled "History" in the
+ various original documents, forming one section Entitled "History"; likewise
+ combine any sections Entitled "Acknowledgements", and any sections Entitled
+ "Dedications". You must delete all sections Entitled "Endorsements."
+ <P><STRONG>6. COLLECTIONS OF DOCUMENTS</STRONG>
+ <P>
+ You may make a collection consisting of the Document and other documents
+ released under this License, and replace the individual copies of this License
+ in the various documents with a single copy that is included in the collection,
+ provided that you follow the rules of this License for verbatim copying of each
+ of the documents in all other respects.
+ <P>
+ You may extract a single document from such a collection, and distribute it
+ individually under this License, provided you insert a copy of this License
+ into the extracted document, and follow this License in all other respects
+ regarding verbatim copying of that document.
+ <P><STRONG>7. AGGREGATION WITH INDEPENDENT WORKS</STRONG>
+ <P>
+ A compilation of the Document or its derivatives with other separate and
+ independent documents or works, in or on a volume of a storage or distribution
+ medium, is called an "aggregate" if the copyright resulting from the
+ compilation is not used to limit the legal rights of the compilation's users
+ beyond what the individual works permit. When the Document is included in an
+ aggregate, this License does not apply to the other works in the aggregate
+ which are not themselves derivative works of the Document.
+ <P>
+ If the Cover Text requirement of section 3 is applicable to these copies of the
+ Document, then if the Document is less than one half of the entire aggregate,
+ the Document's Cover Texts may be placed on covers that bracket the Document
+ within the aggregate, or the electronic equivalent of covers if the Document is
+ in electronic form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+ <P><STRONG>8. TRANSLATION</STRONG>
+ <P>
+ Translation is considered a kind of modification, so you may distribute
+ translations of the Document under the terms of section 4. Replacing Invariant
+ Sections with translations requires special permission from their copyright
+ holders, but you may include translations of some or all Invariant Sections in
+ addition to the original versions of these Invariant Sections. You may include
+ a translation of this License, and all the license notices in the Document, and
+ any Warranty Disclaimers, provided that you also include the original English
+ version of this License and the original versions of those notices and
+ disclaimers. In case of a disagreement between the translation and the original
+ version of this License or a notice or disclaimer, the original version will
+ prevail.
+ <P>
+ If a section in the Document is Entitled "Acknowledgements", "Dedications", or
+ "History", the requirement (section 4) to Preserve its Title (section 1) will
+ typically require changing the actual title.
+ <P><STRONG>9. TERMINATION</STRONG>
+ <P>
+ You may not copy, modify, sublicense, or distribute the Document except as
+ expressly provided for under this License. Any other attempt to copy, modify,
+ sublicense or distribute the Document is void, and will automatically terminate
+ your rights under this License. However, parties who have received copies, or
+ rights, from you under this License will not have their licenses terminated so
+ long as such parties remain in full compliance.
+ <P><STRONG>10. FUTURE REVISIONS OF THIS LICENSE</STRONG>
+ <P>
+ The Free Software Foundation may publish new, revised versions of the GNU Free
+ Documentation License from time to time. Such new versions will be similar in
+ spirit to the present version, but may differ in detail to address new problems
+ or concerns. See http://www.gnu.org/copyleft/.
+ <P>
+ Each version of the License is given a distinguishing version number. If the
+ Document specifies that a particular numbered version of this License "or any
+ later version" applies to it, you have the option of following the terms and
+ conditions either of that specified version or of any later version that has
+ been published (not as a draft) by the Free Software Foundation. If the
+ Document does not specify a version number of this License, you may choose any
+ version ever published (not as a draft) by the Free Software Foundation.
+ <P>
+ <H2>How to use this License for your documents</H2>
+ <P>
+ To use this License in a document you have written, include a copy of the
+ License in the document and put the following copyright and license notices
+ just after the title page:
+ <P><PRE>Copyright (c) YEAR YOUR NAME.
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2
+or any later version published by the Free Software Foundation;
+with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+Texts. A copy of the license is included in the section entitled "GNU
+Free Documentation License".
+ </PRE>
+ <P>
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace
+ the "with...Texts." line with this:
+ <P><PRE>with the Invariant Sections being LIST THEIR TITLES, with the
+Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+ </PRE>
+ <P>
+ If you have Invariant Sections without Cover Texts, or some other combination
+ of the three, merge those two alternatives to suit the situation.
+ <P>
+ If your document contains nontrivial examples of program code, we recommend
+ releasing these examples in parallel under your choice of free software
+ license, such as the GNU General Public License, to permit their use in free
+ software.
+ <P>
+ </BODY>
+</html>
diff --git a/wdshelp/legend.htm b/wdshelp/legend.htm
new file mode 100644
index 0000000..a5cf029
--- /dev/null
+++ b/wdshelp/legend.htm
@@ -0,0 +1,56 @@
+<html>
+ <head>
+ <title>Legend</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ <style type="text/css">
+ <!--
+ h3 { margin-bottom:6pt; }
+ p { margin-top:0pt; }
+ -->
+ </style>
+ </head>
+ <BODY>
+ <h2>Legend</h2>
+ <h3>&lt;Files&gt;</h3>
+ <p>Generally, each directory in the directory list has a pseudo subdirectory
+ &lt;Files&gt;. There, all ordinary files of the directory are put together.
+ That is, all files, which are immediate children of the directory, not those
+ of subdirectories. This has the advantage, that the directory list is cleaner
+ and that the statistics is sounder. Because with this item you can
+ see how much space is used all in all by the files of the directory (not of subdirectories).
+ </p>
+ <p>The &lt;Files&gt; item is ommitted, if there is only one file in the
+ directory, or if it has no subdirectories.
+ </p>
+ <h3>&lt;Free Space&gt;</h3>
+ <p>If you have activated "Show Free Space" in the Options menu, each drive
+ has an &lt;Free Space&gt; item. The size of this item tallies with the amount
+ of free space available on the drive. In the treemap this item has a dark grey color.
+ Through the &lt;Free Space&gt; item you get an impression of the ratio between
+ the totaly used disk space and the free disk space. This information corresponds
+ with the value shown in the Windows Explorer properties dialog for the drive.
+ </p>
+ <h3>&lt;Unknown&gt;</h3>
+ <p>If you have activated "Show Unknown" in the Options menu, each drive
+ has an &lt;Unknown&gt; item. The matter is as follows.
+ On the one hand, WinDirStat knows the total capacity of the drive and
+ the free disk space. (These values tally with the number shown by the
+ Windows Explorer properties dialog for the drive.)
+ On the other hand WinDirStat has determined the sizes of all files
+ and added them up.
+ Well, &lt;Unknown&gt; is the difference: Total capacity minus free space
+ minus determined sum. This rest can be greater than zero by serveral reasons.
+ For instance there can be directories (e.g. "System Volume Information") with read-access
+ denied. Their size cannot be included in the sum calculated by WinDirStat.
+ In the treemap, the &lt;Unknown&gt; item is colored vivid yellow.
+ </p>
+ <h3>&lt; (in column headings)</h3>
+ <p>indicates that the list is <a href="sorting.htm">sorted</a> by this column in ascending order.
+ </p>
+ <h3>&gt; (in column headings)</h3>
+ <p>indicates that the list is <a href="sorting.htm">sorted</a> by this column in descending order.
+ </p>
+ </BODY>
+</html>
diff --git a/wdshelp/limits.htm b/wdshelp/limits.htm
new file mode 100644
index 0000000..0768c93
--- /dev/null
+++ b/wdshelp/limits.htm
@@ -0,0 +1,29 @@
+<html>
+ <head>
+ <title>Limits</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Limits</h2>
+ <table border="1" bordercolor="black" cellspacing="0" cellpadding="20">
+ <tr>
+ <td>Number of direct subitems of a directory</td>
+ <td>2^31 (= 2.147.483.648)</td>
+ </tr>
+ <tr>
+ <td>Time spent on scanning</td>
+ <td>2^32 ms (= 49 days)</td>
+ </tr>
+ <tr>
+ <td>File size, tree size</td>
+ <td>2^63 (= 8.388.608 TB)</td>
+ </tr>
+ <tr>
+ <td>Number of concurrent read jobs</td>
+ <td>2^63</td>
+ </tr>
+ </table>
+ </BODY>
+</html>
diff --git a/wdshelp/original_n_baum55.gif b/wdshelp/original_n_baum55.gif
new file mode 100644
index 0000000..20d2483
--- /dev/null
+++ b/wdshelp/original_n_baum55.gif
Binary files differ
diff --git a/wdshelp/selectdrivesdialog.htm b/wdshelp/selectdrivesdialog.htm
new file mode 100644
index 0000000..96b95f2
--- /dev/null
+++ b/wdshelp/selectdrivesdialog.htm
@@ -0,0 +1,33 @@
+<html>
+ <head>
+ <title>Select Drives Dialog</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Select Drives Dialog</h2>
+ <p>Here you can decide which drives to include in the statistics.
+ </p>
+ <p>You can select one or more drives from the list or choose a directory.
+ </p>
+ <p>The list shows all present drives (hard disks, inserted floppy disks or CDs,
+ and network drives).</p>
+ <h3>Columns</h3>
+ <p>
+ <ul>
+ <li><u>Name</u>. Name and drive letter of the drive.</li>
+ <li><u>Total</u>. Capacity of the drive.</li>
+ <li><u>Free</u>. Free space on the drive.</li>
+ <li><u>Total/Used</u> Percentage of used space, related to the capacity.</li>
+ <li><u>Total/Used</u> The same information in percent.</li>
+ </ul>
+ </p>
+ <h3>Operation</h3>
+ <p>The dialog box has three "radio buttons": "All local drives", "Individual drives"
+ and "A folder". The default is "All local drives", that is all drives, which are not
+ network drives. Simply click on OK to begin the scan.</p>
+ <p>The selection is persistent, i.e. when you open the dialog the next time,
+ the default setting will be that which you made the last time.</p>
+ </BODY>
+</html>
diff --git a/wdshelp/sorting.htm b/wdshelp/sorting.htm
new file mode 100644
index 0000000..644e836
--- /dev/null
+++ b/wdshelp/sorting.htm
@@ -0,0 +1,30 @@
+<html>
+ <head>
+ <title>Sorting</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Sorting</h2>
+ <p>All lists in WinDirStat can be sorted at will. The current sorting is
+ indicated by the symbols &lt; and &gt; in the column headings.
+ &lt; means ascending sort, &gt; means descending sort.
+ </p>
+ <p>You can set the desired sorting by a mouse click on a column heading.
+ </p>
+ <p>Actually two columns are drawn on the sorting. First that one, on which
+ you clicked last, and second - if the elements are equal regarding this column -
+ that, which sorted before.
+ </p>
+ <p>Note that the sorting of the directory list of course respects the
+ tree structure: sorting occurs only within one level.
+ </p>
+ <p></p>
+ <h3>Annotation</h3>
+ <p>The column widths and column order can be adjusted via drag 'n drop.
+ The widths and column order are persistent; that is, at program
+ start they are automatically restored as you have set them last.
+ </p>
+ </BODY>
+</html>
diff --git a/wdshelp/tree.jpg b/wdshelp/tree.jpg
new file mode 100644
index 0000000..e978839
--- /dev/null
+++ b/wdshelp/tree.jpg
Binary files differ
diff --git a/wdshelp/treemap.htm b/wdshelp/treemap.htm
new file mode 100644
index 0000000..26942e2
--- /dev/null
+++ b/wdshelp/treemap.htm
@@ -0,0 +1,43 @@
+<html>
+ <head>
+ <title>Treemap</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>Treemap</h2>
+ <p>The treemap shows the whole contents of the <a href="whatisatree.htm">directory tree</a>
+ straight away.
+ </p>
+ <p>It represents each file as a colored rectangle, the area of which is
+ proportional to the file's size.
+ </p>
+ The rectangles are arranged in such a way, that directories again make up
+ rectangles, which contain all their files and subdirectories. So their area is
+ proportional to the size of the subtrees. </p>
+ <p>The color of a rectangle indicates the type of the file, as shown in the
+ extension list.
+ </p>
+ <p>The cushion shading additionally brings out the directory structure.</p>
+ <h3>Operation</h3>
+ <p>You effortlessly see the big rectangles, that is the big files, even if they are
+ hidden deeply in subdirectories in the directory tree. Click on them: the
+ directory list opens the path to the file, and you can read its location and
+ attributes, and - if you like - apply a cleanup action on it, e.g. delete the
+ file.
+ </p>
+ <p>Navigate in the directory list: the respective selection is highlighted with a
+ colored frame. In this way gain an impression of the proportions: How big, for
+ example, is C:\windows compared with C:\program files?
+ </p>
+ <p>The context menu options "Select Parent" and "Re-select Child" are also useful
+ for the navigation.
+ </p>
+ <p>Zoom. The option "Zoom in" enlarges the treemap, so that a subtree is
+ displayed full size. As it were you make a step towards the selected item.
+ The directory list show the root of this subtree with a blue frame.
+ By "Zoom out" you step back, and the parent element is shown again.
+ </p>
+ </BODY>
+</html>
diff --git a/wdshelp/userdefinedcleanups.htm b/wdshelp/userdefinedcleanups.htm
new file mode 100644
index 0000000..c1662bd
--- /dev/null
+++ b/wdshelp/userdefinedcleanups.htm
@@ -0,0 +1,67 @@
+<html>
+ <head>
+ <title>User Defined Cleanups</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h2>User Defined Cleanups</h2>
+ <p><i>This feature is for experts.</i></p>
+ <p>You can define up to 10 custom cleanup actions. The cleanups are specified by <i>command
+ lines</i>.
+ </p>
+ <p>Select an entry in the list an set it to "enabled". Choose a title, the title
+ appears in the menus.
+ </p>
+ <p>Compose a command line. Use the "MSDOS prompt" (Windows 9x, command.com) or the
+ "Command prompt" (NT, cmd.exe) to get help about the available commands and to
+ test the command line.
+ </p>
+ <h3>Examples</h3>
+ <p>
+ <ul>
+ <li>
+ <pre>dir /b > dir.txt</pre>
+ List the filenames to the text file dir.txt.</li>
+ <li>
+ <pre>del *.bak</pre>
+ Delete all *.bak files in the current directory.</li>
+ <li>
+ <pre>del /s *.bak *.tmp</pre>
+ Recursively delete all *.bak and *.tmp files.</li>
+ <li>
+ <pre>windirstat.exe "%p"</pre>
+ Call up a second instance of WinDirStat with the path of the selected directory
+ (a PATH to windirstat.exe must be set).</li>
+ </ul>
+ </p>
+ <h3>Examples (NT and higher)</h3>
+ <p>
+ <ul>
+ <li>
+ <pre>echo %n & pause</pre>
+ Display the name of the current directory.</li>
+ <li>
+ <pre>cd & pause</pre>
+ Display the current path and wait for a key stroke.</li>
+ <li>
+ <pre>cd .. && myzip "%n"</pre>
+ Compress the selected directory (with the hypothetic tool myzip).</li>
+ </ul>
+ </p>
+ <p>The meaning of the placeholders %p, %n, %sp, %sn is shown in the dialog. Don't
+ forget to enclose them in quotation marks, if necessary.</p>
+ <h3>Assembly of the command line</h3>
+ <p>Suppose you enter the command line
+ <pre>xyz</pre>
+ . WinDirStat then trys to start the following process:
+ <pre>%COMSPEC% /c xyz</pre>
+ </p>
+ <h3>More Options</h3>
+ <p>Specify, for which item types the cleanup works.</p>
+ <p>Specify, whether the cleanup shall be applied recursively on all subdirectories
+ (depth first).</p>
+ <p>The other options should be clear.</p>
+ </BODY>
+</html>
diff --git a/wdshelp/wdshelp.vcproj b/wdshelp/wdshelp.vcproj
new file mode 100644
index 0000000..38d5df5
--- /dev/null
+++ b/wdshelp/wdshelp.vcproj
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="wdshelp"
+ ProjectGUID="{7EE5206B-1657-482A-B6A1-343DE5D6DE11}"
+ Keyword="MakeFileProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="0">
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="echo The help file will only be generated in release build."
+ ReBuildCommandLine="echo The help file will only be generated in release build."
+ CleanCommandLine="echo clean"
+ Output="windirstat.chm"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="0">
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="hhc &quot;$(ProjectDir)windirstat.hhp&quot; || cd ."
+ ReBuildCommandLine="hhc &quot;$(ProjectDir)windirstat.hhp&quot; || cd ."
+ CleanCommandLine="del ..\..\release\wdsh0407.chm"
+ Output="..\..\release\windirstat.chm"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\actions.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\configuration.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\coupling.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\deinstallation.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\directorytree.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\extensionlist.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\faq.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\format.css">
+ </File>
+ <File
+ RelativePath=".\gnufdl.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\legend.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\limits.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\selectdrivesdialog.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\sorting.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\Table of Contents.hhc">
+ </File>
+ <File
+ RelativePath=".\treemap.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\userdefinedcleanups.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\whatisatree.htm"
+ DeploymentContent="TRUE">
+ </File>
+ <File
+ RelativePath=".\windirstat.hhp">
+ </File>
+ <File
+ RelativePath=".\windirstat.htm"
+ DeploymentContent="TRUE">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/wdshelp/whatisatree.htm b/wdshelp/whatisatree.htm
new file mode 100644
index 0000000..42298e1
--- /dev/null
+++ b/wdshelp/whatisatree.htm
@@ -0,0 +1,62 @@
+<html>
+ <head>
+ <title>What is a Directory Tree?</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
+ <LINK href="format.css" type="text/css" rel="stylesheet">
+ </head>
+ <BODY>
+ <h2>What is a Directory Tree?</h2>
+ <p>On most computer operating systems, so on Microsoft Windows, the data on the
+ hard disk are organized hierarchically.
+ </p>
+ <p>On the one hand there are the <i>files</i> which have a certain size and contain
+ the effective data. Each file has a name. Under Microsoft Windows the "filename
+ extension" informs about the type of the file. The extension ".exe", for
+ instance, indicates that it's a program file. The extension ".doc" indicates a
+ WinWord document, ".jpg" is a photo, and so on. But ridiculously the Microsoft
+ Windows Explorer hides these filename extensions by default. You can change
+ this behaviour in the options menu of the Windows Explorer.
+ </p>
+ <p>On the other hand there are <i>directories</i>. The Windows Explorer and
+ WinDirStat, too, symbolize directories as yellow folders. Directories also
+ have a name, but normally without a filename extension. Directories only serve
+ to contain files and other directories ("sub-directories"). Due to the fact
+ that directories can contain subdirectories, and those again can contain
+ subdirectories, the result is a hierarchical structure on the disk.
+ </p>
+ <p>
+ <img src="tree.jpg" width="99" height="105" align="left" vspace="20" hspace="20" />
+ Instead of "hierarchical structure" we simply say <i>tree structure</i>. Since
+ a tree is built hierarchical as well: The trunk branches out into branches, the
+ branches into sub-branches, twigs and finally into the leafs. In a file system
+ the so called root directory is the trunk, the directories
+ are the branches and the files are the leafs.
+ </p>
+ <p>
+ That's why we call the file system of a computer simply a "directory tree".
+ </p>
+ <p><br clear="all" />
+ Unlike most real trees, on a disk the trunk and the branches already have
+ leafs. And, unlike most real trees, too: the <u>files</u> are the voluminous
+ entities (the size of which is mesured by megabytes or gigabytes), whereas the
+ actual directories are neglectibly small. By the way, we imagine abstract trees
+ as turned round: the root at the top, the leafs at the bottom.
+ </p>
+ <p>If you saw a branch off a tree and stick it into the earth, then it becomes
+ itself a little tree (well, at least it looks like one): Every branch is,
+ together with its sub-branches and leafs, itself a tree, a <i>subtree</i>.
+ </p>
+ <p>The family tree metaphor is often used as well: The subdirectories and files of
+ a directory are called its <i>children</i>. And a directory containing a
+ subdirectory or file is called their <i>parent</i>. The root directory is
+ earliest ancestor of all items in the directory tree.
+ </p>
+ <p>A <i>path</i> like "C:\documents\letters\draft\loveletter.doc" indicates that on
+ the hard disk C:, in the root directory "C:\" there is a directory "documents",
+ under it the subdirectory "letters", under it a subdirectory "draft" and in
+ there a file "loveletter.doc". So the path is a precise representation of the
+ way from the root to the leaf.
+ </p>
+ </BODY>
+</html>
diff --git a/wdshelp/windirstat.hhp b/wdshelp/windirstat.hhp
new file mode 100644
index 0000000..7eaaa3a
--- /dev/null
+++ b/wdshelp/windirstat.hhp
@@ -0,0 +1,43 @@
+[OPTIONS]
+Compatibility=1.1 or later
+Compiled file=..\..\release\windirstat.chm
+Contents file=Table of Contents.hhc
+Default Window=main
+Default topic=windirstat.htm
+Display compile progress=No
+Full-text search=Yes
+Language=0x409 Englisch (USA)
+Title=WinDirStat
+
+[WINDOWS]
+main="WinDirStat","Table of Contents.hhc",,"windirstat.htm","windirstat.htm",,,,,0x63420,,0x3006,[22,19,816,782],0x108f0000,,,,,,0
+
+
+[FILES]
+windirstat.htm
+directorytree.htm
+extensionlist.htm
+treemap.htm
+actions.htm
+configuration.htm
+coupling.htm
+faq.htm
+gnufdl.htm
+legend.htm
+selectdrivesdialog.htm
+sorting.htm
+whatisatree.htm
+userdefinedcleanups.htm
+limits.htm
+deinstallation.htm
+
+[ALIAS]
+IDH_StartPage=windirstat.htm
+IDH_UserDefinedCleanups=userdefinedcleanups.htm
+IDH_Treemap=treemap.htm
+
+[MAP]
+#include ..\windirstat\helpmap.h
+
+[INFOTYPES]
+
diff --git a/wdshelp/windirstat.htm b/wdshelp/windirstat.htm
new file mode 100644
index 0000000..160d5d2
--- /dev/null
+++ b/wdshelp/windirstat.htm
@@ -0,0 +1,63 @@
+<html>
+ <head>
+ <title>WinDirStat</title>
+ <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+ <link rel="stylesheet" type="text/css" href="format.css">
+ </head>
+ <BODY>
+ <h1 style="margin-bottom:1pt">WinDirStat - Directory Statistics</h1>
+ <P style="font-size:70%;margin-top:2pt">Copyright (c) 2003 Bernhard Seifert.
+ Permission is granted to copy, distribute and/or modify this document under the
+ terms of the GNU Free Documentation License, Version 1.2 or any later version
+ published by the Free Software Foundation; with no Invariant Sections, no
+ Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included
+ in the section entitled "GNU Free Documentation License".
+ </P>
+ <p>Shows where all your disk space has gone, and helps you clean it up.
+ </p>
+ <p style="color=#006000">You know the problem: The hard disk is almost full, and
+ you don't know, where the big files actually are lying, which occupy all the
+ space. They may well be hidden in sub-sub-directories. To find out this by
+ means of the Windows Explorer, is tiring: you had to expand and collapse the
+ directories again and again or view the "Properties" of the directories, which
+ always count just the size of <i>one</i> subtree. It's hard to form a mental
+ image of the hard disk usage in this way. This is where WinDirStat helps.
+ </p>
+ <p>On start up WinDirStat opens the <a href="selectdrivesdialog.htm">Select Drives
+ Dialog</a>. Press the OK button.
+ </p>
+ <p>
+ Then WinDirStat reads in the whole <a href="whatisatree.htm">directory tree</a>
+ once (this can last some minutes depending on the hard disk size) and then
+ presents it in three useful views:
+ </p>
+ <table border="1" bordercolor="#007000" style="BORDER-RIGHT:3px solid; BORDER-TOP:3px solid; BORDER-LEFT:3px solid; WIDTH:373px; BORDER-BOTTOM:3px solid; BORDER-COLLAPSE:collapse; HEIGHT:226px">
+ <tr>
+ <td colspan="2" style="COLOR:#ffffff; HEIGHT:17px; BACKGROUND-COLOR:#007000">WinDirStat</td>
+ </tr>
+ <tr style="HEIGHT:80px">
+ <td align="center" style="WIDTH: 241px; HEIGHT: 70px"><a href="directorytree.htm">Directory
+ List</a></td>
+ <td align="center" style="HEIGHT: 70px"><a href="extensionlist.htm">Extension List</a></td>
+ </tr>
+ <tr style="HEIGHT:100px">
+ <td colspan="2" align="center"><a href="treemap.htm">Treemap</a></td>
+ </tr>
+ </table>
+ <p>The views are <a href="coupling.htm">coupled</a> with each other.
+ </p>
+ <p>You can clean up the hard disks with serveral <a href="actions.htm">Cleanups</a>.
+ </p>
+ <p>The views and the <a href="userdefinedcleanups.htm">User Defined Cleanups</a> can
+ be <a href="configuration.htm">configured</a> according to your personal needs.
+ </p>
+ <p><a href="sorting.htm">Sorting</a></p>
+ <p><a href="legend.htm">Legend</a></p>
+ <p><a href="faq.htm">Frequently Asked Questions</a></p>
+ <p><a href="limits.htm">Limits</a></p>
+ <p><a href="deinstallation.htm">Deinstallation</a></p>
+ <P style="font-size:70%"><a href="gnufdl.htm">GNU Free Documentation License</a></P>
+ <P>&nbsp;</P>
+ </BODY>
+</html>
diff --git a/wdsr0407/res/Toolbar.bmp b/wdsr0407/res/Toolbar.bmp
new file mode 100644
index 0000000..b05920f
--- /dev/null
+++ b/wdsr0407/res/Toolbar.bmp
Binary files differ
diff --git a/wdsr0407/res/bitmap1.bmp b/wdsr0407/res/bitmap1.bmp
new file mode 100644
index 0000000..4f8b0bd
--- /dev/null
+++ b/wdsr0407/res/bitmap1.bmp
Binary files differ
diff --git a/wdsr0407/res/icon1.ico b/wdsr0407/res/icon1.ico
new file mode 100644
index 0000000..e645c24
--- /dev/null
+++ b/wdsr0407/res/icon1.ico
Binary files differ
diff --git a/wdsr0407/res/license.txt b/wdsr0407/res/license.txt
new file mode 100644
index 0000000..651a1f0
--- /dev/null
+++ b/wdsr0407/res/license.txt
@@ -0,0 +1,345 @@
+
+This program is distributed under the terms of the GPL v2.
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
diff --git a/wdsr0407/res/windirstat.manifest b/wdsr0407/res/windirstat.manifest
new file mode 100644
index 0000000..09ebb83
--- /dev/null
+++ b/wdsr0407/res/windirstat.manifest
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="X86"
+ name="Microsoft.Windows.windirstat"
+ type="win32"
+/>
+<description>Fügen Sie hier die Anwendungsbeschreibung ein</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+</assembly>
diff --git a/wdsr0407/resource.h b/wdsr0407/resource.h
new file mode 100644
index 0000000..900bc44
--- /dev/null
+++ b/wdsr0407/resource.h
@@ -0,0 +1,243 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by windirstat.rc
+//
+#define IDD_ABOUTBOX 100
+#define ID_VIEW_ARRANGE 127
+#define IDR_MAINFRAME 128
+#define IDR_windirstatTYPE 129
+#define IDR_11 130
+#define IDB_NODES 131
+#define IDD_SELECTDRIVES 133
+#define IDR_POPUPLIST 134
+#define IDB_IMAGELIST 135
+#define IDR_POPUPGRAPH 136
+#define IDR_LICENSE 137
+#define IDD_DELETE_WARNING 138
+#define IDD_INVISIBLE 140
+#define IDD_MODALSHELLAPI 140
+#define IDD_MODALAPISHUTTLE 140
+#define IDD_PAGE_CLEANUPS 141
+#define IDD_PAGE_TREELIST 142
+#define IDD_PAGE_TREEMAP 143
+#define IDD_PAGE_GENERAL 144
+#define IDD_REPORTBUG 145
+#define IDS_RESOURCEVERSION 199
+#define IDS_ABOUT_ABOUTTEXTss 200
+#define IDS_ABOUT_THANKSTOTEXT 201
+#define IDS_ABOUT_ABOUT 202
+#define IDS_ABOUT_THANKSTO 203
+#define IDS_ABOUT_LICENSEAGREEMENT 204
+#define IDS_MYCOMPUTER 205
+#define IDS_UDC_CONFIRMATIONss 206
+#define IDS_RUDC_CONFIRMATIONss 207
+#define IDS_THEDIRECTORYsDOESNOTEXIST 208
+#define IDS_THEFILEsDOESNOTEXIST 209
+#define IDS_COULDNOTCREATEPROCESSssss 210
+#define IDS_TREECOL_NAME 211
+#define IDS_TREECOL_SUBTREEPERCENTAGE 212
+#define IDS_TREECOL_PERCENTAGE 213
+#define IDS_TREECOL_SIZE 214
+#define IDS_TREECOL_ITEMS 215
+#define IDS_TREECOL_FILES 216
+#define IDS_TREECOL_SUBDIRS 217
+#define IDS_TREECOL_LASTCHANGE 218
+#define IDS_PLEASECHECKYOURDISKUSAGE 219
+#define IDS_DISKUSAGEREPORTGENERATEDBYWINDIRSTAT 220
+#define IDS__UNKNOWN_ 221
+#define IDS_FREESPACE_ITEM 222
+#define IDS_UNKNOWN_ITEM 223
+#define IDS_FILES_ITEM 224
+#define IDS_ONEREADJOB 225
+#define IDS_sREADJOBS 226
+#define IDS_CANNOTOPENCLIPBOARD 227
+#define IDS_CANNOTEMTPYCLIPBOARD 228
+#define IDS_CANNOTSETCLIPBAORDDATA 229
+#define IDS_WINDIRSTAT_SETTINGS 230
+#define IDS_SCANNING_ 231
+#define IDS_EMPTYRECYCLEBIN 232
+#define IDS__ONEITEMss 233
+#define IDS__sITEMSss 234
+#define IDS_UDCsCTRLd 235
+#define IDS_USERDEFINEDCLEANUP0 236
+#define IDS_REPORT_DISKUSAGE 237
+#define IDS_USERDEFINEDCLEANUPd 238
+#define IDS_POLICY_NOREFRESH 239
+#define IDS_POLICY_REFRESHTHISENTRY 240
+#define IDS_POLICY_REFRESHPARENT 241
+#define IDS_BUGREPORTHINT 242
+#define IDS_FEEDBACKHINT 243
+#define IDS_FROMsPLATFORMs 244
+#define IDS_SEV_CRITICAL 245
+#define IDS_SEV_GRAVE 246
+#define IDS_SEV_NORMAL 247
+#define IDS_SEV_WISH 248
+#define IDS_SEV_FEEDBACK 249
+#define IDS_DRIVECOL_NAME 250
+#define IDS_DRIVECOL_TOTAL 251
+#define IDS_DRIVECOL_FREE 252
+#define IDS_DRIVECOL_GRAPH 253
+#define IDS_DRIVECOL_PERCENTUSED 254
+#define IDS_SELECTFOLDER 255
+#define IDS_EXTCOL_EXTENSION 256
+#define IDS_EXTCOL_COLOR 257
+#define IDS_EXTCOL_BYTES 258
+#define IDS_EXTCOL_FILES 259
+#define IDS_EXTCOL_DESCRIPTION 260
+#define IDS_RAMUSAGEs 261
+#define IDS_HELPFILEsCOULDNOTBEFOUND 262
+#define IDS_SUSPENDED_ 263
+#define IDS_SUSPEND 264
+#define IDC_ALLDRIVES 1000
+#define IDC_GROUPS 1000
+#define IDC_ALLLOCALDRIVES 1000
+#define IDC_SOMEDRIVES 1001
+#define IDC_EXTENSIONS 1001
+#define IDC_AFOLDER 1002
+#define IDC_MEMBERS 1002
+#define IDC_FOLDERNAME 1003
+#define IDC_BROWSEFOLDER 1004
+#define IDC_DRIVES 1005
+#define IDC_TEXT 1012
+#define IDC_TAB 1013
+#define IDC_CAPTION 1014
+#define IDC_FILENAME 1016
+#define IDC_DONTSHOWAGAIN 1017
+#define IDC_CHECK1 1020
+#define IDC_FOLLOWMOUNTPOINTS 1020
+#define IDC_CHECK2 1021
+#define IDC_PACMANANIMATION 1021
+#define IDC_TREEMAPGRID 1022
+#define IDC_ASKFORCONFIRMATION 1022
+#define IDC_SHOWCONSOLEWINDOW 1023
+#define IDC_WAITFORCOMPLETION 1024
+#define IDC_HEIGHTFACTORSPIN 1026
+#define IDC_HEIGHTFACTOR 1027
+#define IDC_TREELISTGRID 1028
+#define IDC_SCALEFACTOR 1028
+#define IDC_HUMANFORMAT 1029
+#define IDC_SCALEFACTORSPIN 1029
+#define IDC_TREEMAPGRIDCOLOR 1030
+#define IDC_CUSHIONSHADING 1031
+#define IDC_AMBIENTLIGHT 1032
+#define IDC_AMBIENTLIGHTSPIN 1033
+#define IDC_RESETTODEFAULTS 1034
+#define IDC_DEMO 1035
+#define IDC_LIST 1036
+#define IDC_TITLE 1037
+#define IDC_COMMANDLINE 1038
+#define IDC_WORKSFORFILES 1039
+#define IDC_WORKSFORDIRECTORIES 1040
+#define IDC_WORKSFORFILESFOLDER 1041
+#define IDC_WORKSFORDRIVES 1042
+#define IDC_REFRESHPOLICY 1043
+#define IDC_HELPBUTTON 1044
+#define IDC_ENABLED 1045
+#define IDC_RECURSEINTOSUBDIRECTORIES 1046
+#define IDC_HINTSP 1047
+#define IDC_HINTSN 1048
+#define IDC_UP 1049
+#define IDC_DOWN 1050
+#define IDC_FROM 1050
+#define IDC_TO 1051
+#define IDC_CRITICAL 1052
+#define IDC_GRAVE 1053
+#define IDC_NORMAL 1054
+#define IDC_WISH 1055
+#define IDC_INAWORD 1056
+#define IDC_APPLICATION 1057
+#define IDC_FEEDBACK 1058
+#define IDC_PLATFORM 1059
+#define IDC_HINT 1060
+#define IDC_COLORBUTTON0 1100
+#define IDC_COLORBUTTON1 1101
+#define IDC_COLORBUTTON2 1102
+#define IDC_COLORBUTTON3 1103
+#define IDC_COLORBUTTON4 1104
+#define IDC_COLORBUTTON5 1105
+#define IDC_COLORBUTTON6 1106
+#define IDC_COLORBUTTON7 1107
+#define IDC_SLIDER1 1200
+#define IDC_SLIDER 1200
+#define IDC_BUTTON8 1201
+#define IDC_TREEMAPHIGHLIGHTCOLOR 1202
+#define IDC_COMBO1 1203
+#define IDC_COMBO 1203
+#define IDC_STATIC_TO 1204
+#define IDC_STATIC_PLATFORM 1205
+#define IDC_STATIC_SEVERITY 1206
+#define IDC_STATIC_OKHINT 1207
+#define ID_FILE_OPENURL 32771
+#define ID_FILE_OPENRECENT 32772
+#define ID_FILE_REFRESHALL 32773
+#define ID_CLEANUP_OPENINEXPLORER 32774
+#define ID_CLEANUP_COMPRESS 32776
+#define ID_CLEANUP_DELETETRASHFILES 32777
+#define ID_Menu 32781
+#define ID_TREEMAP_ZOOMIN 32783
+#define ID_TREEMAP_ZOOMOUT 32784
+#define ID_TREEMAP_SELECTPARENT 32785
+#define ID_TREEMAP_REBUILDTREEMAP 32786
+#define ID_TREEMAP_HELPABOUTTREEMAPS 32787
+#define ID_REPORT_SENDMAILTOOWNER 32788
+#define ID_SETTINGS_SHOWTREEMAP 32789
+#define ID_SETTINGS_SHOWTOOLBAR 32790
+#define ID_SETTINGS_SHOW 32791
+#define ID_VIEW_SHOWTREEMAP 32792
+#define ID_SETTINGS_CONFIGUREWINDIRSTAT 32793
+#define ID_HELP_REPORTBUG 32796
+#define ID_HELP_SENDFEEDBACKMAIL 32797
+#define ID_FILE_REFRESHSELECTED 32801
+#define ID_FILE_CONTINUEREADINGATMOUNTPOINT 32802
+#define ID_CLEANUP_MAKECLEAN 32803
+#define ID_FILE_OPENRECENT_0 32806
+#define ID_FILE_OPENRECENT_1 32807
+#define ID_CLEANUP_OPENINCONSOLE 32808
+#define ID_CLEANUP_DELETETOTRASHBIN 32809
+#define ID_CLEANUP_DELETE 32810
+#define ID_CONFIGURE 32813
+#define ID_HELP_MANUAL 32814
+#define ID_HELP_WHATSTHIS 32815
+#define ID_REFRESHALL 32816
+#define ID_REFRESHSELECTED 32817
+#define ID_CLEANUP_EMPTYRECYCLEBIN 32818
+#define ID_VIEW_SHOWFREESPACE 32819
+#define ID_VIEW_SHOWUNKNOWN 32820
+#define ID_POPUP 32826
+#define ID_Menu32827 32827
+#define ID_Menu32828 32828
+#define ID_Menu32829 32829
+#define ID_BUTTON32835 32835
+#define ID_BUTTON32837 32837
+#define ID_VIEW_SHOWFILETYPES 32846
+#define ID_SENDMAILTOOWNER 32856
+#define ID_USERDEFINEDCLEANUP0 32900
+#define ID_USERDEFINEDCLEANUP1 32901
+#define ID_USERDEFINEDCLEANUP2 32902
+#define ID_USERDEFINEDCLEANUP3 32903
+#define ID_USERDEFINEDCLEANUP4 32904
+#define ID_USERDEFINEDCLEANUP5 32905
+#define ID_USERDEFINEDCLEANUP6 32906
+#define ID_USERDEFINEDCLEANUP7 32907
+#define ID_USERDEFINEDCLEANUP8 32908
+#define ID_USERDEFINEDCLEANUP9 32909
+#define ID_DUMMY_USERDEFINEDCLEANUP 33005
+#define ID_POPUP_CANCEL 33008
+#define ID_TREEMAP_RESELECTCHILD 33011
+#define ID_Menu33012 33012
+#define ID_Menu33013 33013
+#define ID_CLEANUP_OPEN 33015
+#define ID_CLEANUP_PROPERTIES 33019
+#define ID_BUTTON33021 33021
+#define ID_INDICATOR_MEMORYUSAGE 59142
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 900
+#define _APS_NEXT_COMMAND_VALUE 33022
+#define _APS_NEXT_CONTROL_VALUE 1208
+#define _APS_NEXT_SYMED_VALUE 104
+#endif
+#endif
diff --git a/wdsr0407/wdsr0407.vcproj b/wdsr0407/wdsr0407.vcproj
new file mode 100644
index 0000000..dde158c
--- /dev/null
+++ b/wdsr0407/wdsr0407.vcproj
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="wdsr0407"
+ ProjectGUID="{C7A5D1EC-35D3-4754-A815-2C527CACD584}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="../../Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;WDSR0407_EXPORTS"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="../../debug/wdsr0407.dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/wdsr0407.pdb"
+ SubSystem="2"
+ ResourceOnlyDLL="TRUE"
+ ImportLibrary="$(OutDir)/wdsr0407.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="../../Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;WDSR0407_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="../../release/wdsr0407.dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ResourceOnlyDLL="TRUE"
+ ImportLibrary="$(OutDir)/wdsr0407.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Unicode Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;WDSR0407_EXPORTS"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="../../debug/wdsr0407U.dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/wdsr0407.pdb"
+ SubSystem="2"
+ ResourceOnlyDLL="TRUE"
+ ImportLibrary="$(OutDir)/wdsr0407.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Unicode Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;WDSR0407_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="../../release/wdsr0407U.dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ResourceOnlyDLL="TRUE"
+ ImportLibrary="$(OutDir)/wdsr0407.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\resource.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ <File
+ RelativePath=".\res\bitmap1.bmp">
+ </File>
+ <File
+ RelativePath=".\res\icon1.ico">
+ </File>
+ <File
+ RelativePath=".\res\license.txt">
+ </File>
+ <File
+ RelativePath=".\res\Toolbar.bmp">
+ </File>
+ <File
+ RelativePath=".\windirstat.rc">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/wdsr0407/windirstat.rc b/wdsr0407/windirstat.rc
new file mode 100644
index 0000000..e203db5
--- /dev/null
+++ b/wdsr0407/windirstat.rc
@@ -0,0 +1,818 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// German (Germany) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL)\r\n"
+ "LANGUAGE 7, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON "res\\icon1.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDR_MAINFRAME BITMAP "res\\Toolbar.bmp"
+IDB_NODES BITMAP "res\\bitmap1.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Toolbar
+//
+
+IDR_MAINFRAME TOOLBAR 16, 15
+BEGIN
+ BUTTON ID_FILE_OPEN
+ BUTTON ID_REFRESHALL
+ SEPARATOR
+ BUTTON ID_CLEANUP_OPEN
+ BUTTON ID_EDIT_COPY
+ BUTTON ID_CLEANUP_OPENINEXPLORER
+ BUTTON ID_CLEANUP_OPENINCONSOLE
+ BUTTON ID_REFRESHSELECTED
+ SEPARATOR
+ BUTTON ID_CLEANUP_DELETETOTRASHBIN
+ BUTTON ID_CLEANUP_DELETE
+ SEPARATOR
+ BUTTON ID_CLEANUP_PROPERTIES
+ SEPARATOR
+ BUTTON ID_TREEMAP_ZOOMIN
+ BUTTON ID_TREEMAP_ZOOMOUT
+ SEPARATOR
+ BUTTON ID_HELP_MANUAL
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MAINFRAME MENU
+BEGIN
+ POPUP "&Datei"
+ BEGIN
+ MENUITEM "&Öffnen...\tStrg+O", ID_FILE_OPEN
+ MENUITEM SEPARATOR
+ MENUITEM "&Alles aktualisieren", ID_REFRESHALL
+ MENUITEM "&Markierung aktualisieren", ID_REFRESHSELECTED
+ MENUITEM SEPARATOR
+ MENUITEM "&Beenden\tAlt+F4", ID_APP_EXIT
+ END
+ POPUP "&Bearbeiten"
+ BEGIN
+ MENUITEM "&Pfad kopieren\tStrg+C", ID_EDIT_COPY
+ END
+ POPUP "&Aufräumen"
+ BEGIN
+ MENUITEM "&Öffnen\tEnter", ID_CLEANUP_OPEN
+ MENUITEM SEPARATOR
+ MENUITEM "&Explorer hier starten\tStrg+E", ID_CLEANUP_OPENINEXPLORER
+ MENUITEM "&DOS-Prompt hier starten\tStrg+P",
+ ID_CLEANUP_OPENINCONSOLE
+ MENUITEM "&Löschen (in den Papierkorb)\tEntf",
+ ID_CLEANUP_DELETETOTRASHBIN
+ MENUITEM "Löschen (&irreversibel!)\tUmschalt+Entf",
+ ID_CLEANUP_DELETE
+ MENUITEM SEPARATOR
+ MENUITEM "Ei&genschaften", ID_CLEANUP_PROPERTIES
+ MENUITEM SEPARATOR
+ MENUITEM "&Papierkorb leeren", ID_CLEANUP_EMPTYRECYCLEBIN
+ MENUITEM SEPARATOR
+ MENUITEM "Benutzerdefinierte Aktion Nr.0",
+ ID_DUMMY_USERDEFINEDCLEANUP
+ , GRAYED
+ END
+ POPUP "&Baumkarte"
+ BEGIN
+ MENUITEM "&Baumkarte anzeigen\tF9", ID_VIEW_SHOWTREEMAP
+ MENUITEM SEPARATOR
+ MENUITEM "Hin&einzoomen\t+", ID_TREEMAP_ZOOMIN
+ MENUITEM "Her&auszoomen\t-", ID_TREEMAP_ZOOMOUT
+ MENUITEM "Zurück zum &Kindelement\t*", 33011
+ MENUITEM "Zum &Elternelement\t/", ID_TREEMAP_SELECTPARENT
+ MENUITEM SEPARATOR
+ MENUITEM "&Hilfe zur Baumkarte", ID_TREEMAP_HELPABOUTTREEMAPS
+ END
+ POPUP "&Report"
+ BEGIN
+ MENUITEM "&E-Mail an den Eigentümer senden...", ID_SENDMAILTOOWNER
+ END
+ POPUP "&Optionen"
+ BEGIN
+ MENUITEM "&Freien Platz anzeigen\tF6", ID_VIEW_SHOWFREESPACE
+ MENUITEM "&Unbekannten Platz anzeigen\tF7", ID_VIEW_SHOWUNKNOWN
+ MENUITEM SEPARATOR
+ MENUITEM "&Dateityp-Liste anzeigen\tF8", ID_VIEW_SHOWFILETYPES
+ MENUITEM "&Baumkarte anzeigen\tF9", ID_VIEW_SHOWTREEMAP
+ MENUITEM "&Symbolleiste anzeigen", ID_VIEW_TOOLBAR
+ MENUITEM "S&tatusleiste anzeigen", ID_VIEW_STATUS_BAR
+ MENUITEM SEPARATOR
+ MENUITEM "&WinDirStat konfigurieren...", ID_CONFIGURE
+ END
+ POPUP "&?"
+ BEGIN
+ MENUITEM "&Hilfe\tF1", ID_HELP_MANUAL
+ MENUITEM "&Fehlerbericht/Feedback...", ID_HELP_REPORTBUG
+ MENUITEM SEPARATOR
+ MENUITEM "&Über WinDirStat...", ID_APP_ABOUT
+ END
+END
+
+IDR_POPUPLIST MENU
+BEGIN
+ POPUP "POPUP_LIST"
+ BEGIN
+ MENUITEM "&Öffnen\tEnter", ID_CLEANUP_OPEN
+ MENUITEM SEPARATOR
+ MENUITEM "&Pfad kopieren\tStrg+C", 57634
+ MENUITEM "&Explorer hier starten\tStrg+E", 32774
+ MENUITEM "&DOS-Prompt hier starten\tStrg+P", 32808
+ MENUITEM "&Markierung aktualisieren", 32817
+ MENUITEM SEPARATOR
+ MENUITEM "&Löschen (in den Papierkorb)\tEntf", 32809
+ MENUITEM "Löschen (&irreversibel!)\tUmschalt+Entf", 32810
+ MENUITEM SEPARATOR
+ MENUITEM "Ei&genschaften", ID_CLEANUP_PROPERTIES
+ MENUITEM SEPARATOR
+ END
+END
+
+IDR_POPUPGRAPH MENU
+BEGIN
+ POPUP "POPUP_GRAPH"
+ BEGIN
+ MENUITEM "Hin&einzoomen\t+", 32783
+ MENUITEM "Her&auszoomen\t-", 32784
+ MENUITEM "Zurück zum &Kindelement\t*", ID_TREEMAP_RESELECTCHILD
+ MENUITEM "Zum &Elternelement\t/", ID_TREEMAP_SELECTPARENT
+ MENUITEM SEPARATOR
+ MENUITEM "&Pfad kopieren\tStrg+C", 57634
+ MENUITEM "&Explorer hier starten\tStrg+E", 32774
+ MENUITEM "&DOS-Prompt hier starten\tStrg+P", 32808
+ MENUITEM SEPARATOR
+ MENUITEM "&Abbrechen\tEsc", ID_POPUP_CANCEL
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_MAINFRAME ACCELERATORS
+BEGIN
+ VK_DELETE, ID_CLEANUP_DELETE, VIRTKEY, SHIFT, NOINVERT
+ VK_DELETE, ID_CLEANUP_DELETETOTRASHBIN, VIRTKEY, NOINVERT
+ "P", ID_CLEANUP_OPENINCONSOLE, VIRTKEY, CONTROL, NOINVERT
+ "E", ID_CLEANUP_OPENINEXPLORER, VIRTKEY, CONTROL, NOINVERT
+ "C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ "N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT
+ "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
+ VK_F1, ID_HELP_MANUAL, VIRTKEY, NOINVERT
+ VK_MULTIPLY, ID_TREEMAP_RESELECTCHILD, VIRTKEY, NOINVERT
+ VK_DIVIDE, ID_TREEMAP_SELECTPARENT, VIRTKEY, NOINVERT
+ VK_ADD, ID_TREEMAP_ZOOMIN, VIRTKEY, NOINVERT
+ VK_SUBTRACT, ID_TREEMAP_ZOOMOUT, VIRTKEY, NOINVERT
+ "0", ID_USERDEFINEDCLEANUP0, VIRTKEY, CONTROL, NOINVERT
+ "1", ID_USERDEFINEDCLEANUP1, VIRTKEY, CONTROL, NOINVERT
+ "2", ID_USERDEFINEDCLEANUP2, VIRTKEY, CONTROL, NOINVERT
+ "3", ID_USERDEFINEDCLEANUP3, VIRTKEY, CONTROL, NOINVERT
+ "4", ID_USERDEFINEDCLEANUP4, VIRTKEY, CONTROL, NOINVERT
+ "5", ID_USERDEFINEDCLEANUP5, VIRTKEY, CONTROL, NOINVERT
+ "6", ID_USERDEFINEDCLEANUP6, VIRTKEY, CONTROL, NOINVERT
+ "7", ID_USERDEFINEDCLEANUP7, VIRTKEY, CONTROL, NOINVERT
+ "8", ID_USERDEFINEDCLEANUP8, VIRTKEY, CONTROL, NOINVERT
+ "9", ID_USERDEFINEDCLEANUP9, VIRTKEY, CONTROL, NOINVERT
+ VK_F8, ID_VIEW_SHOWFILETYPES, VIRTKEY, NOINVERT
+ VK_F6, ID_VIEW_SHOWFREESPACE, VIRTKEY, NOINVERT
+ VK_F9, ID_VIEW_SHOWTREEMAP, VIRTKEY, NOINVERT
+ VK_F7, ID_VIEW_SHOWUNKNOWN, VIRTKEY, NOINVERT
+ VK_RETURN, ID_CLEANUP_OPEN, VIRTKEY, NOINVERT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 273, 199
+STYLE DS_SETFONT | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU |
+ WS_THICKFRAME
+CAPTION "Über WinDirStat"
+FONT 9, "Microsoft Sans Serif", 400, 0, 0x0
+BEGIN
+ CONTROL "",IDC_TAB,"SysTabControl32",WS_TABSTOP,7,22,259,155,
+ WS_EX_ACCEPTFILES
+ DEFPUSHBUTTON "OK",IDOK,111,180,50,12,WS_GROUP
+ CTEXT "WinDirStat 0.0.000",IDC_CAPTION,69,7,134,8
+ ICON IDR_MAINFRAME,IDC_STATIC,7,3,20,20
+END
+
+IDD_SELECTDRIVES DIALOGEX 0, 0, 276, 182
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU |
+ WS_THICKFRAME
+CAPTION "WinDirStat - Laufwerke auswählen"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "&Alle lokalen Laufwerke",IDC_ALLLOCALDRIVES,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP,7,7,99,10
+ CONTROL "&Einzelne Laufwerke",IDC_SOMEDRIVES,"Button",
+ BS_AUTORADIOBUTTON,7,31,91,10
+ CONTROL "",IDC_DRIVES,"SysListView32",LVS_REPORT |
+ LVS_OWNERDRAWFIXED | LVS_ALIGNLEFT | WS_BORDER |
+ WS_TABSTOP,7,43,262,101
+ CONTROL "Ein &Verzeichnis",IDC_AFOLDER,"Button",
+ BS_AUTORADIOBUTTON,7,150,100,10
+ EDITTEXT IDC_FOLDERNAME,6,161,210,14,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_BROWSEFOLDER,219,161,50,14
+ DEFPUSHBUTTON "OK",IDOK,219,7,50,14
+ PUSHBUTTON "Abbruch",IDCANCEL,219,24,50,14
+END
+
+IDD_DELETE_WARNING DIALOGEX 0, 0, 276, 150
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Warnung"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "Nein",IDNO,163,129,50,14
+ PUSHBUTTON "Ja",IDYES,63,129,50,14
+ CONTROL "&Diese Warnung nicht mehr anzeigen",IDC_DONTSHOWAGAIN,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,99,139,10
+ LTEXT "Wissen Sie was Sie tun?",IDC_STATIC,7,7,110,8
+ LTEXT "Sie sind dabei",IDC_STATIC,7,23,82,8
+ CTEXT "<filename>",IDC_FILENAME,7,38,262,8,SS_PATHELLIPSIS
+ LTEXT "zu löschen.",IDC_STATIC,7,53,67,8
+ LTEXT "Das Löschen von Systemdateien oder -verzeichnissen kann das System ernsthaft beschädigen.",
+ IDC_STATIC,7,76,241,18
+ LTEXT "Fortfahren?",IDC_STATIC,7,99,87,8
+END
+
+IDD_MODALAPISHUTTLE DIALOGEX 0, 0, 186, 90
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "<invisible dialog>"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+END
+
+IDD_PAGE_CLEANUPS DIALOGEX 0, 0, 380, 202
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Aktionen"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LISTBOX IDC_LIST,7,7,113,169,LBS_HASSTRINGS |
+ LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ CONTROL "&Freigegeben",IDC_ENABLED,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,129,7,53,10
+ EDITTEXT IDC_TITLE,212,7,161,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_COMMANDLINE,129,35,244,14,ES_AUTOHSCROLL
+ LTEXT "%p Kompletter Pfad",IDC_STATIC,128,54,94,8
+ LTEXT "%n Datei/Verzeichnisname ohne Pfad",IDC_STATIC,225,54,
+ 138,8
+ LTEXT "%sp Kompletter Pfad des Unterverzeichnisses",IDC_HINTSP,
+ 128,63,91,16
+ LTEXT "%sn Name des Unterverzeichnisses ohne Pfad",IDC_HINTSN,
+ 225,63,138,16
+ CONTROL "&Laufwerke",IDC_WORKSFORDRIVES,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,138,92,49,10
+ CONTROL "&Verzeichnisse",IDC_WORKSFORDIRECTORIES,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,218,92,69,10
+ CONTROL "&Dateien",IDC_WORKSFORFILES,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,138,107,69,10
+ CONTROL "<Dateien>-&Pseudoeinträge",IDC_WORKSFORFILESFOLDER,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,217,107,122,10
+ PUSHBUTTON "&Hilfe",IDC_HELPBUTTON,323,131,50,14
+ CONTROL "&Rekursiv",IDC_RECURSEINTOSUBDIRECTORIES,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,128,132,160,10
+ CONTROL "&Sicherheitsabfrage",IDC_ASKFORCONFIRMATION,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,128,146,160,10
+ CONTROL "K&onsolenfenster anzeigen",IDC_SHOWCONSOLEWINDOW,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,128,160,100,10
+ CONTROL "Auf Beendigung &warten",IDC_WAITFORCOMPLETION,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,250,160,100,10
+ COMBOBOX IDC_REFRESHPOLICY,128,183,245,93,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "&Auf",IDC_UP,21,181,37,14
+ PUSHBUTTON "A&b",IDC_DOWN,66,181,37,14
+ LTEXT "A&ktualisierung",IDC_STATIC,128,174,46,8
+ LTEXT "&Titel",IDC_STATIC,191,7,16,8
+ LTEXT "&Kommandozeile",IDC_STATIC,129,25,77,8
+ GROUPBOX "Anwendbar auf",IDC_STATIC,129,81,244,40
+END
+
+IDD_PAGE_TREELIST DIALOGEX 0, 0, 380, 199
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Verzeichnisliste"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "&Raster anzeigen",IDC_TREELISTGRID,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,23,25,95,10
+ PUSHBUTTON "Ebene &1",IDC_COLORBUTTON0,151,19,175,14,0,WS_EX_RIGHT
+ PUSHBUTTON "Ebene &2",IDC_COLORBUTTON1,167,40,159,14,0,WS_EX_RIGHT
+ PUSHBUTTON "Ebene &3",IDC_COLORBUTTON2,181,61,145,14,0,WS_EX_RIGHT
+ PUSHBUTTON "Ebene &4",IDC_COLORBUTTON3,195,82,131,14,0,WS_EX_RIGHT
+ PUSHBUTTON "Ebene &5",IDC_COLORBUTTON4,207,103,119,14,0,WS_EX_RIGHT
+ PUSHBUTTON "Ebene &6",IDC_COLORBUTTON5,218,124,108,14,0,WS_EX_RIGHT
+ PUSHBUTTON "Ebene &7",IDC_COLORBUTTON6,227,145,99,14,0,WS_EX_RIGHT
+ PUSHBUTTON "Ebene &8",IDC_COLORBUTTON7,236,166,90,14,0,WS_EX_RIGHT
+ CONTROL "",IDC_SLIDER,"msctls_trackbar32",TBS_VERT | TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,339,29,18,160
+ GROUPBOX "&Teilbaumanteil-Farben",IDC_STATIC,129,7,244,185
+END
+
+IDD_PAGE_TREEMAP DIALOGEX 0, 0, 380, 202
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Baumkarte"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "&Kisseneffekt",IDC_CUSHIONSHADING,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,18,15,83,10
+ LTEXT "&Höhe",IDC_STATIC,31,32,50,8
+ EDITTEXT IDC_HEIGHTFACTOR,88,30,35,14,ES_AUTOHSCROLL
+ CONTROL "",IDC_HEIGHTFACTORSPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,125,30,
+ 11,14
+ LTEXT "&Skalierungsfaktor",IDC_STATIC,31,53,53,8
+ EDITTEXT IDC_SCALEFACTOR,88,51,35,14,ES_AUTOHSCROLL
+ CONTROL "",IDC_SCALEFACTORSPIN,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_AUTOBUDDY | UDS_ARROWKEYS,125,51,11,14
+ LTEXT "&Umgebungslicht",IDC_STATIC,31,74,53,8
+ EDITTEXT IDC_AMBIENTLIGHT,88,73,35,14,ES_AUTOHSCROLL
+ CONTROL "",IDC_AMBIENTLIGHTSPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,125,73,
+ 11,14
+ PUSHBUTTON "Standard &wiederherstellen",IDC_RESETTODEFAULTS,31,94,
+ 106,14
+ CONTROL "&Raster anzeigen",IDC_TREEMAPGRID,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,18,144,65,10
+ PUSHBUTTON "Raster-&Farbe",IDC_TREEMAPGRIDCOLOR,88,143,74,14,0,
+ WS_EX_RIGHT
+ CONTROL "",IDC_DEMO,"Static",SS_BLACKFRAME | WS_BORDER,147,30,
+ 118,78,WS_EX_TRANSPARENT
+ PUSHBUTTON "&Markierungsrahmen",IDC_TREEMAPHIGHLIGHTCOLOR,18,166,
+ 143,14,0,WS_EX_RIGHT
+END
+
+IDD_PAGE_GENERAL DIALOGEX 0, 0, 380, 202
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Allgemein"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "&Dateisystemgrenzen überschreiten",
+ IDC_FOLLOWMOUNTPOINTS,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,32,29,187,10
+ CONTROL "&Größen im GB/MB/KB/Bytes-Format anzeigen",
+ IDC_HUMANFORMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,32,
+ 49,207,10
+ CONTROL "&Pacman-Animation in der Verzeichnisliste",
+ IDC_PACMANANIMATION,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,32,69,206,10
+ LTEXT "&Sprache",IDC_STATIC,32,97,166,8
+ COMBOBOX IDC_COMBO,32,110,156,140,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ LTEXT "Änderungen der Sprache werden erst wirksam, wenn das Programm neu gestartet wird.",
+ IDC_STATIC,200,110,173,35
+ LTEXT "Language changes take not effect until the application is restarted.",
+ IDC_STATIC,200,143,173,35
+END
+
+IDD_REPORTBUG DIALOGEX 0, 0, 360, 233
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU |
+ WS_THICKFRAME
+CAPTION "WinDirStat - Fehlerbericht/Feedback"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "&Kritisch",IDC_CRITICAL,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP,14,52,43,10
+ CONTROL "&Schwerwiegend",IDC_GRAVE,"Button",BS_AUTORADIOBUTTON,
+ 73,52,63,10
+ CONTROL "&Normal",IDC_NORMAL,"Button",BS_AUTORADIOBUTTON,138,52,
+ 43,10
+ CONTROL "&Wunsch",IDC_WISH,"Button",BS_AUTORADIOBUTTON,191,52,43,
+ 10
+ CONTROL "&Allgemeines Feedback",IDC_FEEDBACK,"Button",
+ BS_AUTORADIOBUTTON,250,52,98,10
+ EDITTEXT IDC_INAWORD,60,77,293,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_TEXT,7,137,346,60,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
+ DEFPUSHBUTTON "OK",IDOK,154,212,50,14
+ PUSHBUTTON "Abbruch",IDCANCEL,303,212,50,14
+ LTEXT "Von:",IDC_STATIC,7,7,20,8
+ LTEXT "An:",IDC_STATIC_TO,185,7,12,8
+ LTEXT "<from>",IDC_FROM,51,7,122,8
+ LTEXT "<to>",IDC_TO,230,7,123,8
+ GROUPBOX "Schwere",IDC_STATIC_SEVERITY,7,39,346,31,0,
+ WS_EX_TRANSPARENT
+ LTEXT "In einem &Wort:",IDC_STATIC,7,81,50,8
+ LTEXT "&Geben Sie den Text (bitte in englisch oder deutsch) ein, den Sie absenden möchten.",
+ IDC_STATIC,7,100,346,12
+ LTEXT "Programm:",IDC_STATIC,7,22,38,8
+ LTEXT "<application>",IDC_APPLICATION,51,22,123,8
+ LTEXT "Plattform:",IDC_STATIC_PLATFORM,185,22,31,8
+ LTEXT "<platform>",IDC_PLATFORM,230,22,123,8
+ LTEXT "Für einen Fehlerbericht ist es am besten, wenn Sie das Symptom nennen, mit dem vollständigen Wortlaut der Fehlermeldung, und möglichst die Schritte, die zu diesem Fehler führen.",
+ IDC_HINT,7,115,346,19
+ LTEXT "Wenn Sie OK drücken, können Sie die Nachricht in Ihrem E-Mail-Programm nachprüfen.",
+ IDC_STATIC_OKHINT,7,200,346,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_ABOUTBOX, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 266
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 192
+ END
+
+ IDD_SELECTDRIVES, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 269
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 175
+ END
+
+ IDD_DELETE_WARNING, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 269
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 143
+ END
+
+ IDD_MODALAPISHUTTLE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 83
+ END
+
+ IDD_PAGE_CLEANUPS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 373
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 195
+ END
+
+ IDD_PAGE_TREELIST, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 373
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 192
+ END
+
+ IDD_PAGE_TREEMAP, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 373
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 195
+ END
+
+ IDD_PAGE_GENERAL, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 373
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 195
+ END
+
+ IDD_REPORTBUG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 353
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 226
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXT
+//
+
+IDR_LICENSE TEXT "res\\license.txt"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDR_MAINFRAME "WinDirStat\n\nWinDirStat\n\n\n\n"
+END
+
+STRINGTABLE
+BEGIN
+ AFX_IDS_APP_TITLE "WinDirStat"
+ AFX_IDS_IDLEMESSAGE "Bereit"
+END
+
+STRINGTABLE
+BEGIN
+ ID_INDICATOR_EXT "ER"
+ ID_INDICATOR_CAPS "UF"
+ ID_INDICATOR_NUM "NUM"
+ ID_INDICATOR_SCRL "RF"
+ ID_INDICATOR_OVR "ÜB"
+ ID_INDICATOR_REC "MA"
+ ID_INDICATOR_MEMORYUSAGE "Speichernutzung: 123.456.789"
+END
+
+STRINGTABLE
+BEGIN
+ ID_FILE_OPEN "Öffnet eine Menge von Laufwerken.\nÖffnen"
+END
+
+STRINGTABLE
+BEGIN
+ ID_APP_ABOUT "Zeigt Programm-, Versions-, und Copyright-Information.\nInfo"
+ ID_APP_EXIT "Beendet das Programm.\nBeenden"
+END
+
+STRINGTABLE
+BEGIN
+ ID_EDIT_COPY "Kopiert den Pfad des markierten Elements in die Zwischenablage.\nPfad kopieren"
+END
+
+STRINGTABLE
+BEGIN
+ ID_VIEW_TOOLBAR "Blendet die Symbolleiste ein oder aus.\nSymbolleiste"
+ ID_VIEW_STATUS_BAR "Blendet die Statusleiste ein oder aus.\nStatusleiste"
+END
+
+STRINGTABLE
+BEGIN
+ AFX_IDS_SCSIZE "Ändert die Fenstergröße."
+ AFX_IDS_SCMOVE "Ändert die Position des Fensters."
+ AFX_IDS_SCMINIMIZE "Minimiert das Fenster."
+ AFX_IDS_SCMAXIMIZE "Maximiert das Fenster."
+ AFX_IDS_SCCLOSE "Beendet das Programm."
+END
+
+STRINGTABLE
+BEGIN
+ AFX_IDS_SCRESTORE "Stellt die ursprüngliche Fenstergröße wieder her."
+ AFX_IDS_SCTASKLIST "Aktiviert die Taskliste."
+END
+
+STRINGTABLE
+BEGIN
+ ID_FILE_REFRESHALL "Liest den gesamten Baum neu ein."
+ ID_CLEANUP_OPENINEXPLORER
+ "Öffnet den Explorer am markieren Ort.\nExplorer"
+ ID_TREEMAP_ZOOMIN "Vergrößert die Baumkarte.\nHineinzoomen"
+END
+
+STRINGTABLE
+BEGIN
+ ID_FILE_REFRESHSELECTED "Liest den markierten Teilbaum neu ein."
+ ID_CLEANUP_OPENINCONSOLE
+ "Öffnet einen DOS-Prompt am markierten Ort.\nDOS-Prompt"
+ ID_CLEANUP_DELETETOTRASHBIN
+ "Verschiebt das markierte Element in den Papierkorb.\nLöschen (in den Papierkorb)"
+ ID_CLEANUP_DELETE "Löscht das markierte Element (irreversibel!).\nLöschen (irreversibel!)"
+ ID_CONFIGURE "Öffnet den Konfigurationsdialog.\nKonfigurieren"
+ ID_HELP_MANUAL "Öffnet die WinDirStat Online-Hilfe\nHilfe"
+END
+
+STRINGTABLE
+BEGIN
+ ID_TREEMAP_ZOOMOUT "Verkleinert die Baumkarte.\nHerauszoomen"
+ ID_TREEMAP_SELECTPARENT "Markiert das Elternelement.\nZum Elternelement"
+ ID_TREEMAP_HELPABOUTTREEMAPS
+ "Zeigt Hilfe zu Baumkarten an.\nHilfe zu Baumkarten"
+ ID_VIEW_SHOWTREEMAP "Blendet die Baumkarte ein oder aus.\nBaumkarte"
+ ID_HELP_REPORTBUG "Erstellt einen Fehlerbericht bzw. eine Feedback-E-Mail.\nFehlerbericht/Feedback"
+END
+
+STRINGTABLE
+BEGIN
+ ID_REFRESHALL "Liest den gesamten Verzeichnisbaum neu ein.\nAlles aktualisieren"
+ ID_REFRESHSELECTED "Liest den markierten Teilbaum neu ein.\nMarkierung aktualisieren"
+ ID_CLEANUP_EMPTYRECYCLEBIN "Leert den Papierkorb.\nPapierkorb leeren"
+ ID_VIEW_SHOWFREESPACE "Blendet das <Freier Platz>-Element ein oder aus.\n<Freier Platz> anzeigen"
+ ID_VIEW_SHOWUNKNOWN "Blendet das <Unbekannt>-Element ein oder aus.\n<Unbekannt> anzeigen"
+END
+
+STRINGTABLE
+BEGIN
+ ID_DUMMY_USERDEFINEDCLEANUP
+ "Ruft die benutzerdefinierte Aktion Nr. 0 auf\nBenutzerdefinierte Aktion"
+END
+
+STRINGTABLE
+BEGIN
+ ID_SENDMAILTOOWNER "Erstellt einen E-Mail-Report zum aktuell markierten Element.\nE-Mail senden"
+END
+
+STRINGTABLE
+BEGIN
+ ID_VIEW_SHOWFILETYPES "Blendet die Dateityp-Liste ein oder aus.\nDateityp-Liste anzeigen"
+END
+
+STRINGTABLE
+BEGIN
+ ID_TREEMAP_RESELECTCHILD
+ "Geht zurück zum Kind-Element.\nZurück zum Kind-Element"
+ ID_CLEANUP_OPEN "Öffnet das markierte Element.\r\nElement öffnen"
+ ID_CLEANUP_PROPERTIES "Zeigt die Eigenschaften des markierten Elements an.\r\nEigenschaften"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_RESOURCEVERSION "Resource Version 1"
+ IDS_ABOUT_ABOUTTEXTss "\r\nWinDirStat - Verzeichnisstatistik\r\n\r\nZeigt an, wo all der Plattenplatz geblieben ist,\r\nund hilft aufzuräumen.\r\n\r\nNeu programmiert für MS Windows von\r\nBernhard Seifert (mailto:%1!s!),\r\n\r\nauf Grundlage von Stefan Hundhammers KDE (Linux)-Programm KDirStat\r\n(http://kdirstat.sourceforge.net).\r\n\r\nWinDirStats Homepage ist http://%2!s!\r\n\r\nCopyright (c) 2003 Bernhard Seifert"
+ IDS_ABOUT_THANKSTOTEXT "\r\nStefan Hundhammer für sein vorzügliches Linux-Tool KDirStat.\r\nKDirStat (2.3.7) als Vorlage zu nehmen hat mir eine Menge Zeit gespart.\r\nhttp://kdirstat.sourceforge.net/\r\n\r\nDen Autoren von SequoiaView, die gezeigt haben, wie nützlich Baumkarten sein können.\r\nhttp://www.win.tue.nl/sequoiaview/\r\n\r\nJarke J. van Wijk, Huub van de Wetering, Mark Bruls und Kees Huizing\r\nfür ihre Dokumente über ""Cushion Treemaps"" und ""Squarified Treemaps"".\r\nhttp://www.win.tue.nl/~vanwijk/\r\n\r\nBen Shneiderman für seine geniale Erfindung von Treemaps -\r\neiner wirklich intuitiven Art und Weise, Bäume zu visualisieren.\r\nhttp://www.cs.umd.edu/hcil/treemap-history/\r\n\r\nMeinen Kollegen für ihr Feedback zu den frühen Versionen von WinDirStat.\r\nhttp://www.daccord.net/\r\n"
+ IDS_ABOUT_ABOUT "Über WinDirStat"
+ IDS_ABOUT_THANKSTO "Dank"
+ IDS_ABOUT_LICENSEAGREEMENT "Lizenzvereinbarung"
+ IDS_MYCOMPUTER "Arbeitsplatz"
+ IDS_UDC_CONFIRMATIONss "Sie rufen die benutzerdefinierte Aktion\r\n'%1!s!'\r\n\r\nfür '%2!s!' auf.\r\n\r\nFortfahren?"
+ IDS_RUDC_CONFIRMATIONss "Sie rufen die rekursive benutzerdefinierte Aktion\r\n'%1!s!'\r\n\r\nfür '%2!s!' auf.\r\n\r\nFortfahren?"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_THEDIRECTORYsDOESNOTEXIST
+ "Das Verzeichnis '%1!s!' existiert nicht mehr."
+ IDS_THEFILEsDOESNOTEXIST "Die Datei '%1!s!' existiert nicht mehr."
+ IDS_COULDNOTCREATEPROCESSssss
+ "Konnte Prozess nicht starten.\r\n\r\nProgramm: '%1!s!',\r\nKommandozeile: '%2!s!',\r\nArbeitsverzeichnis: '%3!s!'\r\nFehlermeldung:\r\n%4!s!\r\n(Es wird keine Aktualisierung durchgeführt.)"
+ IDS_TREECOL_NAME "Name"
+ IDS_TREECOL_SUBTREEPERCENTAGE "Teilbaum-Anteil"
+ IDS_TREECOL_PERCENTAGE "Anteil"
+ IDS_TREECOL_SIZE "Größe"
+ IDS_TREECOL_ITEMS "Einträge"
+ IDS_TREECOL_FILES "Dateien"
+ IDS_TREECOL_SUBDIRS "Verzeichnisse"
+ IDS_TREECOL_LASTCHANGE "Letzte Änderung"
+ IDS_PLEASECHECKYOURDISKUSAGE
+ "Bitte überprüfen Sie den Plattenplatzverbrauch und räumen Sie, wenn möglich, auf. Danke.\r\n\r\n"
+ IDS_DISKUSAGEREPORTGENERATEDBYWINDIRSTAT
+ "\r\n\r\nPlattenplatzbelegungsreport erzeugt von WinDirStat.\r\n"
+ IDS__UNKNOWN_ "<unbekannt>"
+ IDS_FREESPACE_ITEM "<Freier Platz>"
+ IDS_UNKNOWN_ITEM "<Unbekannt>"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_FILES_ITEM "<Dateien>"
+ IDS_ONEREADJOB "[1 Leseauftrag]"
+ IDS_sREADJOBS "[%1!s! Leseaufträge]"
+ IDS_CANNOTOPENCLIPBOARD "Kann die Zwischenablage nicht öffnen."
+ IDS_CANNOTEMTPYCLIPBOARD "Kann die Zwischenablage nicht leeren."
+ IDS_CANNOTSETCLIPBAORDDATA "Kann die Zwischenablage nicht befüllen."
+ IDS_WINDIRSTAT_SETTINGS "WinDirStat - Einstellungen"
+ IDS_SCANNING_ "Einlesen "
+ IDS_EMPTYRECYCLEBIN "&Papierkorb leeren"
+ IDS__ONEITEMss " (1 Element; %1!s!%2!s!)"
+ IDS__sITEMSss " (%1!s! Elemente; %2!s!%3!s!)"
+ IDS_UDCsCTRLd "%1!s!\tStrg+%2!d!"
+ IDS_USERDEFINEDCLEANUP0 "Benutzerdefinierte Aktion Nr.0"
+ IDS_REPORT_DISKUSAGE "Plattenplatzverbrauch"
+ IDS_USERDEFINEDCLEANUPd "Benutzerdefinierte Aktion Nr.%1!d!"
+ IDS_POLICY_NOREFRESH "Keine Aktualisierung"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_POLICY_REFRESHTHISENTRY "Diesen Eintrag aktualisieren"
+ IDS_POLICY_REFRESHPARENT "Das Elternelement aktualisieren"
+ IDS_BUGREPORTHINT "Für einen Fehlerbericht ist es am besten, wenn Sie das Symptom nennen, mit dem vollständigen Wortlaut der Fehlermeldung, und möglichst die Schritte, die zu diesem Fehler führen."
+ IDS_FEEDBACKHINT "Feedback ist immer willkommen."
+ IDS_FROMsPLATFORMs "Von: %1!s!. Plattform: %2!s!.\r\n\r\n"
+ IDS_SEV_CRITICAL "Kritischer Fehler"
+ IDS_SEV_GRAVE "Schwerwiegender Fehler"
+ IDS_SEV_NORMAL "Fehler"
+ IDS_SEV_WISH "Wunsch"
+ IDS_SEV_FEEDBACK "Feedback"
+ IDS_DRIVECOL_NAME "Name"
+ IDS_DRIVECOL_TOTAL "Gesamt"
+ IDS_DRIVECOL_FREE "Frei"
+ IDS_DRIVECOL_GRAPH "Belegt/Gesamt"
+ IDS_DRIVECOL_PERCENTUSED "Belegt/Gesamt"
+ IDS_SELECTFOLDER "WinDirStat - Verzeichnis auswählen"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_EXTCOL_EXTENSION "Dateityp"
+ IDS_EXTCOL_COLOR "Farbe"
+ IDS_EXTCOL_BYTES "Bytes"
+ IDS_EXTCOL_FILES "Dateien"
+ IDS_EXTCOL_DESCRIPTION "Beschreibung"
+ IDS_RAMUSAGEs "Speichernutzung: %1!s!"
+ IDS_HELPFILEsCOULDNOTBEFOUND
+ "Die Hilfedatei %1!s! ist nicht da.\r\nSie wird im selben Verzeichnis erwartet, in dem windirstat.exe liegt.\r\nSie sollten sie zusammen mit windirstat.exe erhalten haben.\r\nSie können eine Hilfedatei downloaden von der WinDirStat Homepage (siehe Aboutbox)."
+ IDS_SUSPENDED_ "(angehalten) "
+ IDS_SUSPEND "Anhalten"
+END
+
+#endif // German (Germany) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL)
+LANGUAGE 7, 1
+#pragma code_page(1252)
+#include "afxres.rc" // Standard components
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/windirstat.sln b/windirstat.sln
new file mode 100644
index 0000000..15e0131
--- /dev/null
+++ b/windirstat.sln
@@ -0,0 +1,75 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windirstat", "windirstat\windirstat.vcproj", "{BD11B94C-6594-4477-9FDF-2E24447D1F14}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wdsr0407", "wdsr0407\wdsr0407.vcproj", "{C7A5D1EC-35D3-4754-A815-2C527CACD584}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wdsh0407", "wdsh0407\wdsh0407.vcproj", "{76695BEC-D0B6-44BC-8F2D-E9C45D239137}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "setup", "setup\setup.vcproj", "{C9448E7F-B7CF-4267-81EC-0D9F98589F2C}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wdshelp", "wdshelp\wdshelp.vcproj", "{7EE5206B-1657-482A-B6A1-343DE5D6DE11}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ Unicode Debug = Unicode Debug
+ Unicode Release = Unicode Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {BD11B94C-6594-4477-9FDF-2E24447D1F14}.Debug.ActiveCfg = Debug|Win32
+ {BD11B94C-6594-4477-9FDF-2E24447D1F14}.Debug.Build.0 = Debug|Win32
+ {BD11B94C-6594-4477-9FDF-2E24447D1F14}.Release.ActiveCfg = Release|Win32
+ {BD11B94C-6594-4477-9FDF-2E24447D1F14}.Release.Build.0 = Release|Win32
+ {BD11B94C-6594-4477-9FDF-2E24447D1F14}.Unicode Debug.ActiveCfg = Unicode Debug|Win32
+ {BD11B94C-6594-4477-9FDF-2E24447D1F14}.Unicode Debug.Build.0 = Unicode Debug|Win32
+ {BD11B94C-6594-4477-9FDF-2E24447D1F14}.Unicode Release.ActiveCfg = Unicode Release|Win32
+ {BD11B94C-6594-4477-9FDF-2E24447D1F14}.Unicode Release.Build.0 = Unicode Release|Win32
+ {C7A5D1EC-35D3-4754-A815-2C527CACD584}.Debug.ActiveCfg = Debug|Win32
+ {C7A5D1EC-35D3-4754-A815-2C527CACD584}.Debug.Build.0 = Debug|Win32
+ {C7A5D1EC-35D3-4754-A815-2C527CACD584}.Release.ActiveCfg = Release|Win32
+ {C7A5D1EC-35D3-4754-A815-2C527CACD584}.Release.Build.0 = Release|Win32
+ {C7A5D1EC-35D3-4754-A815-2C527CACD584}.Unicode Debug.ActiveCfg = Unicode Debug|Win32
+ {C7A5D1EC-35D3-4754-A815-2C527CACD584}.Unicode Debug.Build.0 = Unicode Debug|Win32
+ {C7A5D1EC-35D3-4754-A815-2C527CACD584}.Unicode Release.ActiveCfg = Unicode Release|Win32
+ {C7A5D1EC-35D3-4754-A815-2C527CACD584}.Unicode Release.Build.0 = Unicode Release|Win32
+ {76695BEC-D0B6-44BC-8F2D-E9C45D239137}.Debug.ActiveCfg = Debug|Win32
+ {76695BEC-D0B6-44BC-8F2D-E9C45D239137}.Debug.Build.0 = Debug|Win32
+ {76695BEC-D0B6-44BC-8F2D-E9C45D239137}.Release.ActiveCfg = Release|Win32
+ {76695BEC-D0B6-44BC-8F2D-E9C45D239137}.Release.Build.0 = Release|Win32
+ {76695BEC-D0B6-44BC-8F2D-E9C45D239137}.Unicode Debug.ActiveCfg = Unicode Debug|Win32
+ {76695BEC-D0B6-44BC-8F2D-E9C45D239137}.Unicode Debug.Build.0 = Unicode Debug|Win32
+ {76695BEC-D0B6-44BC-8F2D-E9C45D239137}.Unicode Release.ActiveCfg = Unicode Release|Win32
+ {76695BEC-D0B6-44BC-8F2D-E9C45D239137}.Unicode Release.Build.0 = Unicode Release|Win32
+ {C9448E7F-B7CF-4267-81EC-0D9F98589F2C}.Debug.ActiveCfg = Debug|Win32
+ {C9448E7F-B7CF-4267-81EC-0D9F98589F2C}.Debug.Build.0 = Debug|Win32
+ {C9448E7F-B7CF-4267-81EC-0D9F98589F2C}.Release.ActiveCfg = Release|Win32
+ {C9448E7F-B7CF-4267-81EC-0D9F98589F2C}.Release.Build.0 = Release|Win32
+ {C9448E7F-B7CF-4267-81EC-0D9F98589F2C}.Unicode Debug.ActiveCfg = Unicode Debug|Win32
+ {C9448E7F-B7CF-4267-81EC-0D9F98589F2C}.Unicode Debug.Build.0 = Unicode Debug|Win32
+ {C9448E7F-B7CF-4267-81EC-0D9F98589F2C}.Unicode Release.ActiveCfg = Unicode Release|Win32
+ {C9448E7F-B7CF-4267-81EC-0D9F98589F2C}.Unicode Release.Build.0 = Unicode Release|Win32
+ {7EE5206B-1657-482A-B6A1-343DE5D6DE11}.Debug.ActiveCfg = Debug|Win32
+ {7EE5206B-1657-482A-B6A1-343DE5D6DE11}.Debug.Build.0 = Debug|Win32
+ {7EE5206B-1657-482A-B6A1-343DE5D6DE11}.Release.ActiveCfg = Release|Win32
+ {7EE5206B-1657-482A-B6A1-343DE5D6DE11}.Release.Build.0 = Release|Win32
+ {7EE5206B-1657-482A-B6A1-343DE5D6DE11}.Unicode Debug.ActiveCfg = Debug|Win32
+ {7EE5206B-1657-482A-B6A1-343DE5D6DE11}.Unicode Debug.Build.0 = Debug|Win32
+ {7EE5206B-1657-482A-B6A1-343DE5D6DE11}.Unicode Release.ActiveCfg = Release|Win32
+ {7EE5206B-1657-482A-B6A1-343DE5D6DE11}.Unicode Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/windirstat/DeleteWarningDlg.cpp b/windirstat/DeleteWarningDlg.cpp
new file mode 100644
index 0000000..3acb000
--- /dev/null
+++ b/windirstat/DeleteWarningDlg.cpp
@@ -0,0 +1,64 @@
+// DeleteWarningDlg.cpp: implementation of CDeleteWarningDlg
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include ".\deletewarningdlg.h"
+
+
+IMPLEMENT_DYNAMIC(CDeleteWarningDlg, CDialog)
+
+CDeleteWarningDlg::CDeleteWarningDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CDeleteWarningDlg::IDD, pParent)
+ , m_fileName(_T(""))
+ , m_dontShowAgain(false)
+{
+}
+
+CDeleteWarningDlg::~CDeleteWarningDlg()
+{
+}
+
+void CDeleteWarningDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ DDX_Check(pDX, IDC_DONTSHOWAGAIN, m_dontShowAgain);
+ DDX_Text(pDX, IDC_FILENAME, m_fileName);
+}
+
+
+BEGIN_MESSAGE_MAP(CDeleteWarningDlg, CDialog)
+ ON_BN_CLICKED(IDNO, OnBnClickedNo)
+ ON_BN_CLICKED(IDYES, OnBnClickedYes)
+END_MESSAGE_MAP()
+
+
+void CDeleteWarningDlg::OnBnClickedNo()
+{
+ UpdateData();
+ EndDialog(IDNO);
+}
+
+void CDeleteWarningDlg::OnBnClickedYes()
+{
+ UpdateData();
+ EndDialog(IDYES);
+}
diff --git a/windirstat/DeleteWarningDlg.h b/windirstat/DeleteWarningDlg.h
new file mode 100644
index 0000000..b1ab041
--- /dev/null
+++ b/windirstat/DeleteWarningDlg.h
@@ -0,0 +1,46 @@
+// deletewarningdlg.h - Declaration of CDeleteWarningDlg
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+//
+// CDeleteWarningDlg. As WinDirStat can delete all files and folders,
+// e.g. C:\Windows, we show an additional warning, when the user
+// selects "Delete" (before the shell shows its warning).
+//
+class CDeleteWarningDlg : public CDialog
+{
+ DECLARE_DYNAMIC(CDeleteWarningDlg)
+ enum { IDD = IDD_DELETE_WARNING };
+
+public:
+ CDeleteWarningDlg(CWnd* pParent = NULL);
+ virtual ~CDeleteWarningDlg();
+
+ CString m_fileName; // [in] file name for feedback
+ BOOL m_dontShowAgain; // [out]
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX);
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnBnClickedNo();
+ afx_msg void OnBnClickedYes();
+};
diff --git a/windirstat/ModalApiShuttle.cpp b/windirstat/ModalApiShuttle.cpp
new file mode 100644
index 0000000..1de7af7
--- /dev/null
+++ b/windirstat/ModalApiShuttle.cpp
@@ -0,0 +1,61 @@
+// ModalApiShuttle.cpp - Implementation of CModalApiShuttle
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "ModalApiShuttle.h"
+
+
+IMPLEMENT_DYNAMIC(CModalApiShuttle, CDialog)
+
+CModalApiShuttle::CModalApiShuttle(CWnd* pParent /*=NULL*/)
+ : CDialog(CModalApiShuttle::IDD, pParent)
+{
+}
+
+CModalApiShuttle::~CModalApiShuttle()
+{
+}
+
+BEGIN_MESSAGE_MAP(CModalApiShuttle, CDialog)
+END_MESSAGE_MAP()
+
+
+BOOL CModalApiShuttle::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ CRect rc;
+ AfxGetMainWnd()->GetWindowRect(rc);
+ rc.right= rc.left;
+ rc.bottom= rc.top;
+
+ MoveWindow(rc, false);
+
+ EnableWindow(true);
+ ShowWindow(SW_SHOW);
+
+ DoOperation();
+
+ EndDialog(IDOK);
+ return TRUE;
+}
+
diff --git a/windirstat/ModalApiShuttle.h b/windirstat/ModalApiShuttle.h
new file mode 100644
index 0000000..3e3e51a
--- /dev/null
+++ b/windirstat/ModalApiShuttle.h
@@ -0,0 +1,60 @@
+// modalapishuttle.h - Declaration of CModalApiShuttle
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+
+//
+// CModalApiShuttle. (Base class for CModalShellApi and CModalSendMail.)
+//
+// Both the SHFileOperation() and MAPISendMail() functions show modeless dialogs,
+// but we want them to be modal.
+//
+// My first approximation was:
+//
+// AfxGetMainWnd()->EnableWindow(false);
+// Do the operation (SHFileOperation respectively MAPISendMail)
+// AfxGetMainWnd()->EnableWindow(true);
+//
+// But when the operation window is destroyed, the system brings
+// some other window to the foreground and WinDirStat ends up in the background.
+// That's because it is still disabled at that moment.
+//
+// So my solution is this:
+// First create an invisible (zero size) (but enabled) modal dialog,
+// then do the operation in its OnInitDialog function
+// and end the dialog.
+//
+class CModalApiShuttle: public CDialog
+{
+ DECLARE_DYNAMIC(CModalApiShuttle)
+
+public:
+ CModalApiShuttle(CWnd* pParent = NULL);
+ virtual ~CModalApiShuttle();
+
+protected:
+ enum { IDD = IDD_MODALAPISHUTTLE };
+ virtual BOOL OnInitDialog();
+ DECLARE_MESSAGE_MAP()
+
+ virtual void DoOperation() =0;
+};
diff --git a/windirstat/ModalSendMail.cpp b/windirstat/ModalSendMail.cpp
new file mode 100644
index 0000000..9b67d4c
--- /dev/null
+++ b/windirstat/ModalSendMail.cpp
@@ -0,0 +1,124 @@
+// modalsendmail.cpp - Implementation of CModalSendMail
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "modalsendmail.h"
+
+
+namespace
+{
+ CString GetMapiError(UINT r)
+ {
+ CString s;
+ switch (r)
+ {
+ case MAPI_E_AMBIGUOUS_RECIPIENT: s= _T("A recipient matched more than one of the recipient descriptor structures and MAPI_DIALOG was not set. No message was sent."); break;
+ case MAPI_E_ATTACHMENT_NOT_FOUND: s= _T("The specified attachment was not found. No message was sent."); break;
+ case MAPI_E_ATTACHMENT_OPEN_FAILURE: s= _T("The specified attachment could not be opened. No message was sent."); break;
+ case MAPI_E_BAD_RECIPTYPE: s= _T("The type of a recipient was not MAPI_TO, MAPI_CC, or MAPI_BCC. No message was sent."); break;
+ case MAPI_E_FAILURE: s= _T("One or more unspecified errors occurred. No message was sent."); break;
+ case MAPI_E_INSUFFICIENT_MEMORY: s= _T("There was insufficient memory to proceed. No message was sent."); break;
+ case MAPI_E_INVALID_RECIPS: s= _T("One or more recipients were invalid or did not resolve to any address."); break;
+ case MAPI_E_LOGIN_FAILURE: s= _T("There was no default logon, and the user failed to log on successfully when the logon dialog box was displayed. No message was sent."); break;
+ case MAPI_E_TEXT_TOO_LARGE: s= _T("The text in the message was too large. No message was sent."); break;
+ case MAPI_E_TOO_MANY_FILES: s= _T("There were too many file attachments. No message was sent."); break;
+ case MAPI_E_TOO_MANY_RECIPIENTS: s= _T("There were too many recipients. No message was sent."); break;
+ case MAPI_E_UNKNOWN_RECIPIENT: s= _T("A recipient did not appear in the address list. No message was sent."); break;
+ case MAPI_E_USER_ABORT: s= _T("The user canceled one of the dialog boxes. No message was sent."); break;
+ case SUCCESS_SUCCESS: s= _T("The call succeeded and the message was sent."); break;
+ default:
+ s.Format(_T("Unknown MAPI error code %u"), r);
+ break;
+ }
+ return s;
+ }
+}
+
+CModalSendMail::CModalSendMail()
+{
+}
+
+// static
+bool CModalSendMail::IsSendMailAvailable()
+{
+ // This code is derived from the implementation of CDocument::OnUpdateFileSendMail()
+ if (::GetProfileInt(_T("MAIL"), _T("MAPI"), 0) == 0)
+ return false;
+
+ if (!CMapi32Api::IsDllPresent())
+ return false;
+
+ return true;
+}
+
+bool CModalSendMail::SendMail(LPCTSTR recipient, LPCTSTR subject, LPCTSTR body)
+{
+ m_recipient= recipient;
+ m_subject= subject;
+ m_body= body;
+
+ DoModal();
+
+ return m_result == SUCCESS_SUCCESS;
+}
+
+void CModalSendMail::DoOperation()
+{
+ USES_CONVERSION;
+
+ // This code is derived from the implementation of CDocument::OnFileSendMail()
+ if (!IsSendMailAvailable())
+ return;
+
+ if (!m_api.IsSupported())
+ return;
+
+ CWaitCursor wc;
+
+ // Call the MAPI-api
+ MapiRecipDesc mrd;
+
+ MapiMessage message;
+ ZeroMemory(&message, sizeof(message));
+ message.lpszSubject= T2A((LPTSTR)(LPCTSTR)m_subject);
+ message.lpszNoteText= T2A((LPTSTR)(LPCTSTR)m_body);
+ if (!m_recipient.IsEmpty())
+ {
+ message.nRecipCount= 1;
+ message.lpRecips= &mrd;
+ ZeroMemory(&mrd, sizeof(mrd));
+ mrd.ulRecipClass= MAPI_TO;
+ mrd.lpszName= T2A((LPTSTR)(LPCTSTR)m_recipient);
+ }
+
+ UINT r= m_api.MAPISendMail(0, (ULONG)AfxGetMainWnd()->m_hWnd, &message, MAPI_LOGON_UI|MAPI_DIALOG, 0);
+ // This call ASSERTs in winocc.cpp, line 207, if, for example, an invalid recipient is entered,
+ // and (in my case) Outlook Express displays a dialog.
+ // The assertion can safely be ignored.
+ // The original code (CDocument::OnFileSendMail()) asserts in the same way.
+
+ if (r != SUCCESS_SUCCESS && r != MAPI_USER_ABORT && r != MAPI_E_LOGIN_FAILURE)
+ AfxMessageBox(GetMapiError(r));
+
+ m_result= r;
+}
+
diff --git a/windirstat/ModalSendMail.h b/windirstat/ModalSendMail.h
new file mode 100644
index 0000000..c19b03f
--- /dev/null
+++ b/windirstat/ModalSendMail.h
@@ -0,0 +1,47 @@
+// modalsendmail.h - Declaration of CModalSendMail
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "modalapishuttle.h"
+
+
+//
+// CModalSendMail. For "Send mail to owner". Modal version of MAPISendMail.
+// See comment on CModalApiShuttle.
+//
+class CModalSendMail: public CModalApiShuttle
+{
+public:
+ CModalSendMail();
+
+ static bool IsSendMailAvailable();
+ bool SendMail(LPCTSTR recipient, LPCTSTR subject, LPCTSTR body);
+
+protected:
+ virtual void DoOperation();
+
+ CMapi32Api m_api; // Dynamically linked mapi32.dll
+ CString m_recipient; // Empty, if no recipient
+ CString m_subject; // Subject-line of e-mail
+ CString m_body; // Text of e-mail
+ UINT m_result;
+};
diff --git a/windirstat/ModalShellApi.cpp b/windirstat/ModalShellApi.cpp
new file mode 100644
index 0000000..8a07092
--- /dev/null
+++ b/windirstat/ModalShellApi.cpp
@@ -0,0 +1,100 @@
+// ModalShellApi.cpp - Implementation of CModalShellApi
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "ModalShellApi.h"
+
+
+namespace
+{
+ enum
+ {
+ EMPTY_RECYCLE_BIN,
+ DELETE_FILE
+ };
+}
+
+
+CModalShellApi::CModalShellApi()
+{
+}
+
+bool CModalShellApi::IsRecycleBinApiSupported()
+{
+ return m_rbapi.IsSupported();
+}
+
+void CModalShellApi::EmptyRecycleBin()
+{
+ m_operation= EMPTY_RECYCLE_BIN;
+
+ DoModal();
+}
+
+void CModalShellApi::DeleteFile(LPCTSTR fileName, bool toRecycleBin)
+{
+ m_operation= DELETE_FILE;
+ m_fileName= fileName;
+ m_toRecycleBin= toRecycleBin;
+
+ DoModal();
+}
+
+void CModalShellApi::DoOperation()
+{
+ switch (m_operation)
+ {
+ case EMPTY_RECYCLE_BIN:
+ DoEmptyRecycleBin();
+ break;
+
+ case DELETE_FILE:
+ DoDeleteFile();
+ break;
+ }
+}
+
+void CModalShellApi::DoEmptyRecycleBin()
+{
+ HRESULT hr= m_rbapi.SHEmptyRecycleBin(*AfxGetMainWnd(), NULL, 0);
+ if (FAILED(hr))
+ AfxMessageBox(MdGetWinerrorText(hr));
+}
+
+void CModalShellApi::DoDeleteFile()
+{
+ int len= m_fileName.GetLength();
+ LPTSTR psz= m_fileName.GetBuffer(len + 2);
+ psz[len + 1]= 0;
+
+ SHFILEOPSTRUCT sfos;
+ ZeroMemory(&sfos, sizeof(sfos));
+ sfos.wFunc= FO_DELETE;
+ sfos.pFrom= psz;
+ sfos.fFlags= m_toRecycleBin ? FOF_ALLOWUNDO : 0;
+
+ sfos.hwnd= *AfxGetMainWnd();
+
+ (void)SHFileOperation(&sfos);
+
+ m_fileName.ReleaseBuffer();
+}
diff --git a/windirstat/ModalShellApi.h b/windirstat/ModalShellApi.h
new file mode 100644
index 0000000..9219e00
--- /dev/null
+++ b/windirstat/ModalShellApi.h
@@ -0,0 +1,52 @@
+// modalshellapi.h - Declaration of CModalShellApi
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "modalapishuttle.h"
+
+
+//
+// CModalShellApi. Modal version of the shell functions
+// EmptyRecycleBin and DeleteFile.
+//
+// See comment on CModalApiShuttle.
+//
+class CModalShellApi : public CModalApiShuttle
+{
+public:
+ CModalShellApi();
+
+ bool IsRecycleBinApiSupported();
+ void EmptyRecycleBin();
+ void DeleteFile(LPCTSTR fileName, bool toRecycleBin);
+
+protected:
+ virtual void DoOperation();
+
+ void DoEmptyRecycleBin();
+ void DoDeleteFile();
+
+ CRecycleBinApi m_rbapi; // Dynamically linked shell32.dll functions
+ int m_operation; // Enum specifying the desired operation
+ CString m_fileName; // File name to be deleted
+ bool m_toRecycleBin; // True if file shall only be move to the recycle bin
+};
diff --git a/windirstat/PageCleanups.cpp b/windirstat/PageCleanups.cpp
new file mode 100644
index 0000000..ebfd25f
--- /dev/null
+++ b/windirstat/PageCleanups.cpp
@@ -0,0 +1,359 @@
+// PageCleanups.cpp - Implementation of CPageCleanups
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include ".\pagecleanups.h"
+
+
+IMPLEMENT_DYNAMIC(CPageCleanups, CPropertyPage)
+
+CPageCleanups::CPageCleanups()
+ : CPropertyPage(CPageCleanups::IDD)
+ , m_enabled(FALSE)
+ , m_title(_T(""))
+ , m_worksForDrives(FALSE)
+ , m_worksForDirectories(FALSE)
+ , m_worksForFilesFolder(FALSE)
+ , m_worksForFiles(FALSE)
+ , m_recurseIntoSubdirectories(FALSE)
+ , m_askForConfirmation(FALSE)
+ , m_showConsoleWindow(FALSE)
+ , m_waitForCompletion(FALSE)
+ , m_refreshPolicy(0)
+ , m_commandLine(_T(""))
+ , m_current(-1)
+{
+}
+
+CPageCleanups::~CPageCleanups()
+{
+}
+
+void CPageCleanups::DoDataExchange(CDataExchange* pDX)
+{
+ CPropertyPage::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST, m_list);
+ DDX_Check(pDX, IDC_ENABLED, m_enabled);
+ DDX_Text(pDX, IDC_TITLE, m_title);
+ DDX_Check(pDX, IDC_WORKSFORDRIVES, m_worksForDrives);
+ DDX_Check(pDX, IDC_WORKSFORDIRECTORIES, m_worksForDirectories);
+ DDX_Check(pDX, IDC_WORKSFORFILESFOLDER, m_worksForFilesFolder);
+ DDX_Check(pDX, IDC_WORKSFORFILES, m_worksForFiles);
+ DDX_Text(pDX, IDC_COMMANDLINE, m_commandLine);
+ DDX_Check(pDX, IDC_RECURSEINTOSUBDIRECTORIES, m_recurseIntoSubdirectories);
+ DDX_Check(pDX, IDC_ASKFORCONFIRMATION, m_askForConfirmation);
+ DDX_Check(pDX, IDC_SHOWCONSOLEWINDOW, m_showConsoleWindow);
+ DDX_Check(pDX, IDC_WAITFORCOMPLETION, m_waitForCompletion);
+ DDX_Control(pDX, IDC_REFRESHPOLICY, m_ctlRefreshPolicy);
+ DDX_CBIndex(pDX, IDC_REFRESHPOLICY, m_refreshPolicy);
+
+ DDX_Control(pDX, IDC_TITLE, m_ctlTitle);
+ DDX_Control(pDX, IDC_WORKSFORDRIVES, m_ctlWorksForDrives);
+ DDX_Control(pDX, IDC_WORKSFORDIRECTORIES, m_ctlWorksForDirectories);
+ DDX_Control(pDX, IDC_WORKSFORFILESFOLDER, m_ctlWorksForFilesFolder);
+ DDX_Control(pDX, IDC_WORKSFORFILES, m_ctlWorksForFiles);
+ DDX_Control(pDX, IDC_COMMANDLINE, m_ctlCommandLine);
+ DDX_Control(pDX, IDC_RECURSEINTOSUBDIRECTORIES, m_ctlRecurseIntoSubdirectories);
+ DDX_Control(pDX, IDC_ASKFORCONFIRMATION, m_ctlAskForConfirmation);
+ DDX_Control(pDX, IDC_SHOWCONSOLEWINDOW, m_ctlShowConsoleWindow);
+ DDX_Control(pDX, IDC_WAITFORCOMPLETION, m_ctlWaitForCompletion);
+ DDX_Control(pDX, IDC_HINTSP, m_ctlHintSp);
+ DDX_Control(pDX, IDC_HINTSN, m_ctlHintSn);
+ DDX_Control(pDX, IDC_UP, m_ctlUp);
+ DDX_Control(pDX, IDC_DOWN, m_ctlDown);
+}
+
+
+BEGIN_MESSAGE_MAP(CPageCleanups, CPropertyPage)
+ ON_LBN_SELCHANGE(IDC_LIST, OnLbnSelchangeList)
+ ON_BN_CLICKED(IDC_ENABLED, OnBnClickedEnabled)
+ ON_EN_CHANGE(IDC_TITLE, OnEnChangeTitle)
+ ON_BN_CLICKED(IDC_WORKSFORDRIVES, OnBnClickedWorksfordrives)
+ ON_BN_CLICKED(IDC_WORKSFORDIRECTORIES, OnBnClickedWorksfordirectories)
+ ON_BN_CLICKED(IDC_WORKSFORFILESFOLDER, OnBnClickedWorksforfilesfolder)
+ ON_BN_CLICKED(IDC_WORKSFORFILES, OnBnClickedWorksforfiles)
+ ON_EN_CHANGE(IDC_COMMANDLINE, OnEnChangeCommandline)
+ ON_BN_CLICKED(IDC_RECURSEINTOSUBDIRECTORIES, OnBnClickedRecurseintosubdirectories)
+ ON_BN_CLICKED(IDC_ASKFORCONFIRMATION, OnBnClickedAskforconfirmation)
+ ON_BN_CLICKED(IDC_SHOWCONSOLEWINDOW, OnBnClickedShowconsolewindow)
+ ON_BN_CLICKED(IDC_WAITFORCOMPLETION, OnBnClickedWaitforcompletion)
+ ON_CBN_SELENDOK(IDC_REFRESHPOLICY, OnCbnSelendokRefreshpolicy)
+ ON_BN_CLICKED(IDC_UP, OnBnClickedUp)
+ ON_BN_CLICKED(IDC_DOWN, OnBnClickedDown)
+ ON_BN_CLICKED(IDC_HELPBUTTON, OnBnClickedHelpbutton)
+END_MESSAGE_MAP()
+
+
+
+BOOL CPageCleanups::OnInitDialog()
+{
+ CPropertyPage::OnInitDialog();
+
+ // Combobox data correspond to enum REFRESHPOLICY:
+ m_ctlRefreshPolicy.AddString(LoadString(IDS_POLICY_NOREFRESH));
+ m_ctlRefreshPolicy.AddString(LoadString(IDS_POLICY_REFRESHTHISENTRY));
+ m_ctlRefreshPolicy.AddString(LoadString(IDS_POLICY_REFRESHPARENT));
+ // We don't do this: m_ctlRefreshPolicy.AddString("Assume entry has been deleted");
+ // That conflicts with "works for <Files> Pseudoentries".
+
+ GetOptions()->GetUserDefinedCleanups(m_udc);
+
+ for (int i=0; i < USERDEFINEDCLEANUPCOUNT; i++)
+ m_list.AddString(m_udc[i].title);
+
+ m_list.SetCurSel(0);
+ OnLbnSelchangeList();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+}
+
+void CPageCleanups::OnOK()
+{
+ CheckEmptyTitle();
+
+ GetOptions()->SetUserDefinedCleanups(m_udc);
+
+ CPropertyPage::OnOK();
+}
+
+void CPageCleanups::OnLbnSelchangeList()
+{
+ CheckEmptyTitle();
+
+ m_current= m_list.GetCurSel();
+ CurrentUdcToDialog();
+}
+
+void CPageCleanups::CheckEmptyTitle()
+{
+ if (m_current == -1)
+ return;
+
+ UpdateData();
+ if (m_title.IsEmpty())
+ {
+ m_title.FormatMessage(IDS_USERDEFINEDCLEANUPd, m_current);
+ UpdateData(false);
+
+ m_list.DeleteString(m_current);
+ m_list.InsertString(m_current, m_title);
+
+ DialogToCurrentUdc();
+ }
+}
+
+void CPageCleanups::CurrentUdcToDialog()
+{
+ m_enabled= m_udc[m_current].enabled;
+ m_title= m_udc[m_current].title;
+ m_worksForDrives= m_udc[m_current].worksForDrives;
+ m_worksForDirectories= m_udc[m_current].worksForDirectories;
+ m_worksForFilesFolder= m_udc[m_current].worksForFilesFolder;
+ m_worksForFiles= m_udc[m_current].worksForFiles;
+ m_commandLine= m_udc[m_current].commandLine;
+ m_recurseIntoSubdirectories= m_udc[m_current].recurseIntoSubdirectories;
+ m_askForConfirmation= m_udc[m_current].askForConfirmation;
+ m_showConsoleWindow= m_udc[m_current].showConsoleWindow;
+ m_waitForCompletion= m_udc[m_current].waitForCompletion;
+ m_refreshPolicy= m_udc[m_current].refreshPolicy;
+
+ UpdateControlStatus();
+ UpdateData(false);
+
+}
+
+void CPageCleanups::DialogToCurrentUdc()
+{
+ UpdateData();
+
+ m_udc[m_current].enabled= m_enabled;
+ m_udc[m_current].title= m_title;
+ m_udc[m_current].worksForDrives= m_worksForDrives;
+ m_udc[m_current].worksForDirectories= m_worksForDirectories;
+ m_udc[m_current].worksForFilesFolder= m_worksForFilesFolder;
+ m_udc[m_current].worksForFiles= m_worksForFiles;
+ m_udc[m_current].commandLine= m_commandLine;
+ m_udc[m_current].recurseIntoSubdirectories= m_recurseIntoSubdirectories;
+ m_udc[m_current].askForConfirmation= m_askForConfirmation;
+ m_udc[m_current].showConsoleWindow= m_showConsoleWindow;
+ m_udc[m_current].waitForCompletion= m_waitForCompletion;
+ m_udc[m_current].refreshPolicy= (REFRESHPOLICY)m_refreshPolicy;
+}
+
+void CPageCleanups::OnSomethingChanged()
+{
+ UpdateData();
+ if (!m_worksForDrives && !m_worksForDirectories)
+ m_recurseIntoSubdirectories= false;
+ if (!m_worksForDrives && !m_worksForDirectories)
+ m_recurseIntoSubdirectories= false;
+ if (!m_waitForCompletion)
+ m_refreshPolicy= RP_NO_REFRESH;
+ if (m_recurseIntoSubdirectories)
+ m_waitForCompletion= true;
+ UpdateData(false);
+ DialogToCurrentUdc();
+ SetModified();
+}
+
+void CPageCleanups::UpdateControlStatus()
+{
+ m_ctlTitle.EnableWindow(m_enabled);
+ m_ctlWorksForDrives.EnableWindow(m_enabled);
+ m_ctlWorksForDirectories.EnableWindow(m_enabled);
+ m_ctlWorksForFilesFolder.EnableWindow(m_enabled);
+ m_ctlWorksForFiles.EnableWindow(m_enabled);
+ m_ctlCommandLine.EnableWindow(m_enabled);
+ m_ctlRecurseIntoSubdirectories.EnableWindow(m_enabled && (m_worksForDrives || m_worksForDirectories));
+ m_ctlAskForConfirmation.EnableWindow(m_enabled);
+ m_ctlShowConsoleWindow.EnableWindow(m_enabled);
+ m_ctlWaitForCompletion.EnableWindow(m_enabled && !m_recurseIntoSubdirectories);
+ m_ctlRefreshPolicy.EnableWindow(m_enabled);
+
+ m_ctlHintSp.ShowWindow(m_recurseIntoSubdirectories ? SW_SHOW : SW_HIDE);
+ m_ctlHintSn.ShowWindow(m_recurseIntoSubdirectories ? SW_SHOW : SW_HIDE);
+
+ m_ctlUp.EnableWindow(m_current > 0);
+ m_ctlDown.EnableWindow(m_current < USERDEFINEDCLEANUPCOUNT - 1);
+}
+
+void CPageCleanups::OnBnClickedEnabled()
+{
+ OnSomethingChanged();
+ UpdateControlStatus();
+ if (m_enabled)
+ {
+ m_ctlTitle.SetFocus();
+ m_ctlTitle.SetSel(0, -1, true);
+ }
+ else
+ {
+ m_list.SetFocus();
+ }
+}
+
+void CPageCleanups::OnEnChangeTitle()
+{
+ OnSomethingChanged();
+ m_list.DeleteString(m_current);
+ m_list.InsertString(m_current, m_title);
+ m_list.SetCurSel(m_current);
+}
+
+void CPageCleanups::OnBnClickedWorksfordrives()
+{
+ OnSomethingChanged();
+ UpdateControlStatus();
+}
+
+void CPageCleanups::OnBnClickedWorksfordirectories()
+{
+ OnSomethingChanged();
+ UpdateControlStatus();
+}
+
+void CPageCleanups::OnBnClickedWorksforfilesfolder()
+{
+ OnSomethingChanged();
+}
+
+void CPageCleanups::OnBnClickedWorksforfiles()
+{
+ OnSomethingChanged();
+}
+
+void CPageCleanups::OnEnChangeCommandline()
+{
+ OnSomethingChanged();
+}
+
+void CPageCleanups::OnBnClickedRecurseintosubdirectories()
+{
+ OnSomethingChanged();
+ UpdateControlStatus();
+}
+
+void CPageCleanups::OnBnClickedAskforconfirmation()
+{
+ OnSomethingChanged();
+}
+
+void CPageCleanups::OnBnClickedShowconsolewindow()
+{
+ OnSomethingChanged();
+}
+
+void CPageCleanups::OnBnClickedWaitforcompletion()
+{
+ OnSomethingChanged();
+}
+
+void CPageCleanups::OnCbnSelendokRefreshpolicy()
+{
+ OnSomethingChanged();
+}
+
+
+void CPageCleanups::OnBnClickedUp()
+{
+ ASSERT(m_current > 0);
+
+ UpdateData();
+
+ USERDEFINEDCLEANUP h= m_udc[m_current - 1];
+ m_udc[m_current - 1]= m_udc[m_current];
+ m_udc[m_current]= h;
+
+ m_list.DeleteString(m_current);
+ m_list.InsertString(m_current - 1, m_title);
+
+ m_current--;
+ m_list.SetCurSel(m_current);
+
+ SetModified();
+ UpdateControlStatus();
+}
+
+void CPageCleanups::OnBnClickedDown()
+{
+ ASSERT(m_current < USERDEFINEDCLEANUPCOUNT - 1);
+
+ UpdateData();
+
+ USERDEFINEDCLEANUP h= m_udc[m_current + 1];
+ m_udc[m_current + 1]= m_udc[m_current];
+ m_udc[m_current]= h;
+
+ m_list.DeleteString(m_current);
+ m_list.InsertString(m_current + 1, m_title);
+
+ m_current++;
+ m_list.SetCurSel(m_current);
+
+ SetModified();
+ UpdateControlStatus();
+}
+
+void CPageCleanups::OnBnClickedHelpbutton()
+{
+ GetApp()->DoContextHelp(IDH_UserDefinedCleanups);
+}
diff --git a/windirstat/PageCleanups.h b/windirstat/PageCleanups.h
new file mode 100644
index 0000000..68e6b01
--- /dev/null
+++ b/windirstat/PageCleanups.h
@@ -0,0 +1,100 @@
+// pagecleanups.h - Declaration of CPageCleanups
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+#include "afxwin.h"
+
+//
+// CPageCleanups. "Settings" property page "User defined cleanups".
+//
+class CPageCleanups : public CPropertyPage
+{
+ DECLARE_DYNAMIC(CPageCleanups)
+ enum { IDD = IDD_PAGE_CLEANUPS };
+
+public:
+ CPageCleanups();
+ virtual ~CPageCleanups();
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX);
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+
+ void CurrentUdcToDialog();
+ void DialogToCurrentUdc();
+ void OnSomethingChanged();
+ void UpdateControlStatus();
+ void CheckEmptyTitle();
+
+ USERDEFINEDCLEANUP m_udc[USERDEFINEDCLEANUPCOUNT];
+ int m_current; // currently selected user defined cleanup
+
+ // Dialog data
+ CListBox m_list;
+ BOOL m_enabled;
+ CString m_title;
+ BOOL m_worksForDrives;
+ BOOL m_worksForDirectories;
+ BOOL m_worksForFilesFolder;
+ BOOL m_worksForFiles;
+ CString m_commandLine;
+ BOOL m_recurseIntoSubdirectories;
+ BOOL m_askForConfirmation;
+ BOOL m_showConsoleWindow;
+ BOOL m_waitForCompletion;
+ int m_refreshPolicy;
+ CComboBox m_ctlRefreshPolicy;
+
+ CEdit m_ctlTitle;
+ CButton m_ctlWorksForDrives;
+ CButton m_ctlWorksForDirectories;
+ CButton m_ctlWorksForFilesFolder;
+ CButton m_ctlWorksForFiles;
+ CEdit m_ctlCommandLine;
+ CButton m_ctlRecurseIntoSubdirectories;
+ CButton m_ctlAskForConfirmation;
+ CButton m_ctlShowConsoleWindow;
+ CButton m_ctlWaitForCompletion;
+ CStatic m_ctlHintSp;
+ CStatic m_ctlHintSn;
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnLbnSelchangeList();
+ afx_msg void OnBnClickedEnabled();
+ afx_msg void OnEnChangeTitle();
+ afx_msg void OnBnClickedWorksfordrives();
+ afx_msg void OnBnClickedWorksfordirectories();
+ afx_msg void OnBnClickedWorksforfilesfolder();
+ afx_msg void OnBnClickedWorksforfiles();
+ afx_msg void OnEnChangeCommandline();
+ afx_msg void OnBnClickedRecurseintosubdirectories();
+ afx_msg void OnBnClickedAskforconfirmation();
+ afx_msg void OnBnClickedShowconsolewindow();
+ afx_msg void OnBnClickedWaitforcompletion();
+ afx_msg void OnCbnSelendokRefreshpolicy();
+public:
+ afx_msg void OnBnClickedUp();
+ afx_msg void OnBnClickedDown();
+ CButton m_ctlUp;
+ CButton m_ctlDown;
+ afx_msg void OnBnClickedHelpbutton();
+};
diff --git a/windirstat/PageColors.cpp b/windirstat/PageColors.cpp
new file mode 100644
index 0000000..e5f12e8
--- /dev/null
+++ b/windirstat/PageColors.cpp
@@ -0,0 +1,360 @@
+// PageColors.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "bdirstat.h"
+#include "dirstatdoc.h"
+#include "PageColors.h"
+#include ".\pagecolors.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+CExtensionListControl::CListItem::CListItem(LPCSTR extension)
+{
+ m_extension= extension;
+ m_extension.MakeLower();
+ m_image= -1;
+}
+
+CString CExtensionListControl::CListItem::GetText(int subitem)
+{
+ switch (subitem)
+ {
+ case COL_EXTENSION:
+ return GetExtension();
+
+ case COL_DESCRIPTION:
+ return GetDescription();
+
+ default:
+ ASSERT(0);
+ return "";
+ }
+}
+
+CString CExtensionListControl::CListItem::GetExtension()
+{
+ return m_extension;
+}
+
+int CExtensionListControl::CListItem::GetImage()
+{
+ if (m_image == -1)
+ {
+ m_image= GetExtensionImageIndexAndDescription(m_extension, m_description);
+ }
+ return m_image;
+}
+
+
+CString CExtensionListControl::CListItem::GetDescription()
+{
+ if (m_description.IsEmpty())
+ {
+ m_image= GetExtensionImageIndexAndDescription(m_extension, m_description);
+ }
+ return m_description;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+BEGIN_MESSAGE_MAP(CExtensionListControl, CListCtrl)
+ ON_WM_DESTROY()
+ ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnLvnGetdispinfo)
+ ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnLvnDeleteitem)
+END_MESSAGE_MAP()
+
+// As we will not receive WM_CREATE, we must do initialization
+// in this extra method. The counterpart is OnDestroy().
+void CExtensionListControl::Initialize()
+{
+ SetImageList(CImageList::FromHandle(GetSystemImageList()), LVSIL_SMALL);
+ InsertColumn(COL_EXTENSION, "Extension", LVCFMT_LEFT, 70, COL_EXTENSION);
+ InsertColumn(COL_DESCRIPTION, "Description", LVCFMT_LEFT, 210, COL_DESCRIPTION);
+}
+
+void CExtensionListControl::OnDestroy()
+{
+ SetImageList(NULL, LVSIL_SMALL);
+
+ CListCtrl::OnDestroy();
+}
+
+void CExtensionListControl::AddExtensions(const CExtensionSet& extensions, bool select)
+{
+ POSITION pos= extensions.GetStartPosition();
+ while (pos != NULL)
+ {
+ CString ext;
+ extensions.GetNextAssoc(pos, ext);
+
+ CListItem *item= new CListItem(ext);
+
+ LVITEM lvi;
+ ZeroMemory(&lvi, sizeof(lvi));
+ lvi.mask= LVIF_IMAGE | LVIF_PARAM | LVIF_TEXT | LVIF_STATE;
+ lvi.iItem= GetItemCount();
+ lvi.state= select ? LVIS_SELECTED : 0;
+ lvi.stateMask= LVIS_SELECTED;
+ lvi.pszText= LPSTR_TEXTCALLBACK;
+ lvi.iImage= I_IMAGECALLBACK;
+ lvi.lParam= (LPARAM)item;
+
+ InsertItem(&lvi);
+ }
+}
+
+void CExtensionListControl::GetSelectedIndices(CArray<int, int>& selected)
+{
+ selected.RemoveAll();
+ POSITION pos= GetFirstSelectedItemPosition();
+ while (pos != NULL)
+ {
+ int i= GetNextSelectedItem(pos);
+ selected.Add(i);
+ }
+}
+
+CExtensionListControl::CListItem *CExtensionListControl::GetListItem(int i)
+{
+ return (CListItem *)GetItemData(i);
+}
+
+void CExtensionListControl::OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ NMLVDISPINFO *di= reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
+
+ CListItem *item= GetListItem(di->item.iItem);
+
+ if ((di->item.mask & LVIF_IMAGE) != 0)
+ di->item.iImage= item->GetImage();
+
+ if ((di->item.mask & LVIF_TEXT) != 0)
+ lstrcpyn(di->item.pszText, item->GetText(di->item.iSubItem), di->item.cchTextMax);
+
+ *pResult = 0;
+}
+
+void CExtensionListControl::OnLvnDeleteitem(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMLISTVIEW lv= reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
+ delete (CListItem *)(lv->lParam);
+ *pResult = 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CGroupListControl::Initialize()
+{
+ // TODO: Imagelist
+ InsertColumn(0, "Color Group", LVCFMT_LEFT, 280, 0);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_DYNAMIC(CPageColors, CPropertyPage)
+
+CPageColors::CPageColors()
+ : CPropertyPage(CPageColors::IDD)
+{
+}
+
+CPageColors::~CPageColors()
+{
+}
+
+void CPageColors::ReadOptions(SOptions *options)
+{
+ // Copy colorgroup
+ m_colorGroup.RemoveAll();
+ for (int i=0; i < options->colorGroup.GetSize(); i++)
+ m_colorGroup.Add(options->colorGroup[i]);
+
+ // Copy extension map
+ m_extension.RemoveAll();
+ POSITION pos= options->extension.GetStartPosition();
+ while (pos != NULL)
+ {
+ CString ext;
+ int group;
+ options->extension.GetNextAssoc(pos, ext, group);
+ m_extension.SetAt(ext, group);
+ }
+
+ // Include unassigned extensions
+ pos= options->extensionColorMap.GetStartPosition();
+ while (pos != NULL)
+ {
+ CString ext;
+ COLORREF dummy;
+ options->extensionColorMap.GetNextAssoc(pos, ext, dummy);
+
+ int group;
+ if (!m_extension.Lookup(ext, group))
+ m_extension.SetAt(ext, 0);
+ }
+}
+
+void CPageColors::WriteOptions(SOptions *options)
+{
+ // Copy colorgroup
+ options->colorGroup.RemoveAll();
+ for (int i=0; i < m_colorGroup.GetSize(); i++)
+ options->colorGroup.Add(m_colorGroup[i]);
+
+ // Copy extension map
+ options->extension.RemoveAll();
+ POSITION pos= m_extension.GetStartPosition();
+ while (pos != NULL)
+ {
+ CString ext;
+ int group;
+ m_extension.GetNextAssoc(pos, ext, group);
+ options->extension.SetAt(ext, group);
+ }
+
+ // Recreate extensionColorMap
+ options->extensionColorMap.RemoveAll();
+ pos= m_extension.GetStartPosition();
+ while (pos != NULL)
+ {
+ CString ext;
+ int group;
+ m_extension.GetNextAssoc(pos, ext, group);
+
+ options->extensionColorMap.SetAt(ext, m_colorGroup[group].color);
+ }
+}
+
+void CPageColors::DoDataExchange(CDataExchange* pDX)
+{
+ CPropertyPage::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_EXTENSIONS, m_extensionList);
+ DDX_Control(pDX, IDC_MEMBERS, m_memberList);
+ DDX_Control(pDX, IDC_GROUPS, m_groupList);
+}
+
+
+BEGIN_MESSAGE_MAP(CPageColors, CPropertyPage)
+ ON_NOTIFY(LVN_BEGINDRAG, IDC_EXTENSIONS, OnLvnBegindrag)
+ ON_NOTIFY(LVN_BEGINDRAG, IDC_GROUPS, OnLvnBegindrag)
+ ON_NOTIFY(LVN_BEGINDRAG, IDC_MEMBERS, OnLvnBegindrag)
+END_MESSAGE_MAP()
+
+
+// CPageColors message handlers
+
+BOOL CPageColors::OnInitDialog()
+{
+ CPropertyPage::OnInitDialog();
+
+ m_extensionList.Initialize();
+ m_groupList.Initialize();
+ m_memberList.Initialize();
+
+ CExtensionSet es;
+ POSITION pos= m_extension.GetStartPosition();
+ while (pos != NULL)
+ {
+ CString ext;
+ int group;
+ m_extension.GetNextAssoc(pos, ext, group);
+ if (group == 0)
+ es.SetKey(ext);
+ }
+
+ m_extensionList.AddExtensions(es, false);
+ return TRUE; // return TRUE unless you set the focus to a control
+}
+
+
+// See MFC sample "LISTHDR".
+void CPageColors::OnLvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMLISTVIEW lv= reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
+ *pResult = 0;
+
+ if (lv->hdr.idFrom == IDC_GROUPS)
+ return;
+
+ CExtensionListControl *source= NULL;
+ switch (lv->hdr.idFrom)
+ {
+ case IDC_EXTENSIONS: source= &m_extensionList; break;
+ case IDC_MEMBERS: source= &m_memberList; break;
+ default: ASSERT(0); break;
+ }
+
+ CRect rcSource;
+ source->GetWindowRect(rcSource);
+ ScreenToClient(rcSource);
+
+ const itemDrag= lv->iItem;
+ CPoint ptAction= lv->ptAction;
+ ptAction+= rcSource.TopLeft();
+
+ CPoint ptItem;
+ source->GetItemPosition(itemDrag, &ptItem); // view coordinates
+ ptItem+= rcSource.TopLeft();
+
+ CPoint ptOrigin;
+ source->GetOrigin(&ptOrigin);
+
+ const CPoint ptHotSpot= ptAction - ptItem + ptOrigin; // relative to drag image
+
+ CArray<int, int> ia;
+ source->GetSelectedIndices(ia);
+ if (ia.GetSize() == 0)
+ return;
+
+ for (int i=0; i < ia.GetSize(); i++)
+ if (ia[i] == itemDrag)
+ break;
+ ASSERT(i < ia.GetSize());
+ int tmp= ia[0]; ia[0]= ia[i]; ia[i]= tmp;
+
+ CImageList il;
+ il.Create(IDB_DRAGIMAGES, 24, 0, RGB(255,0,255));
+ int image= ia.GetSize() > 1 ? 1 : 0;
+
+ CSize szDelta= ptAction - ptItem;
+ il.DragShowNolock(true); // lock updates and show drag image
+ il.SetDragCursorImage(image, CPoint(0, 0)); // define the hot spot for the new cursor image
+ ptAction-= szDelta;
+ il.BeginDrag(image, CPoint(0, 0));
+ il.DragEnter(this, ptAction);
+
+ il.DragMove(ptAction);
+
+
+ //ShowCursor(false);
+ SetCapture();
+
+ for (;;)
+ {
+ MSG msg;
+ GetMessage(&msg, *this, 0, 0);
+
+ if (msg.message == WM_MOUSEMOVE)
+ {
+ CPoint point= msg.pt;
+ ScreenToClient(&point);
+ il.DragMove(point - szDelta); // move the image
+ }
+ else if (msg.message == WM_LBUTTONUP)
+ {
+ break;
+ }
+ }
+
+ il.DragLeave(this);
+ il.EndDrag();
+
+ ReleaseCapture();
+ //ShowCursor(true);
+}
+
+
diff --git a/windirstat/PageColors.h b/windirstat/PageColors.h
new file mode 100644
index 0000000..cab9e8c
--- /dev/null
+++ b/windirstat/PageColors.h
@@ -0,0 +1,102 @@
+// pagecolors.h
+
+
+#pragma once
+
+#include "dirstatdoc.h" //SOptions
+
+typedef CSet<CString, LPCSTR> CExtensionSet;
+typedef CIndexArray;
+
+struct SColorGroup
+{
+ CString name;
+ COLORREF color;
+};
+
+struct SOptions
+{
+ CExtensionColorMap extensionColorMap;
+ CArray<SColorGroup, SColorGroup&> colorGroup; // Group #0 = <unassigned>
+ CMap<CString, LPCSTR, int, int> extension; // extension -> colorGroup
+
+ void ReadFromRegistry() {}
+ void WriteToRegistry() {}
+};
+
+
+class CExtensionListControl: public CListCtrl
+{
+protected:
+ enum
+ {
+ COL_EXTENSION,
+ COL_DESCRIPTION
+ };
+
+ class CListItem
+ {
+ public:
+ CListItem(LPCSTR extension);
+ CString GetExtension();
+ CString GetText(int subitem);
+ int GetImage();
+
+ private:
+ CString GetDescription();
+
+ CString m_extension;
+ CString m_description;
+ int m_image;
+ };
+
+public:
+ void Initialize();
+ void AddExtensions(const CExtensionSet& extensions, bool select);
+ void GetSelectedIndices(CArray<int, int>& selected);
+
+protected:
+ CListItem *GetListItem(int i);
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnDestroy();
+public:
+ afx_msg void OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnLvnDeleteitem(NMHDR *pNMHDR, LRESULT *pResult);
+};
+
+class CGroupListControl: public CListCtrl
+{
+public:
+ void Initialize();
+};
+
+
+class CPageColors : public CPropertyPage
+{
+ DECLARE_DYNAMIC(CPageColors)
+
+public:
+ CPageColors();
+ virtual ~CPageColors();
+
+ void ReadOptions(SOptions *options);
+ void WriteOptions(SOptions *options);
+
+protected:
+ // Dialog Data
+ CArray<SColorGroup, SColorGroup&> m_colorGroup; // Group #0 = <unassigned>
+ CMap<CString, LPCSTR, int, int> m_extension; // extension -> colorGroup
+
+ enum { IDD = IDD_PAGE_COLORS };
+
+ virtual void DoDataExchange(CDataExchange* pDX);
+
+ DECLARE_MESSAGE_MAP()
+ CExtensionListControl m_extensionList;
+ CExtensionListControl m_memberList;
+ CGroupListControl m_groupList;
+public:
+ virtual BOOL OnInitDialog();
+ afx_msg void OnLvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult);
+};
diff --git a/windirstat/PageGeneral.cpp b/windirstat/PageGeneral.cpp
new file mode 100644
index 0000000..34cd71f
--- /dev/null
+++ b/windirstat/PageGeneral.cpp
@@ -0,0 +1,125 @@
+// PageGeneral.cpp - Implementation of CPageGeneral
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include ".\pagegeneral.h"
+
+
+IMPLEMENT_DYNAMIC(CPageGeneral, CPropertyPage)
+
+CPageGeneral::CPageGeneral()
+ : CPropertyPage(CPageGeneral::IDD)
+ , m_humanFormat(FALSE)
+ , m_followMountPoints(FALSE)
+ , m_pacmanAnimation(FALSE)
+{
+}
+
+CPageGeneral::~CPageGeneral()
+{
+}
+
+void CPageGeneral::DoDataExchange(CDataExchange* pDX)
+{
+ CPropertyPage::DoDataExchange(pDX);
+ DDX_Check(pDX, IDC_HUMANFORMAT, m_humanFormat);
+ DDX_Check(pDX, IDC_FOLLOWMOUNTPOINTS, m_followMountPoints);
+ DDX_Check(pDX, IDC_PACMANANIMATION, m_pacmanAnimation);
+ DDX_Control(pDX, IDC_COMBO, m_combo);
+ DDX_Control(pDX, IDC_FOLLOWMOUNTPOINTS, m_ctlFollowMountPoints);
+}
+
+
+BEGIN_MESSAGE_MAP(CPageGeneral, CPropertyPage)
+ ON_BN_CLICKED(IDC_HUMANFORMAT, OnBnClickedHumanformat)
+ ON_BN_CLICKED(IDC_FOLLOWMOUNTPOINTS, OnBnClickedFollowmountpoints)
+ ON_BN_CLICKED(IDC_PACMANANIMATION, OnBnClickedPacmananimation)
+END_MESSAGE_MAP()
+
+
+BOOL CPageGeneral::OnInitDialog()
+{
+ CPropertyPage::OnInitDialog();
+
+ m_humanFormat= GetOptions()->IsHumanFormat();
+ m_pacmanAnimation= GetOptions()->IsPacmanAnimation();
+
+ m_followMountPoints= GetOptions()->IsFollowMountPoints();
+ CVolumeApi va;
+ if (!va.IsSupported())
+ {
+ m_followMountPoints= false; // Otherwise we would see pacman only.
+ m_ctlFollowMountPoints.ShowWindow(SW_HIDE); // Ignorance is bliss.
+ }
+
+ int k= m_combo.AddString(GetLocaleLanguage(GetApp()->GetBuiltInLanguage()));
+ m_combo.SetItemData(k, GetApp()->GetBuiltInLanguage());
+
+ CArray<LANGID, LANGID> langid;
+ GetApp()->GetAvailableResourceDllLangids(langid);
+
+ for (int i=0; i < langid.GetSize(); i++)
+ {
+ k= m_combo.AddString(GetLocaleLanguage(langid[i]));
+ m_combo.SetItemData(k, langid[i]);
+ }
+
+ for (i=0; i < m_combo.GetCount(); i++)
+ {
+ if (m_combo.GetItemData(i) == GetApp()->GetLangid())
+ {
+ m_combo.SetCurSel(i);
+ break;
+ }
+ }
+
+ UpdateData(false);
+ return TRUE;
+}
+
+void CPageGeneral::OnOK()
+{
+ UpdateData();
+ GetOptions()->SetHumanFormat(m_humanFormat);
+ GetOptions()->SetFollowMountPoints(m_followMountPoints);
+ GetOptions()->SetPacmanAnimation(m_pacmanAnimation);
+
+ LANGID id= (LANGID)m_combo.GetItemData(m_combo.GetCurSel());
+ CLanguageOptions::SetLanguage(id);
+
+ CPropertyPage::OnOK();
+}
+
+void CPageGeneral::OnBnClickedHumanformat()
+{
+ SetModified();
+}
+
+void CPageGeneral::OnBnClickedFollowmountpoints()
+{
+ SetModified();
+}
+
+void CPageGeneral::OnBnClickedPacmananimation()
+{
+ SetModified();
+}
diff --git a/windirstat/PageGeneral.h b/windirstat/PageGeneral.h
new file mode 100644
index 0000000..a23057e
--- /dev/null
+++ b/windirstat/PageGeneral.h
@@ -0,0 +1,53 @@
+// pagegeneral.h - Declaration of CPageGeneral
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+
+//
+// CPageGeneral. "Settings" property page "General".
+//
+class CPageGeneral : public CPropertyPage
+{
+ DECLARE_DYNAMIC(CPageGeneral)
+ enum { IDD = IDD_PAGE_GENERAL };
+
+public:
+ CPageGeneral();
+ virtual ~CPageGeneral();
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX);
+
+ BOOL m_humanFormat;
+
+ DECLARE_MESSAGE_MAP()
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+ afx_msg void OnBnClickedHumanformat();
+public:
+ BOOL m_followMountPoints;
+ afx_msg void OnBnClickedFollowmountpoints();
+ BOOL m_pacmanAnimation;
+ afx_msg void OnBnClickedPacmananimation();
+ CComboBox m_combo;
+ CButton m_ctlFollowMountPoints;
+};
diff --git a/windirstat/PageTreelist.cpp b/windirstat/PageTreelist.cpp
new file mode 100644
index 0000000..47f4ee5
--- /dev/null
+++ b/windirstat/PageTreelist.cpp
@@ -0,0 +1,120 @@
+// PageTreelist.cpp - Implementation of CPageTreelist
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include ".\pagetreelist.h"
+
+
+IMPLEMENT_DYNAMIC(CPageTreelist, CPropertyPage)
+
+CPageTreelist::CPageTreelist()
+ : CPropertyPage(CPageTreelist::IDD)
+ , m_treelistGrid(FALSE)
+{
+}
+
+CPageTreelist::~CPageTreelist()
+{
+}
+
+void CPageTreelist::DoDataExchange(CDataExchange* pDX)
+{
+ CPropertyPage::DoDataExchange(pDX);
+ DDX_Check(pDX, IDC_TREELISTGRID, m_treelistGrid);
+ for (int i=0; i < TREELISTCOLORCOUNT; i++)
+ {
+ DDX_Control(pDX, IDC_COLORBUTTON0 + i, m_colorButton[i]);
+ if (pDX->m_bSaveAndValidate)
+ m_treelistColor[i]= m_colorButton[i].GetColor();
+ else
+ m_colorButton[i].SetColor(m_treelistColor[i]);
+ }
+ DDX_Control(pDX, IDC_SLIDER, m_slider);
+}
+
+
+BEGIN_MESSAGE_MAP(CPageTreelist, CPropertyPage)
+ ON_BN_CLICKED(IDC_TREELISTGRID, OnBnClickedTreelistgrid)
+ ON_NOTIFY_RANGE(COLBN_CHANGED, IDC_COLORBUTTON0, IDC_COLORBUTTON7, OnColorChanged)
+ ON_WM_VSCROLL()
+END_MESSAGE_MAP()
+
+
+BOOL CPageTreelist::OnInitDialog()
+{
+ CPropertyPage::OnInitDialog();
+
+ m_treelistGrid= GetOptions()->IsTreelistGrid();
+ m_treelistColorCount= GetOptions()->GetTreelistColorCount();
+ GetOptions()->GetTreelistColors(m_treelistColor);
+
+ m_slider.SetRange(1, TREELISTCOLORCOUNT);
+ m_slider.SetPos(m_treelistColorCount);
+
+ EnableButtons();
+
+ UpdateData(false);
+ return TRUE;
+}
+
+void CPageTreelist::OnOK()
+{
+ UpdateData();
+ GetOptions()->SetTreelistGrid(m_treelistGrid);
+ GetOptions()->SetTreelistColorCount(m_treelistColorCount);
+ GetOptions()->SetTreelistColors(m_treelistColor);
+ CPropertyPage::OnOK();
+}
+
+void CPageTreelist::OnBnClickedTreelistgrid()
+{
+ SetModified();
+}
+
+void CPageTreelist::OnColorChanged(UINT, NMHDR *, LRESULT *)
+{
+ SetModified();
+}
+
+void CPageTreelist::EnableButtons()
+{
+ for (int i=0; i < m_treelistColorCount; i++)
+ m_colorButton[i].EnableWindow(true);
+ for (; i < TREELISTCOLORCOUNT; i++)
+ m_colorButton[i].EnableWindow(false);
+}
+
+
+void CPageTreelist::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ if ((CSliderCtrl *)pScrollBar == &m_slider)
+ {
+ int pos= m_slider.GetPos();
+ ASSERT(pos > 0);
+ ASSERT(pos <= TREELISTCOLORCOUNT);
+
+ m_treelistColorCount= pos;
+ EnableButtons();
+ SetModified();
+ }
+ CPropertyPage::OnVScroll(nSBCode, nPos, pScrollBar);
+}
diff --git a/windirstat/PageTreelist.h b/windirstat/PageTreelist.h
new file mode 100644
index 0000000..e0c4359
--- /dev/null
+++ b/windirstat/PageTreelist.h
@@ -0,0 +1,57 @@
+// pagetreelist.h - Declaration of CPageTreelist
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "colorbutton.h"
+#include "afxcmn.h"
+
+//
+// CPageTreelist. "Settings" property page "Treelist".
+//
+class CPageTreelist : public CPropertyPage
+{
+ DECLARE_DYNAMIC(CPageTreelist)
+ enum { IDD = IDD_PAGE_TREELIST };
+
+public:
+ CPageTreelist();
+ virtual ~CPageTreelist();
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX);
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+ void EnableButtons();
+
+ BOOL m_treelistGrid;
+ int m_treelistColorCount;
+ COLORREF m_treelistColor[TREELISTCOLORCOUNT];
+
+ CColorButton m_colorButton[TREELISTCOLORCOUNT];
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnBnClickedTreelistgrid();
+ afx_msg void OnColorChanged(UINT id, NMHDR *, LRESULT *);
+public:
+ CSliderCtrl m_slider;
+ afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+};
diff --git a/windirstat/PageTreemap.cpp b/windirstat/PageTreemap.cpp
new file mode 100644
index 0000000..52115be
--- /dev/null
+++ b/windirstat/PageTreemap.cpp
@@ -0,0 +1,295 @@
+// PageTreemap.cpp - Implementation of CDemoControl and CPageTreemap
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include ".\pagetreemap.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+CDemoControl::CDemoControl()
+{
+}
+
+void CDemoControl::SetParameters(int heightFactor, int scaleFactor)
+{
+ m_h= heightFactor / 100.0;
+ m_f= scaleFactor / 100.0;
+
+ for (int i=0; i < 3; i++)
+ {
+ m_bigSurface[i]= 0;
+ m_smallSurface1[i]= 0;
+ m_smallSurface2[i]= 0;
+ }
+
+ CRect rc;
+ GetClientRect(rc);
+
+ m_middle= rc.left + (int)(0.7 * rc.Width());
+
+ AddRidge(rc.left, rc.right, m_bigSurface, m_h);
+ AddRidge(rc.left, m_middle, m_smallSurface1, m_h * m_f);
+ AddRidge(m_middle, rc.right, m_smallSurface2, m_h * m_f);
+
+ for (i=0; i < 3; i++)
+ {
+ m_sum1[i]= m_bigSurface[i] + m_smallSurface1[i];
+ m_sum2[i]= m_bigSurface[i] + m_smallSurface2[i];
+ }
+
+
+ InvalidateRect(NULL);
+}
+
+void CDemoControl::AddRidge(int left, int right, double *surface, double h)
+{
+ surface[1]+= 4 * h * (right + left) / (right - left);
+ surface[0]-= 4 * h / (right - left);
+ surface[2]-= surface[0] * left * left + surface[1] * left;
+}
+
+BEGIN_MESSAGE_MAP(CDemoControl, CStatic)
+ ON_WM_PAINT()
+END_MESSAGE_MAP()
+
+void CDemoControl::OnPaint()
+{
+ CPaintDC dc(this);
+
+ CRect rc;
+ GetClientRect(rc);
+
+ dc.IntersectClipRect(rc);
+ dc.FillSolidRect(rc, GetSysColor(COLOR_BTNFACE));
+
+ DrawSurface(&dc, rc, rc.left, rc.right, m_bigSurface, RGB(0, 0, 255), 1);
+ DrawSurface(&dc, rc, rc.left, m_middle, m_smallSurface1, RGB(0, 200, 0), 1);
+ DrawSurface(&dc, rc, m_middle, rc.right, m_smallSurface2, RGB(0, 200, 0), 1);
+
+ DrawSurface(&dc, rc, rc.left, m_middle, m_sum1, RGB(255, 0, 0), 2);
+ DrawSurface(&dc, rc, m_middle, rc.right, m_sum2, RGB(255, 0, 0), 2);
+
+}
+
+void CDemoControl::DrawSurface(CDC *pdc, const CRect& rc, int left, int right, const double *surface, COLORREF color, int thick)
+{
+ for (int x=left; x < right; x++)
+ {
+ int y= (int)(surface[0] * x * x + surface[1] * x + surface[2]);
+ y/= 2;
+
+ y= rc.bottom - y;
+
+ CRect r(x-thick, y-thick, x+thick, y+thick);
+ pdc->FillSolidRect(r, color);
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_DYNAMIC(CPageTreemap, CPropertyPage)
+
+CPageTreemap::CPageTreemap()
+ : CPropertyPage(CPageTreemap::IDD)
+ , m_treemapGrid(FALSE)
+ , m_cushionShading(FALSE)
+ , m_scaleFactor(0)
+ , m_heightFactor(0)
+ , m_ambientLight(0)
+{
+ m_inited= false;
+}
+
+CPageTreemap::~CPageTreemap()
+{
+}
+
+void CPageTreemap::DoDataExchange(CDataExchange* pDX)
+{
+ int min, max;
+
+ CPropertyPage::DoDataExchange(pDX);
+
+ DDX_Check(pDX, IDC_TREEMAPGRID, m_treemapGrid);
+ DDX_Control(pDX, IDC_TREEMAPGRIDCOLOR, m_treemapGridColor);
+ DDX_Control(pDX, IDC_TREEMAPHIGHLIGHTCOLOR, m_treemapHighlightColor);
+
+ DDX_Check(pDX, IDC_CUSHIONSHADING, m_cushionShading);
+
+ DDX_Text(pDX, IDC_SCALEFACTOR, m_scaleFactor);
+ GetOptions()->GetScaleFactorRange(min, max);
+ DDV_MinMaxUInt(pDX, m_scaleFactor, min, max);
+
+ DDX_Text(pDX, IDC_HEIGHTFACTOR, m_heightFactor);
+ GetOptions()->GetHeightFactorRange(min, max);
+ DDV_MinMaxUInt(pDX, m_heightFactor, min, max);
+
+ DDX_Text(pDX, IDC_AMBIENTLIGHT, m_ambientLight);
+ GetOptions()->GetAmbientLightRange(min, max);
+ DDV_MinMaxUInt(pDX, m_ambientLight, min, max);
+
+ DDX_Control(pDX, IDC_AMBIENTLIGHTSPIN, m_ambientLightSpin);
+ DDX_Control(pDX, IDC_HEIGHTFACTORSPIN, m_heightFactorSpin);
+ DDX_Control(pDX, IDC_SCALEFACTORSPIN, m_scaleFactorSpin);
+ DDX_Control(pDX, IDC_AMBIENTLIGHT, m_ctlAmbientLight);
+ DDX_Control(pDX, IDC_HEIGHTFACTOR, m_ctlHeightFactor);
+ DDX_Control(pDX, IDC_SCALEFACTOR, m_ctlScaleFactor);
+ DDX_Control(pDX, IDC_RESETTODEFAULTS, m_resetToDefaults);
+ DDX_Control(pDX, IDC_DEMO, m_demo);
+}
+
+
+BEGIN_MESSAGE_MAP(CPageTreemap, CPropertyPage)
+ ON_BN_CLICKED(IDC_TREEMAPGRID, OnBnClickedTreemapgrid)
+ ON_NOTIFY(COLBN_CHANGED, IDC_TREEMAPGRIDCOLOR, OnColorChangedTreemapGrid)
+ ON_NOTIFY(COLBN_CHANGED, IDC_TREEMAPHIGHLIGHTCOLOR, OnColorChangedTreemapHighlight)
+ ON_BN_CLICKED(IDC_CUSHIONSHADING, OnBnClickedCushionshading)
+ ON_EN_CHANGE(IDC_SCALEFACTOR, OnEnChangeScalefactor)
+ ON_EN_CHANGE(IDC_HEIGHTFACTOR, OnEnChangeHeightfactor)
+ ON_EN_CHANGE(IDC_AMBIENTLIGHT, OnEnChangeAmbientlight)
+ ON_BN_CLICKED(IDC_RESETTODEFAULTS, OnBnClickedResettodefaults)
+END_MESSAGE_MAP()
+
+
+BOOL CPageTreemap::OnInitDialog()
+{
+ CPropertyPage::OnInitDialog();
+
+ m_cushionShading= GetOptions()->IsCushionShading();
+ m_treemapGrid= GetOptions()->IsTreemapGrid();
+ m_treemapGridColor.SetColor(GetOptions()->GetTreemapGridColor());
+ m_treemapHighlightColor.SetColor(GetOptions()->GetTreemapHighlightColor());
+ m_heightFactor= GetOptions()->GetHeightFactor();
+ m_scaleFactor= GetOptions()->GetScaleFactor();
+ m_ambientLight= GetOptions()->GetAmbientLight();
+
+ int min, max;
+
+ GetOptions()->GetHeightFactorRange(min, max);
+ m_heightFactorSpin.SetRange32(min, max);
+
+ GetOptions()->GetScaleFactorRange(min, max);
+ m_scaleFactorSpin.SetRange32(min, max);
+
+ GetOptions()->GetAmbientLightRange(min, max);
+ m_ambientLightSpin.SetRange32(min, max);
+
+ UpdateData(false);
+ m_inited= true;
+ UpdateControlStatus();
+ return TRUE;
+}
+
+void CPageTreemap::OnOK()
+{
+ UpdateData();
+
+ GetOptions()->SetCushionShading(m_cushionShading);
+ GetOptions()->SetTreemapGrid(m_treemapGrid);
+ GetOptions()->SetTreemapGridColor(m_treemapGridColor.GetColor());
+ GetOptions()->SetTreemapHighlightColor(m_treemapHighlightColor.GetColor());
+ GetOptions()->SetHeightFactor(m_heightFactor);
+ GetOptions()->SetScaleFactor(m_scaleFactor);
+ GetOptions()->SetAmbientLight(m_ambientLight);
+
+ CPropertyPage::OnOK();
+}
+
+void CPageTreemap::OnBnClickedTreemapgrid()
+{
+ SetModified();
+ UpdateControlStatus();
+}
+
+void CPageTreemap::OnColorChangedTreemapGrid(NMHDR *, LRESULT *result)
+{
+ *result= 0;
+ SetModified();
+}
+
+void CPageTreemap::OnColorChangedTreemapHighlight(NMHDR *, LRESULT *result)
+{
+ *result= 0;
+ SetModified();
+}
+
+void CPageTreemap::UpdateControlStatus()
+{
+ if (!m_inited)
+ return;
+
+ UpdateData();
+
+ m_ctlHeightFactor.EnableWindow(m_cushionShading);
+ m_heightFactorSpin.EnableWindow(m_cushionShading);
+ m_ctlScaleFactor.EnableWindow(m_cushionShading);
+ m_scaleFactorSpin.EnableWindow(m_cushionShading);
+ m_ctlAmbientLight.EnableWindow(m_cushionShading);
+ m_ambientLightSpin.EnableWindow(m_cushionShading);
+ m_resetToDefaults.EnableWindow(m_cushionShading);
+
+ m_demo.SetParameters(m_heightFactor, m_scaleFactor);
+
+ m_treemapGridColor.EnableWindow(m_treemapGrid);
+}
+
+void CPageTreemap::OnBnClickedCushionshading()
+{
+ SetModified();
+ UpdateData();
+ if (!m_cushionShading)
+ {
+ m_treemapGrid= true;
+ UpdateData(false);
+ }
+ UpdateControlStatus();
+}
+
+void CPageTreemap::OnEnChangeScalefactor()
+{
+ SetModified();
+ UpdateControlStatus();
+}
+
+void CPageTreemap::OnEnChangeHeightfactor()
+{
+ SetModified();
+ UpdateControlStatus();
+}
+
+void CPageTreemap::OnEnChangeAmbientlight()
+{
+ SetModified();
+}
+
+void CPageTreemap::OnBnClickedResettodefaults()
+{
+ UpdateData();
+ m_heightFactor = GetOptions()->GetHeightFactorDefault();
+ m_scaleFactor = GetOptions()->GetScaleFactorDefault();
+ m_ambientLight = GetOptions()->GetAmbientLightDefault();
+ UpdateData(false);
+ UpdateControlStatus();
+ SetModified();
+}
diff --git a/windirstat/PageTreemap.h b/windirstat/PageTreemap.h
new file mode 100644
index 0000000..d88a058
--- /dev/null
+++ b/windirstat/PageTreemap.h
@@ -0,0 +1,100 @@
+// pagetreemap.h - Declaration of CDemoControl and CPageTreemap
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "colorbutton.h"
+
+//
+// CDemoControl. Shows the effect of alteration of H and F.
+//
+class CDemoControl: public CStatic
+{
+public:
+ CDemoControl();
+ void SetParameters(int heightFactor, int scaleFactor); // Percent
+
+protected:
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnPaint();
+
+ void AddRidge(int left, int right, double *surface, double h);
+ void DrawSurface(CDC *pdc, const CRect& rc, int left, int right, const double *surface, COLORREF color, int thick);
+
+ double m_h;
+ double m_f;
+
+ double m_bigSurface[3]; // y(x) = [0] * x^2 + [1] * x + [2]
+ double m_smallSurface1[3];
+ double m_smallSurface2[3];
+ double m_sum1[3];
+ double m_sum2[3];
+ int m_middle;
+};
+
+
+//
+// CPageTreemap. "Settings" property page "Treemap".
+//
+class CPageTreemap : public CPropertyPage
+{
+ DECLARE_DYNAMIC(CPageTreemap)
+ enum { IDD = IDD_PAGE_TREEMAP };
+
+public:
+ CPageTreemap();
+ virtual ~CPageTreemap();
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX);
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+
+ void UpdateControlStatus();
+
+ BOOL m_treemapGrid;
+ CColorButton m_treemapGridColor;
+ CColorButton m_treemapHighlightColor;
+ BOOL m_cushionShading;
+ UINT m_scaleFactor;
+ UINT m_heightFactor;
+ UINT m_ambientLight;
+ CSpinButtonCtrl m_ambientLightSpin;
+ CSpinButtonCtrl m_heightFactorSpin;
+ CSpinButtonCtrl m_scaleFactorSpin;
+ CEdit m_ctlAmbientLight;
+ CEdit m_ctlHeightFactor;
+ CEdit m_ctlScaleFactor;
+ CButton m_resetToDefaults;
+ CDemoControl m_demo;
+
+ bool m_inited; // true after OnInitDialog
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnBnClickedCushionshading();
+ afx_msg void OnEnChangeScalefactor();
+ afx_msg void OnEnChangeHeightfactor();
+ afx_msg void OnEnChangeAmbientlight();
+ afx_msg void OnBnClickedResettodefaults();
+ afx_msg void OnBnClickedTreemapgrid();
+ afx_msg void OnColorChangedTreemapGrid(NMHDR *, LRESULT *);
+ afx_msg void OnColorChangedTreemapHighlight(NMHDR *, LRESULT *);
+};
diff --git a/windirstat/ReportBugDlg.cpp b/windirstat/ReportBugDlg.cpp
new file mode 100644
index 0000000..d25a568
--- /dev/null
+++ b/windirstat/ReportBugDlg.cpp
@@ -0,0 +1,236 @@
+// ReportBugDlg.cpp - Implementation of CReportBugDlg
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "aboutdlg.h"
+#include "getosplatformstring.h"
+#include ".\reportbugdlg.h"
+
+
+namespace
+{
+ enum
+ {
+ SEV_CRITICAL,
+ SEV_GRAVE,
+ SEV_NORMAL,
+ SEV_WISH,
+ SEV_FEEDBACK
+ };
+}
+
+
+IMPLEMENT_DYNAMIC(CReportBugDlg, CDialog)
+
+CReportBugDlg::CReportBugDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CReportBugDlg::IDD, pParent)
+ , m_from(_T(""))
+ , m_to(_T(""))
+ , m_application(_T(""))
+ , m_platform(_T(""))
+ , m_hint(_T(""))
+ , m_severity(SEV_NORMAL)
+ , m_inAWord(_T(""))
+ , m_text(_T(""))
+ , m_layout(this, _T("rbdlg"))
+{
+}
+
+CReportBugDlg::~CReportBugDlg()
+{
+}
+
+void CReportBugDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ DDX_Text(pDX, IDC_FROM, m_from);
+ DDX_Text(pDX, IDC_TO, m_to);
+ DDX_Text(pDX, IDC_APPLICATION, m_application);
+ DDX_Text(pDX, IDC_PLATFORM, m_platform);
+ DDX_Text(pDX, IDC_HINT, m_hint);
+ DDX_Radio(pDX, IDC_CRITICAL, m_severity);
+ DDX_Text(pDX, IDC_INAWORD, m_inAWord);
+ DDX_Text(pDX, IDC_TEXT, m_text);
+}
+
+
+BEGIN_MESSAGE_MAP(CReportBugDlg, CDialog)
+ ON_BN_CLICKED(IDC_CRITICAL, OnBnClickedCritical)
+ ON_BN_CLICKED(IDC_GRAVE, OnBnClickedGrave)
+ ON_BN_CLICKED(IDC_NORMAL, OnBnClickedNormal)
+ ON_BN_CLICKED(IDC_WISH, OnBnClickedWish)
+ ON_BN_CLICKED(IDC_FEEDBACK, OnBnClickedFeedback)
+ ON_WM_SIZE()
+ ON_WM_GETMINMAXINFO()
+ ON_WM_DESTROY()
+END_MESSAGE_MAP()
+
+
+
+BOOL CReportBugDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ m_layout.AddControl(IDC_STATIC_TO, 1, 0, 0, 0);
+ m_layout.AddControl(IDC_STATIC_PLATFORM,1, 0, 0, 0);
+ m_layout.AddControl(IDC_TO, 1, 0, 0, 0);
+ m_layout.AddControl(IDC_PLATFORM, 1, 0, 0, 0);
+ m_layout.AddControl(IDC_STATIC_SEVERITY,0, 0, 1, 0);
+ m_layout.AddControl(IDC_CRITICAL, 0, 0, 0, 0);
+ m_layout.AddControl(IDC_GRAVE, 0.25, 0, 0, 0);
+ m_layout.AddControl(IDC_NORMAL, 0.50, 0, 0, 0);
+ m_layout.AddControl(IDC_WISH, 0.75, 0, 0, 0);
+ m_layout.AddControl(IDC_FEEDBACK, 1.0, 0, 0, 0);
+ m_layout.AddControl(IDC_INAWORD, 0, 0, 1, 0);
+ m_layout.AddControl(IDC_TEXT, 0, 0, 1, 1);
+ m_layout.AddControl(IDC_STATIC_OKHINT, 0, 1, 0, 0);
+ m_layout.AddControl(IDOK, 0.5, 1, 0, 0);
+ m_layout.AddControl(IDCANCEL, 1, 1, 0, 0);
+
+ m_layout.OnInitDialog(true);
+
+ m_from= GetUserName();
+ m_to= GetAuthorEmail();
+ m_application= CAboutDlg::GetAppVersion();
+ m_platform= GetOsPlatformString();
+
+ UpdateData(false);
+ OnSeverityClick();
+ return TRUE;
+}
+
+void CReportBugDlg::OnBnClickedCritical()
+{
+ OnSeverityClick();
+}
+
+void CReportBugDlg::OnBnClickedGrave()
+{
+ OnSeverityClick();
+}
+
+void CReportBugDlg::OnBnClickedNormal()
+{
+ OnSeverityClick();
+}
+
+void CReportBugDlg::OnBnClickedWish()
+{
+ OnSeverityClick();
+}
+
+void CReportBugDlg::OnBnClickedFeedback()
+{
+ OnSeverityClick();
+}
+
+void CReportBugDlg::OnSeverityClick()
+{
+ UpdateData();
+ switch (m_severity)
+ {
+ case SEV_CRITICAL:
+ case SEV_GRAVE:
+ case SEV_NORMAL:
+ m_hint.LoadString(IDS_BUGREPORTHINT);
+ break;
+ case SEV_WISH:
+ m_hint.Empty();
+ break;
+ case SEV_FEEDBACK:
+ m_hint.LoadString(IDS_FEEDBACKHINT);
+ break;
+ default:
+ ASSERT(0);
+ }
+
+ UpdateData(false);
+}
+
+
+void CReportBugDlg::OnOK()
+{
+ UpdateData();
+
+ m_recipient= m_to;
+ m_subject.Format(_T("%s - %s: %s"), m_application, GetSeverityString(), m_inAWord);
+ m_body.Empty();
+
+ CString s;
+
+ s.FormatMessage(IDS_FROMsPLATFORMs, m_from, m_platform);
+ m_body+= s;
+
+ s= m_text;
+ s.TrimLeft();
+ s.TrimRight();
+ s+= _T("\r\n");
+ m_body+= s;
+
+ CDialog::OnOK();
+}
+
+CString CReportBugDlg::GetSeverityString()
+{
+ CString s;
+
+ switch (m_severity)
+ {
+ case SEV_CRITICAL:
+ s.LoadString(IDS_SEV_CRITICAL);
+ break;
+ case SEV_GRAVE:
+ s.LoadString(IDS_SEV_GRAVE);
+ break;
+ case SEV_NORMAL:
+ s.LoadString(IDS_SEV_NORMAL);
+ break;
+ case SEV_WISH:
+ s.LoadString(IDS_SEV_WISH);
+ break;
+ case SEV_FEEDBACK:
+ s.LoadString(IDS_SEV_FEEDBACK);
+ break;
+ default:
+ ASSERT(0);
+ }
+
+ return s;
+}
+
+void CReportBugDlg::OnSize(UINT nType, int cx, int cy)
+{
+ CDialog::OnSize(nType, cx, cy);
+ m_layout.OnSize();
+}
+
+void CReportBugDlg::OnGetMinMaxInfo(MINMAXINFO* mmi)
+{
+ m_layout.OnGetMinMaxInfo(mmi);
+ CDialog::OnGetMinMaxInfo(mmi);
+}
+
+void CReportBugDlg::OnDestroy()
+{
+ m_layout.OnDestroy();
+ CDialog::OnDestroy();
+}
diff --git a/windirstat/ReportBugDlg.h b/windirstat/ReportBugDlg.h
new file mode 100644
index 0000000..fce237d
--- /dev/null
+++ b/windirstat/ReportBugDlg.h
@@ -0,0 +1,70 @@
+// reportbugdlg.h - Declaratino of CReportBugDlg
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "layout.h"
+
+
+class CReportBugDlg : public CDialog
+{
+ DECLARE_DYNAMIC(CReportBugDlg)
+ enum { IDD = IDD_REPORTBUG };
+
+public:
+ CReportBugDlg(CWnd* pParent = NULL);
+ virtual ~CReportBugDlg();
+
+ // [out]
+ CString m_recipient;
+ CString m_subject;
+ CString m_body;
+
+protected:
+ virtual BOOL OnInitDialog();
+ virtual void DoDataExchange(CDataExchange* pDX);
+ virtual void OnOK();
+ void OnSeverityClick();
+ CString GetSeverityString();
+
+ CString m_from;
+ CString m_to;
+ CString m_application;
+ CString m_platform;
+ CString m_hint;
+ int m_severity;
+ CString m_inAWord;
+ CString m_text;
+
+ CLayout m_layout;
+
+ DECLARE_MESSAGE_MAP()
+
+ afx_msg void OnBnClickedCritical();
+ afx_msg void OnBnClickedGrave();
+ afx_msg void OnBnClickedNormal();
+ afx_msg void OnBnClickedWish();
+ afx_msg void OnBnClickedFeedback();
+public:
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
+ afx_msg void OnDestroy();
+};
diff --git a/windirstat/SelectDrivesDlg.cpp b/windirstat/SelectDrivesDlg.cpp
new file mode 100644
index 0000000..e4761ed
--- /dev/null
+++ b/windirstat/SelectDrivesDlg.cpp
@@ -0,0 +1,556 @@
+// SelectDrivesDlg.cpp - Implementation of CDriveItem, CDrivesList and CSelectDrivesDlg
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include ".\selectdrivesdlg.h"
+
+namespace
+{
+ enum
+ {
+ COL_NAME,
+ COL_TOTAL,
+ COL_FREE,
+ COL_GRAPH,
+ COL_PERCENTUSED,
+ COLUMN_COUNT
+ };
+
+ const UINT WMU_OK = WM_USER + 100;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+CDriveItem::CDriveItem(CDrivesList *list, LPCTSTR pszPath)
+{
+ m_list= list;
+ m_path= pszPath;
+
+ m_name= FormatVolumeName(m_path);
+
+ MyGetDiskFreeSpace(m_path, m_totalBytes, m_freeBytes);
+
+ ASSERT(m_freeBytes <= m_totalBytes);
+ m_used= 0;
+ if (m_totalBytes > 0)
+ m_used= (double)(m_totalBytes - m_freeBytes) / m_totalBytes;
+
+ m_isRemote= (DRIVE_REMOTE == GetDriveType(m_path));
+}
+
+bool CDriveItem::IsRemote() const
+{
+ return m_isRemote;
+}
+
+int CDriveItem::Compare(const CSortingListItem *baseOther, int subitem) const
+{
+ const CDriveItem *other= (CDriveItem *)baseOther;
+
+ int r= 0;
+
+ switch (subitem)
+ {
+ case COL_NAME: r= GetPath().CompareNoCase(other->GetPath()); break;
+ case COL_TOTAL: r= signum(m_totalBytes - other->m_totalBytes); break;
+ case COL_FREE: r= signum(m_freeBytes - other->m_freeBytes); break;
+ case COL_GRAPH:
+ case COL_PERCENTUSED:
+ r= signum(m_used - other->m_used); break;
+ default:
+ ASSERT(0);
+ }
+
+ return r;
+}
+
+
+int CDriveItem::GetImage() const
+{
+ return GetMyImageList()->GetFileImage(m_path);
+}
+
+bool CDriveItem::DrawSubitem(int subitem, CDC *pdc, CRect rc, UINT state, int *width) const
+{
+ if (subitem == COL_NAME)
+ {
+ DrawLabel(m_list, GetMyImageList(), pdc, rc, state, width);
+ return true;
+ }
+ else if (subitem == COL_GRAPH)
+ {
+ if (width != NULL)
+ {
+ *width= 100;
+ return true;
+ }
+
+ rc.DeflateRect(3, 3);
+
+ CPen pen(PS_SOLID, 1, RGB(0,0,0));
+ CSelectObject sopen(pdc, &pen);
+
+ CSelectStockObject sobrush(pdc, NULL_BRUSH);
+ pdc->Rectangle(rc);
+
+ rc.DeflateRect(1, 1);
+
+ CRect rcLeft= rc;
+ rcLeft.right= rcLeft.left + (int)(m_used * rc.Width());
+ pdc->FillSolidRect(rcLeft, RGB(0,0,170));
+
+ CRect rcRight= rc;
+ rcRight.left= rcLeft.right;
+ pdc->FillSolidRect(rcRight, RGB(220,220,220));
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+CString CDriveItem::GetText(int subitem) const
+{
+ CString s= m_name;
+
+ switch (subitem)
+ {
+ case COL_NAME:
+ s= m_name;
+ break;
+
+ case COL_TOTAL:
+ s= FormatBytes((LONGLONG)m_totalBytes);
+ break;
+
+ case COL_FREE:
+ s= FormatBytes((LONGLONG)m_freeBytes);
+ break;
+
+ case COL_GRAPH:
+ break;
+
+ case COL_PERCENTUSED:
+ s= FormatDouble(m_used * 100) + _T("%");
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ return s;
+}
+
+CString CDriveItem::GetPath() const
+{
+ return m_path;
+}
+
+CString CDriveItem::GetDrive() const
+{
+ return m_path.Left(2);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_DYNAMIC(CDrivesList, COwnerDrawnListControl)
+
+CDrivesList::CDrivesList()
+: COwnerDrawnListControl(_T("drives"), 20)
+{
+}
+
+CDriveItem *CDrivesList::GetItem(int i)
+{
+ return (CDriveItem *)GetItemData(i);
+}
+
+bool CDrivesList::HasImages()
+{
+ return true;
+}
+
+void CDrivesList::SelectItem(CDriveItem *item)
+{
+ int i= FindListItem(item);
+ SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
+}
+
+bool CDrivesList::IsItemSelected(int i)
+{
+ return (LVIS_SELECTED == GetItemState(i, LVIS_SELECTED));
+}
+
+void CDrivesList::SelectAllLocalDrives()
+{
+ for (int i=0; i < GetItemCount(); i++)
+ {
+ CDriveItem *item= GetItem(i);
+ UINT state= item->IsRemote() ? 0 : LVIS_SELECTED;
+ SetItemState(i, LVIS_SELECTED, state);
+ }
+}
+
+void CDrivesList::OnLButtonDown(UINT /*nFlags*/, CPoint /*point*/)
+{
+ // We simulate Ctrl-Key-Down here, so that the dialog
+ // can be driven with one hand (mouse) only.
+ const MSG *msg= GetCurrentMessage();
+ DefWindowProc(msg->message, msg->wParam | MK_CONTROL, msg->lParam);
+}
+
+void CDrivesList::OnNMDblclk(NMHDR * /*pNMHDR*/, LRESULT *pResult)
+{
+ *pResult = 0;
+
+ CPoint point= GetCurrentMessage()->pt;
+ ScreenToClient(&point);
+ int i= HitTest(point);
+ if (i == -1)
+ return;
+
+ for (int k=0; k < GetItemCount(); k++)
+ SetItemState(k, k == i ? LVIS_SELECTED : 0, LVIS_SELECTED);
+
+ GetParent()->SendMessage(WMU_OK);
+}
+
+BEGIN_MESSAGE_MAP(CDrivesList, COwnerDrawnListControl)
+ ON_WM_LBUTTONDOWN()
+ ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnLvnDeleteitem)
+ ON_WM_MEASUREITEM_REFLECT()
+ ON_NOTIFY_REFLECT(NM_DBLCLK, OnNMDblclk)
+END_MESSAGE_MAP()
+
+void CDrivesList::OnLvnDeleteitem(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
+ delete GetItem(pNMLV->iItem);
+ *pResult = 0;
+}
+
+void CDrivesList::MeasureItem(LPMEASUREITEMSTRUCT mis)
+{
+ mis->itemHeight= GetRowHeight();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_DYNAMIC(CSelectDrivesDlg, CDialog)
+
+CSelectDrivesDlg::CSelectDrivesDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CSelectDrivesDlg::IDD, pParent)
+ , m_layout(this, _T("sddlg"))
+{
+}
+
+CSelectDrivesDlg::~CSelectDrivesDlg()
+{
+}
+
+void CSelectDrivesDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_DRIVES, m_list);
+ DDX_Radio(pDX, IDC_ALLDRIVES, m_radio);
+ DDX_Text(pDX, IDC_FOLDERNAME, m_folderName);
+ DDX_Control(pDX, IDOK, m_okButton);
+}
+
+
+BEGIN_MESSAGE_MAP(CSelectDrivesDlg, CDialog)
+ ON_BN_CLICKED(IDC_BROWSEFOLDER, OnBnClickedBrowsefolder)
+ ON_BN_CLICKED(IDC_AFOLDER, OnBnClickedAfolder)
+ ON_BN_CLICKED(IDC_SOMEDRIVES, OnBnClickedSomedrives)
+ ON_EN_CHANGE(IDC_FOLDERNAME, OnEnChangeFoldername)
+ ON_WM_MEASUREITEM()
+ ON_NOTIFY(LVN_ITEMCHANGED, IDC_DRIVES, OnLvnItemchangedDrives)
+ ON_BN_CLICKED(IDC_ALLLOCALDRIVES, OnBnClickedAlllocaldrives)
+ ON_WM_SIZE()
+ ON_WM_GETMINMAXINFO()
+ ON_WM_DESTROY()
+ ON_MESSAGE(WMU_OK, OnWmuOk)
+END_MESSAGE_MAP()
+
+
+BOOL CSelectDrivesDlg::OnInitDialog()
+{
+ CWaitCursor wc;
+
+ CDialog::OnInitDialog();
+
+ m_layout.AddControl(IDOK, 1, 0, 0, 0);
+ m_layout.AddControl(IDCANCEL, 1, 0, 0, 0);
+ m_layout.AddControl(IDC_DRIVES, 0, 0, 1, 1);
+ m_layout.AddControl(IDC_AFOLDER, 0, 1, 0, 0);
+ m_layout.AddControl(IDC_FOLDERNAME, 0, 1, 1, 0);
+ m_layout.AddControl(IDC_BROWSEFOLDER, 1, 1, 0, 0);
+
+ m_layout.OnInitDialog(true);
+
+ m_list.ShowGrid(true);
+
+ m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_HEADERDRAGDROP);
+ // If we set an ImageList here, OnMeasureItem will have no effect ?!
+
+ m_list.InsertColumn(COL_NAME, LoadString(IDS_DRIVECOL_NAME), LVCFMT_LEFT, 120, COL_NAME);
+ m_list.InsertColumn(COL_TOTAL, LoadString(IDS_DRIVECOL_TOTAL), LVCFMT_RIGHT, 120, COL_TOTAL);
+ m_list.InsertColumn(COL_FREE, LoadString(IDS_DRIVECOL_FREE), LVCFMT_RIGHT, 120, COL_FREE);
+ m_list.InsertColumn(COL_GRAPH, LoadString(IDS_DRIVECOL_GRAPH), LVCFMT_RIGHT, 120, COL_GRAPH);
+ m_list.InsertColumn(COL_PERCENTUSED,LoadString(IDS_DRIVECOL_PERCENTUSED),LVCFMT_RIGHT, 80, COL_PERCENTUSED);
+
+ m_list.OnColumnsInserted();
+
+ m_folderName= CPersistence::GetSelectDrivesFolder();
+ CPersistence::GetSelectDrivesDrives(m_selectedDrives);
+
+ ShowWindow(SW_SHOWNORMAL);
+ UpdateWindow();
+ BringWindowToTop();
+ SetForegroundWindow();
+
+ DWORD drives= GetLogicalDrives();
+ int i;
+ DWORD mask= 0x00000001;
+ for (i=0; i < 32; i++, mask <<= 1)
+ {
+ if ((drives & mask) != 0)
+ {
+ CString s;
+ s.Format(_T("%c:\\"), i + _T('A'));
+
+ UINT type= GetDriveType(s);
+ if (type == DRIVE_UNKNOWN || type == DRIVE_NO_ROOT_DIR)
+ {
+ continue;
+ }
+
+ if (!DriveExists(s))
+ {
+ continue;
+ }
+
+ CDriveItem *item= new CDriveItem(&m_list, s);
+ m_list.InsertListItem(m_list.GetItemCount(), item);
+ for (int col=0; col < COLUMN_COUNT; col++)
+ m_list.AdjustColumnWidth(col);
+ m_list.UpdateWindow();
+
+ for (int k=0; k < m_selectedDrives.GetSize(); k++)
+ {
+ if (item->GetDrive() == m_selectedDrives[k])
+ {
+ m_list.SelectItem(item);
+ break;
+ }
+ }
+ }
+ }
+
+ m_list.SortItems();
+
+ m_radio= CPersistence::GetSelectDrivesRadio();
+ UpdateData(false);
+
+ switch (m_radio)
+ {
+ case RADIO_ALLLOCALDRIVES:
+ case RADIO_AFOLDER:
+ m_okButton.SetFocus();
+ break;
+ case RADIO_SOMEDRIVES:
+ m_list.SetFocus();
+ break;
+ }
+
+ UpdateButtons();
+ return false; // we have set the focus.
+}
+
+void CSelectDrivesDlg::OnBnClickedBrowsefolder()
+{
+ CString sDisplayName;
+ BROWSEINFO bi;
+ ZeroMemory(&bi, sizeof(bi));
+
+ CString title= LoadString(IDS_SELECTFOLDER);
+ bi.hwndOwner= m_hWnd;
+ bi.pszDisplayName= sDisplayName.GetBuffer(_MAX_PATH);
+ bi.lpszTitle= title;
+ bi.ulFlags= BIF_RETURNONLYFSDIRS | BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_NONEWFOLDERBUTTON;
+
+ LPITEMIDLIST pidl= SHBrowseForFolder(&bi);
+ sDisplayName.ReleaseBuffer();
+
+ if (pidl != NULL)
+ {
+ CString sDir;
+
+ LPSHELLFOLDER pshf;
+ HRESULT hr= SHGetDesktopFolder(&pshf);
+ ASSERT(SUCCEEDED(hr));
+
+ STRRET strret;
+ strret.uType= STRRET_CSTR;
+ hr= pshf->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
+ ASSERT(SUCCEEDED(hr));
+ sDir= MyStrRetToString(pidl, &strret);
+
+ CoTaskMemFree(pidl);
+ pshf->Release();
+
+ m_folderName= sDir;
+ m_radio= RADIO_AFOLDER;
+ UpdateData(false);
+ UpdateButtons();
+ }
+}
+
+void CSelectDrivesDlg::OnOK()
+{
+ UpdateData();
+
+ m_drives.RemoveAll();
+ m_selectedDrives.RemoveAll();
+ if (m_radio != RADIO_AFOLDER)
+ {
+ for (int i=0; i < m_list.GetItemCount(); i++)
+ {
+ CDriveItem *item= m_list.GetItem(i);
+
+ if (m_radio == RADIO_ALLLOCALDRIVES && !item->IsRemote()
+ || m_radio == RADIO_SOMEDRIVES && m_list.IsItemSelected(i))
+ {
+ m_drives.Add(item->GetDrive());
+ if (m_list.IsItemSelected(i))
+ m_selectedDrives.Add(item->GetDrive());
+ }
+ }
+ }
+
+ CPersistence::SetSelectDrivesRadio(m_radio);
+ CPersistence::SetSelectDrivesFolder(m_folderName);
+ CPersistence::SetSelectDrivesDrives(m_selectedDrives);
+
+ CDialog::OnOK();
+}
+
+void CSelectDrivesDlg::UpdateButtons()
+{
+ UpdateData();
+ bool enableOk= false;
+ switch (m_radio)
+ {
+ case RADIO_ALLLOCALDRIVES:
+ enableOk= true;
+ break;
+ case RADIO_SOMEDRIVES:
+ enableOk= (m_list.GetSelectedCount() > 0);
+ break;
+ case RADIO_AFOLDER:
+ if (!m_folderName.IsEmpty())
+ {
+ CString pattern= m_folderName;
+ if (pattern.Right(1) != _T("\\"))
+ pattern+= _T("\\");
+ pattern+= _T("*.*");
+ CFileFind finder;
+ BOOL b= finder.FindFile(pattern);
+ enableOk= b;
+ }
+ break;
+ default:
+ ASSERT(0);
+ }
+ m_okButton.EnableWindow(enableOk);
+}
+
+void CSelectDrivesDlg::OnBnClickedAfolder()
+{
+ UpdateButtons();
+}
+
+void CSelectDrivesDlg::OnBnClickedSomedrives()
+{
+ m_list.SetFocus();
+ UpdateButtons();
+}
+
+void CSelectDrivesDlg::OnEnChangeFoldername()
+{
+ UpdateButtons();
+}
+
+void CSelectDrivesDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT mis)
+{
+ if (nIDCtl == IDC_DRIVES)
+ mis->itemHeight= 20;
+ else
+ CDialog::OnMeasureItem(nIDCtl, mis);
+}
+
+void CSelectDrivesDlg::OnLvnItemchangedDrives(NMHDR * /*pNMHDR*/, LRESULT *pResult)
+{
+ // unused: LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
+
+ m_radio= RADIO_SOMEDRIVES;
+
+ UpdateData(false);
+ UpdateButtons();
+
+ *pResult = 0;
+}
+
+void CSelectDrivesDlg::OnBnClickedAlllocaldrives()
+{
+ UpdateButtons();
+}
+
+void CSelectDrivesDlg::OnSize(UINT nType, int cx, int cy)
+{
+ CDialog::OnSize(nType, cx, cy);
+ m_layout.OnSize();
+}
+
+void CSelectDrivesDlg::OnGetMinMaxInfo(MINMAXINFO* mmi)
+{
+ m_layout.OnGetMinMaxInfo(mmi);
+ CDialog::OnGetMinMaxInfo(mmi);
+}
+
+void CSelectDrivesDlg::OnDestroy()
+{
+ m_layout.OnDestroy();
+ CDialog::OnDestroy();
+}
+
+LRESULT CSelectDrivesDlg::OnWmuOk(WPARAM, LPARAM)
+{
+ OnOK();
+ return 0;
+}
diff --git a/windirstat/SelectDrivesDlg.h b/windirstat/SelectDrivesDlg.h
new file mode 100644
index 0000000..df18cfe
--- /dev/null
+++ b/windirstat/SelectDrivesDlg.h
@@ -0,0 +1,133 @@
+// SelectDrivesDlg.h - Declaration of CDriveItem, CDrivesList and CSelectDrivesDlg
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "ownerdrawnlistcontrol.h"
+#include "layout.h"
+
+//
+// The dialog has these three radio buttons.
+//
+enum RADIO
+{
+ RADIO_ALLLOCALDRIVES,
+ RADIO_SOMEDRIVES,
+ RADIO_AFOLDER
+};
+
+
+class CDrivesList;
+
+//
+// CDriveItem. An item in the CDrivesList Control.
+//
+class CDriveItem: public COwnerDrawnListItem
+{
+public:
+ CDriveItem(CDrivesList *list, LPCTSTR pszPath);
+ virtual int Compare(const CSortingListItem *other, int subitem) const;
+
+ CString GetPath() const;
+ CString GetDrive() const;
+ bool IsRemote() const;
+ virtual bool DrawSubitem(int subitem, CDC *pdc, CRect rc, UINT state, int *width) const;
+ virtual CString GetText(int subitem) const;
+ int GetImage() const;
+
+private:
+ CDrivesList *m_list; // Backpointer
+ CString m_path; // e.g. "C:\"
+ CString m_name; // e.g. "BOOT (C:)"
+ LONGLONG m_totalBytes; // Capacity
+ LONGLONG m_freeBytes; // Free space
+ bool m_isRemote; // Whether the drive type is DRIVE_REMOTE (network drive)
+ double m_used; // used space / total space
+};
+
+
+//
+// CDrivesList.
+//
+class CDrivesList: public COwnerDrawnListControl
+{
+ DECLARE_DYNAMIC(CDrivesList)
+public:
+ CDrivesList();
+ CDriveItem *GetItem(int i);
+ void SelectItem(CDriveItem *item);
+ bool IsItemSelected(int i);
+ void SelectAllLocalDrives();
+
+ virtual bool HasImages();
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnLvnDeleteitem(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
+ afx_msg void OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult);
+};
+
+
+//
+// CSelectDrivesDlg. The initial dialog, where the user can select
+// one or more drives or a folder for scanning.
+//
+class CSelectDrivesDlg : public CDialog
+{
+ DECLARE_DYNAMIC(CSelectDrivesDlg)
+ enum { IDD = IDD_SELECTDRIVES };
+
+public:
+ CSelectDrivesDlg(CWnd* pParent = NULL);
+ virtual ~CSelectDrivesDlg();
+
+ // Dialog Data
+ int m_radio; // out.
+ CString m_folderName; // out. Valid if m_radio = RADIO_AFOLDER
+ CStringArray m_drives; // out. Valid if m_radio != RADIO_AFOLDER
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX);
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+
+ void UpdateButtons();
+
+ CDrivesList m_list;
+ CButton m_okButton;
+ CStringArray m_selectedDrives;
+ CLayout m_layout;
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnBnClickedBrowsefolder();
+ afx_msg void OnLbnSelchangeDrives();
+ afx_msg void OnBnClickedAlllocaldrives();
+ afx_msg void OnBnClickedAfolder();
+ afx_msg void OnBnClickedSomedrives();
+ afx_msg void OnEnChangeFoldername();
+ afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct);
+ afx_msg void OnLvnItemchangedDrives(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
+ afx_msg void OnDestroy();
+ afx_msg LRESULT OnWmuOk(WPARAM, LPARAM);
+};
diff --git a/windirstat/TreeListControl.cpp b/windirstat/TreeListControl.cpp
new file mode 100644
index 0000000..5c172e5
--- /dev/null
+++ b/windirstat/TreeListControl.cpp
@@ -0,0 +1,798 @@
+// TreeListControl.cpp - Implementation of CTreeListItem and CTreeListControl
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include ".\treelistcontrol.h"
+
+namespace
+{
+ // Sequence within IDB_NODES
+ enum
+ {
+ NODE_PLUS_SIBLING,
+ NODE_PLUS_END,
+ NODE_MINUS_SIBLING,
+ NODE_MINUS_END,
+ NODE_SIBLING,
+ NODE_END,
+ NODE_LINE
+ };
+ const UINT NODE_WIDTH = 15; // Width of a node within IDB_NODES
+ const UINT NODE_HEIGHT = 24; // Height of IDB_NODES
+ const UINT INDENT_WIDTH = 18;
+
+ const UINT HOTNODE_CX = 9; // Size and position of the +/- buttons
+ const UINT HOTNODE_CY = 9;
+ const UINT HOTNODE_X = 0;
+
+}
+
+CTreeListItem::CTreeListItem()
+{
+ m_parent= NULL;
+ m_vi= NULL;
+}
+
+CTreeListItem::~CTreeListItem()
+{
+ delete m_vi;
+}
+
+bool CTreeListItem::DrawSubitem(int subitem, CDC *pdc, CRect rc, UINT state, int *width) const
+{
+ if (subitem != 0)
+ return false;
+
+ CRect rcNode= rc;
+ CRect rcPlusMinus;
+ GetTreeListControl()->DrawNode(pdc, rcNode, rcPlusMinus, this, width);
+
+ CRect rcLabel= rc;
+ rcLabel.left= rcNode.right;
+ DrawLabel(GetTreeListControl(), GetMyImageList(), pdc, rcLabel, state, width, false);
+
+ if (width != NULL)
+ {
+ *width= rcLabel.right - rc.left;
+ }
+ else
+ {
+ SetPlusMinusRect(rcPlusMinus - rc.TopLeft());
+ SetTitleRect(rcLabel - rc.TopLeft());
+ }
+
+ return true;
+}
+
+CString CTreeListItem::GetText(int /*subitem*/) const
+{
+ return _T("test");
+}
+
+int CTreeListItem::GetImage() const
+{
+ ASSERT(IsVisible());
+ if (m_vi->image == -1)
+ m_vi->image= GetImageToCache();
+ return m_vi->image;
+}
+
+void CTreeListItem::DrawPacman(CDC *pdc, const CRect& rc) const
+{
+ ASSERT(IsVisible());
+ m_vi->pacman.Draw(pdc, rc);
+}
+
+void CTreeListItem::StartPacman(bool start)
+{
+ if (IsVisible())
+ m_vi->pacman.Start(start);
+}
+
+bool CTreeListItem::DrivePacman(LONGLONG readJobs)
+{
+ if (!IsVisible())
+ return false;
+
+ return m_vi->pacman.Drive(readJobs);
+}
+
+int CTreeListItem::GetScrollPosition()
+{
+ return GetTreeListControl()->GetItemScrollPosition(this);
+}
+
+void CTreeListItem::SetScrollPosition(int top)
+{
+ GetTreeListControl()->SetItemScrollPosition(this, top);
+}
+
+void CTreeListItem::UncacheImage()
+{
+ if (IsVisible())
+ m_vi->image= -1;
+}
+
+void CTreeListItem::SortChildren()
+{
+ ASSERT(IsVisible());
+ m_vi->sortedChildren.SetSize(GetChildrenCount());
+ for (int i=0; i < GetChildrenCount(); i++)
+ m_vi->sortedChildren[i]= GetTreeListChild(i);
+
+ qsort(m_vi->sortedChildren.GetData(), m_vi->sortedChildren.GetSize(), sizeof(CTreeListItem *), &_compareProc);
+}
+
+int __cdecl CTreeListItem::_compareProc(const void *p1, const void *p2)
+{
+ CTreeListItem *item1= *(CTreeListItem **)p1;
+ CTreeListItem *item2= *(CTreeListItem **)p2;
+ return item1->CompareS(item2, GetTreeListControl()->GetSorting());
+}
+
+CTreeListItem *CTreeListItem::GetSortedChild(int i)
+{
+ return m_vi->sortedChildren[i];
+}
+
+int CTreeListItem::Compare(const CSortingListItem *baseOther, int subitem) const
+{
+ CTreeListItem *other= (CTreeListItem *)baseOther;
+
+ if (other == this)
+ return 0;
+
+ if (m_parent == other->m_parent)
+ return CompareSibling(other, subitem);
+
+ if (m_parent == NULL)
+ return -2;
+
+ if (other->m_parent == NULL)
+ return 2;
+
+ if (GetIndent() < other->GetIndent())
+ return Compare(other->m_parent, subitem);
+ else if (GetIndent() > other->GetIndent())
+ return m_parent->Compare(other, subitem);
+ else
+ return m_parent->Compare(other->m_parent, subitem);
+}
+
+int CTreeListItem::FindSortedChild(const CTreeListItem *child)
+{
+ for (int i=0; i < GetChildrenCount(); i++)
+ if (child == GetSortedChild(i))
+ return i;
+ ASSERT(0);
+ return 0;
+}
+CTreeListItem *CTreeListItem::GetParent() const
+{
+ return m_parent;
+}
+void CTreeListItem::SetParent(CTreeListItem *parent)
+{
+ m_parent= parent;
+}
+bool CTreeListItem::HasSiblings() const
+{
+ if (m_parent == NULL)
+ return false;
+ int i= m_parent->FindSortedChild(this);
+ return i < m_parent->GetChildrenCount() - 1;
+}
+bool CTreeListItem::HasChildren() const
+{
+ return GetChildrenCount() > 0;
+}
+bool CTreeListItem::IsExpanded() const
+{
+ ASSERT(IsVisible());
+ return m_vi->isExpanded;
+}
+void CTreeListItem::SetExpanded(bool expanded)
+{
+ ASSERT(IsVisible());
+ m_vi->isExpanded= expanded;
+}
+bool CTreeListItem::IsVisible() const
+{
+ return (m_vi != NULL);
+}
+void CTreeListItem::SetVisible(bool visible)
+{
+ if (visible)
+ {
+ ASSERT(!IsVisible());
+ m_vi= new VISIBLEINFO;
+ if (GetParent() == NULL)
+ m_vi->indent= 0;
+ else
+ m_vi->indent= GetParent()->GetIndent() + 1;
+ m_vi->image= -1;
+ m_vi->isExpanded= false;
+ }
+ else
+ {
+ ASSERT(IsVisible());
+ delete m_vi;
+ m_vi= NULL;
+ }
+}
+int CTreeListItem::GetIndent() const
+{
+ ASSERT(IsVisible());
+ return m_vi->indent;
+}
+CRect CTreeListItem::GetPlusMinusRect() const
+{
+ ASSERT(IsVisible());
+ return m_vi->rcPlusMinus;
+}
+void CTreeListItem::SetPlusMinusRect(const CRect& rc) const
+{
+ ASSERT(IsVisible());
+ m_vi->rcPlusMinus= rc;
+}
+CRect CTreeListItem::GetTitleRect() const
+{
+ ASSERT(IsVisible());
+ return m_vi->rcTitle;
+}
+void CTreeListItem::SetTitleRect(const CRect& rc) const
+{
+ ASSERT(IsVisible());
+ m_vi->rcTitle= rc;
+}
+
+CTreeListControl *CTreeListItem::GetTreeListControl()
+{
+ // As we only have 1 TreeListControl and want to economize memory
+ // we simple made the TreeListControl global.
+ return CTreeListControl::GetTheTreeListControl();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CTreeListControl
+
+CTreeListControl *CTreeListControl::_theTreeListControl;
+
+CTreeListControl *CTreeListControl::GetTheTreeListControl()
+{
+ ASSERT(_theTreeListControl != NULL);
+ return _theTreeListControl;
+}
+
+
+IMPLEMENT_DYNAMIC(CTreeListControl, COwnerDrawnListControl)
+
+CTreeListControl::CTreeListControl(int rowHeight)
+: COwnerDrawnListControl(_T("treelist"), rowHeight)
+{
+ ASSERT(_theTreeListControl == NULL);
+ _theTreeListControl= this;
+
+ ASSERT(rowHeight <= NODE_HEIGHT); // größer können wir nicht
+ ASSERT(rowHeight % 2 == 0); // muss gerade sein
+}
+
+CTreeListControl::~CTreeListControl()
+{
+}
+
+bool CTreeListControl::HasImages()
+{
+ return true;
+}
+void CTreeListControl::MySetImageList(CImageList *il)
+{
+ m_imageList= il;
+}
+
+void CTreeListControl::SelectItem(int i)
+{
+ SetItemState(i, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
+ EnsureVisible(i, false);
+}
+
+void CTreeListControl::SelectItem(const CTreeListItem *item)
+{
+ int i= FindTreeItem(item);
+ if (i != -1)
+ SelectItem(i);
+}
+
+BOOL CTreeListControl::CreateEx(DWORD dwExStyle, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
+{
+ COLORMAP cm[1] = {
+ { RGB(255,0,255), GetSysColor(COLOR_WINDOW) }
+ };
+ VERIFY(m_bmNodes.LoadMappedBitmap(IDB_NODES, 0, cm, 1));
+
+ dwStyle|= LVS_OWNERDRAWFIXED | LVS_SINGLESEL;
+ VERIFY(COwnerDrawnListControl::CreateEx(dwExStyle, dwStyle, rect, pParentWnd, nID));
+ return true;
+}
+
+CTreeListItem *CTreeListControl::GetItem(int i)
+{
+ CTreeListItem *item= (CTreeListItem *)GetItemData(i);
+ return item;
+}
+
+void CTreeListControl::SetRootItem(CTreeListItem *root)
+{
+ DeleteAllItems();
+
+ if (root != NULL)
+ {
+ InsertItem(0, root);
+ ExpandItem(0);
+ }
+}
+
+void CTreeListControl::DeselectAll()
+{
+ for (int i=0; i < GetItemCount(); i++)
+ SetItemState(i, 0, LVIS_SELECTED);
+}
+
+void CTreeListControl::SelectAndShowItem(const CTreeListItem *item, bool showWholePath)
+{
+ if (item == NULL)
+ return;
+
+ CArray<const CTreeListItem *, const CTreeListItem *> path;
+ const CTreeListItem *p= item;
+ while (p != NULL)
+ {
+ path.Add(p);
+ p= p->GetParent();
+ }
+
+ int parent= 0;
+ for (int i=path.GetSize() - 1; i >= 0; i--)
+ {
+ int index= FindTreeItem(path[i]);
+ if (index == -1)
+ {
+ ASSERT(i < path.GetSize() - 1);
+ ExpandItem(parent, false);
+ index= FindTreeItem(path[i]);
+ }
+ else
+ {
+ for (int k=parent+1; k < index; k++)
+ {
+ CollapseItem(k);
+ index= FindTreeItem(path[i]);
+ }
+ }
+ parent= index;
+ }
+
+ i= FindTreeItem(path[0]);
+
+ int w= GetSubItemWidth(GetItem(i), 0) + 5;
+ if (GetColumnWidth(0) < w)
+ SetColumnWidth(0, w);
+
+ if (showWholePath)
+ EnsureVisible(0, false);
+
+ SelectItem(i);
+}
+
+void CTreeListControl::InsertItem(int i, CTreeListItem *item)
+{
+ COwnerDrawnListControl::InsertListItem(i, item);
+ item->SetVisible(true);
+}
+
+void CTreeListControl::DeleteItem(int i)
+{
+ GetItem(i)->SetExpanded(false);
+ GetItem(i)->SetVisible(false);
+ COwnerDrawnListControl::DeleteItem(i);
+}
+
+int CTreeListControl::FindTreeItem(const CTreeListItem *item)
+{
+ return COwnerDrawnListControl::FindListItem(item);
+}
+
+BEGIN_MESSAGE_MAP(CTreeListControl, COwnerDrawnListControl)
+ ON_WM_MEASUREITEM_REFLECT()
+ ON_WM_LBUTTONDOWN()
+ ON_WM_KEYDOWN()
+ ON_WM_LBUTTONDBLCLK()
+ ON_WM_DESTROY()
+END_MESSAGE_MAP()
+
+
+void CTreeListControl::DrawNode(CDC *pdc, CRect& rc, CRect& rcPlusMinus, const CTreeListItem *item, int *width)
+{
+ CRect rcRest= rc;
+ rcRest.left+= GetGeneralLeftIndent();
+ if (item->GetIndent() > 0)
+ {
+ rcRest.left+= 3;
+
+ CDC dcmem;
+ dcmem.CreateCompatibleDC(pdc);
+ CSelectObject sonodes(&dcmem, &m_bmNodes);
+
+ int ysrc= NODE_HEIGHT / 2 - GetRowHeight() / 2;
+
+ if (width == NULL)
+ {
+ const CTreeListItem *ancestor= item;
+ for (int indent=item->GetIndent() - 2; indent >= 0; indent--)
+ {
+ ancestor= ancestor->GetParent();
+ if (ancestor->HasSiblings())
+ {
+ pdc->BitBlt(rcRest.left + indent * INDENT_WIDTH, rcRest.top, NODE_WIDTH, NODE_HEIGHT, &dcmem, NODE_WIDTH * NODE_LINE, ysrc, SRCCOPY);
+ }
+ }
+ }
+
+ rcRest.left+= (item->GetIndent() - 1) * INDENT_WIDTH;
+
+ if (width == NULL)
+ {
+ int node;
+ if (item->HasChildren())
+ if (item->HasSiblings())
+ if (item->IsExpanded())
+ node= NODE_MINUS_SIBLING;
+ else
+ node= NODE_PLUS_SIBLING;
+ else
+ if (item->IsExpanded())
+ node= NODE_MINUS_END;
+ else
+ node= NODE_PLUS_END;
+ else
+ if (item->HasSiblings())
+ node= NODE_SIBLING;
+ else
+ node= NODE_END;
+
+ pdc->BitBlt(rcRest.left, rcRest.top, NODE_WIDTH, NODE_HEIGHT, &dcmem, NODE_WIDTH * node, ysrc, SRCCOPY);
+
+ rcPlusMinus.left = rcRest.left + HOTNODE_X;
+ rcPlusMinus.right = rcPlusMinus.left + HOTNODE_CX;
+ rcPlusMinus.top = rcRest.top + rcRest.Height() / 2 - HOTNODE_CY / 2 - 1;
+ rcPlusMinus.bottom = rcPlusMinus.top + HOTNODE_CY;
+ }
+ rcRest.left+= NODE_WIDTH;
+ }
+
+ rc.right= rcRest.left;
+
+ if (width != NULL)
+ *width= rc.Width();
+}
+
+void CTreeListControl::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ LVHITTESTINFO hti;
+ ZeroMemory(&hti, sizeof(hti));
+ hti.pt= point;
+
+ int i= HitTest(&hti);
+ if (i == -1)
+ return;
+
+ if (hti.iSubItem != 0)
+ {
+ COwnerDrawnListControl::OnLButtonDown(nFlags, point);
+ return;
+ }
+
+ CRect rc= GetWholeSubitemRect(i, 0);
+ CPoint pt= point - rc.TopLeft();
+
+ CTreeListItem *item= GetItem(i);
+
+ if (item->GetPlusMinusRect().PtInRect(pt))
+ ToggleExpansion(i);
+ else
+ COwnerDrawnListControl::OnLButtonDown(nFlags, point);
+}
+
+void CTreeListControl::ToggleExpansion(int i)
+{
+ if (GetItem(i)->IsExpanded())
+ CollapseItem(i);
+ else
+ ExpandItem(i);
+}
+
+void CTreeListControl::CollapseItem(int i)
+{
+ CTreeListItem *item= GetItem(i);
+ if (!item->IsExpanded())
+ return;
+
+ CWaitCursor wc;
+ LockWindowUpdate();
+ bool selectNode= false;
+ int todelete= 0;
+ for (int k=i+1; k < GetItemCount(); k++)
+ {
+ CTreeListItem *child= GetItem(k);
+ if (child->GetIndent() <= item->GetIndent())
+ break;
+ if (GetItemState(k, LVIS_SELECTED) == LVIS_SELECTED)
+ selectNode= true;
+ todelete++;
+ }
+ for (int m=0; m < todelete; m++)
+ DeleteItem(i + 1);
+ item->SetExpanded(false);
+ if (selectNode)
+ SelectItem(i);
+ UnlockWindowUpdate();
+ RedrawItems(i, i);
+}
+
+int CTreeListControl::GetItemScrollPosition(CTreeListItem *item)
+{
+ CRect rc;
+ VERIFY(GetItemRect(FindTreeItem(item), rc, LVIR_BOUNDS));
+ return rc.top;
+}
+
+void CTreeListControl::SetItemScrollPosition(CTreeListItem *item, int top)
+{
+ int old= GetItemScrollPosition(item);
+ Scroll(CSize(0, top - old));
+}
+
+void CTreeListControl::ExpandItem(CTreeListItem *item)
+{
+ ExpandItem(FindTreeItem(item), false);
+}
+
+void CTreeListControl::ExpandItem(int i, bool scroll)
+{
+ CTreeListItem *item= GetItem(i);
+ if (item->IsExpanded())
+ return;
+
+ CWaitCursor wc; // TODO: smart WaitCursor. In CollapseItem(), too.
+ LockWindowUpdate();
+
+ item->SortChildren();
+
+ int maxwidth= GetSubItemWidth(item, 0);
+ for (int c=0; c < item->GetChildrenCount(); c++)
+ {
+ CTreeListItem *child= item->GetSortedChild(c);
+ InsertItem(i + 1 + c, child);
+ if (scroll)
+ {
+ int w= GetSubItemWidth(child, 0);
+ if (w > maxwidth)
+ maxwidth= w;
+ }
+ }
+
+ if (scroll && GetColumnWidth(0) < maxwidth)
+ SetColumnWidth(0, maxwidth);
+
+ item->SetExpanded(true);
+ UnlockWindowUpdate();
+ RedrawItems(i, i);
+
+ if (scroll)
+ {
+#if 0
+ EnsureVisible(i, false);
+#elif 1
+ // Scroll up so far, that i is still visible
+ // and the first child becomes visible, if possible.
+ if (item->GetChildrenCount() > 0)
+ EnsureVisible(i + 1, false);
+ EnsureVisible(i, false);
+#elif 0
+ // Scroll up so far, that i is still visible
+ // and the last child becomes visible, if possible.
+
+ CRect rcClient;
+ GetClientRect(rcClient);
+
+ CRect rcLastChild;
+ VERIFY(GetItemRect(i + item->GetChildrenCount(), rcLastChild, LVIR_BOUNDS));
+
+ int cy= rcLastChild.bottom - rcClient.bottom;
+ if (cy < 0)
+ return;
+
+ CRect rcHeader;
+ GetHeaderCtrl()->GetWindowRect(rcHeader);
+ ScreenToClient(rcHeader);
+
+ CRect rcParent;
+ VERIFY(GetItemRect(i, rcParent, LVIR_BOUNDS));
+
+ int cymax= rcParent.top - rcHeader.bottom;
+ if (cymax < 0)
+ return;
+
+ if (cy > cymax)
+ cy= cymax;
+
+ Scroll(CSize(0, cy));
+#endif
+ }
+
+}
+
+void CTreeListControl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ int i= GetNextItem(-1, LVNI_FOCUSED);
+ if (i != -1)
+ {
+ CTreeListItem *item= GetItem(i);
+ switch (nChar)
+ {
+ case VK_LEFT:
+ if (item->IsExpanded())
+ {
+ CollapseItem(i);
+ }
+ else if (item->GetParent() != NULL)
+ {
+ SelectItem(item->GetParent());
+ }
+ return;
+
+ case VK_RIGHT:
+ if (!item->IsExpanded())
+ {
+ ExpandItem(i);
+ }
+ else if (item->GetChildrenCount() > 0)
+ {
+ SelectItem(item->GetSortedChild(0));
+ }
+ return;
+ }
+ }
+ COwnerDrawnListControl::OnKeyDown(nChar, nRepCnt, nFlags);
+}
+
+void CTreeListControl::OnLButtonDblClk(UINT nFlags, CPoint point)
+{
+ LVHITTESTINFO hti;
+ ZeroMemory(&hti, sizeof(hti));
+ hti.pt= point;
+
+ int i= HitTest(&hti);
+ if (i == -1)
+ return;
+
+ if (hti.iSubItem != 0)
+ return;
+
+ CRect rc;
+ GetItemRect(i, rc, LVIR_BOUNDS);
+ CPoint pt= point - rc.TopLeft();
+
+ CTreeListItem *item= GetItem(i);
+
+ if (item->GetTitleRect().PtInRect(pt))
+ {
+ COwnerDrawnListControl::OnLButtonDblClk(nFlags, point);
+ ToggleExpansion(i);
+ }
+ else if (item->GetPlusMinusRect().PtInRect(pt))
+ {
+ ToggleExpansion(i);
+ }
+}
+
+void CTreeListControl::OnChildAdded(CTreeListItem *parent, CTreeListItem *child)
+{
+ if (!parent->IsVisible())
+ return;
+
+ int p= FindTreeItem(parent);
+ ASSERT(p != -1);
+
+ if (parent->IsExpanded())
+ {
+ InsertItem(p + 1, child);
+ RedrawItems(p, p);
+ Sort();
+ }
+ else
+ {
+ RedrawItems(p, p);
+ }
+}
+
+void CTreeListControl::OnChildRemoved(CTreeListItem *parent, CTreeListItem *child)
+{
+ if (!parent->IsVisible())
+ return;
+
+ int p= FindTreeItem(parent);
+ ASSERT(p != -1);
+
+ if (parent->IsExpanded())
+ {
+ for (int i=0; i < child->GetChildrenCount(); i++)
+ {
+ OnChildRemoved(child, child->GetTreeListChild(i));
+ }
+
+ int c= FindTreeItem(child);
+ ASSERT(c != -1);
+ COwnerDrawnListControl::DeleteItem(c);
+ parent->SortChildren();
+ }
+
+ RedrawItems(p, p);
+}
+
+void CTreeListControl::OnRemovingAllChildren(CTreeListItem *parent)
+{
+ if (!parent->IsVisible())
+ return;
+
+ int p= FindTreeItem(parent);
+ ASSERT(p != -1);
+
+ CollapseItem(p);
+}
+
+void CTreeListControl::Sort()
+{
+ for (int i=0; i < GetItemCount(); i++)
+ {
+ if (GetItem(i)->IsExpanded())
+ GetItem(i)->SortChildren();
+ }
+ COwnerDrawnListControl::SortItems();
+}
+
+void CTreeListControl::EnsureItemVisible(const CTreeListItem *item)
+{
+ if (item == NULL)
+ return;
+ int i= FindTreeItem(item);
+ if (i == -1)
+ return;
+ EnsureVisible(i, false);
+}
+
+void CTreeListControl::MeasureItem(LPMEASUREITEMSTRUCT mis)
+{
+ mis->itemHeight= GetRowHeight();
+}
+
diff --git a/windirstat/TreeListControl.h b/windirstat/TreeListControl.h
new file mode 100644
index 0000000..c7d24f3
--- /dev/null
+++ b/windirstat/TreeListControl.h
@@ -0,0 +1,160 @@
+// TreeListControl.h - Declaration of CTreeListItem and CTreeListControl
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "ownerdrawnlistcontrol.h"
+#include "pacman.h"
+
+class CTreeListItem;
+class CTreeListControl;
+
+
+//
+// CTreeListItem. An item in the CTreeListControl. (CItem is derived from CTreeListItem.)
+// In order to save memory, once the item is actually inserted in the List,
+// we allocate the VISIBLEINFO structure (m_vi).
+// m_vi is freed as soon as the item is removed from the List.
+//
+class CTreeListItem: public COwnerDrawnListItem
+{
+ // Data needed to display the item.
+ struct VISIBLEINFO
+ {
+ int indent; // 0 for the root item, 1 for its children, and so on.
+ int image; // -1 as long as not needed, >= 0: valid index in MyImageList.
+ CRect rcPlusMinus; // Coordinates of the little +/- rectangle, relative to the upper left corner of the item.
+ CRect rcTitle; // Coordinates of the label, relative to the upper left corner of the item.
+ bool isExpanded; // Whether item is expanded.
+
+ // sortedChildren: This member contains our children (the same set of
+ // children as in CItem::m_children) and is initialized as soon as
+ // we are expanded. In contrast to CItem::m_children, this array is always
+ // sorted depending on the current user-defined sort column and -order.
+ CArray<CTreeListItem *, CTreeListItem *> sortedChildren;
+
+ CPacman pacman;
+ };
+
+public:
+ CTreeListItem();
+ virtual ~CTreeListItem();
+
+ virtual int CompareSibling(const CTreeListItem *tlib, int subitem) const =0;
+
+ virtual bool DrawSubitem(int subitem, CDC *pdc, CRect rc, UINT state, int *width) const;
+ virtual CString GetText(int subitem) const;
+ virtual int GetImage() const;
+ virtual int Compare(const CSortingListItem *other, int subitem) const;
+ virtual CTreeListItem *GetTreeListChild(int i) const =0;
+ virtual int GetChildrenCount() const =0;
+ virtual int GetImageToCache() const =0;
+
+ void DrawPacman(CDC *pdc, const CRect& rc) const;
+ void UncacheImage();
+ void SortChildren();
+ CTreeListItem *GetSortedChild(int i);
+ int FindSortedChild(const CTreeListItem *child);
+ CTreeListItem *GetParent() const;
+ void SetParent(CTreeListItem *parent);
+ bool HasSiblings() const;
+ bool HasChildren() const;
+ bool IsExpanded() const;
+ void SetExpanded(bool expanded =true);
+ bool IsVisible() const;
+ void SetVisible(bool visible =true);
+ int GetIndent() const;
+ CRect GetPlusMinusRect() const;
+ void SetPlusMinusRect(const CRect& rc) const;
+ CRect GetTitleRect() const;
+ void SetTitleRect(const CRect& rc) const;
+
+protected:
+ static int __cdecl _compareProc(const void *p1, const void *p2);
+ static CTreeListControl *GetTreeListControl();
+ void StartPacman(bool start);
+ bool DrivePacman(LONGLONG readJobs);
+ int GetScrollPosition();
+ void SetScrollPosition(int top);
+
+private:
+ CTreeListItem *m_parent;
+ mutable VISIBLEINFO *m_vi;
+};
+
+
+//
+// CTreeListControl. A CListCtrl, which additionally behaves an looks like a tree control.
+//
+class CTreeListControl: public COwnerDrawnListControl
+{
+ DECLARE_DYNAMIC(CTreeListControl)
+
+ // In order to save memory, and as we have only one CTreeListControl in the application,
+ // this is global.
+ static CTreeListControl *_theTreeListControl;
+
+public:
+ static CTreeListControl *GetTheTreeListControl();
+
+ CTreeListControl(int rowHeight = -1);
+ virtual ~CTreeListControl();
+ void MySetImageList(CImageList *il);
+ virtual BOOL CreateEx(DWORD dwExStyle, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
+ void SetRootItem(CTreeListItem *root);
+ void OnChildAdded(CTreeListItem *parent, CTreeListItem *child);
+ void OnChildRemoved(CTreeListItem *parent, CTreeListItem *childdata);
+ void OnRemovingAllChildren(CTreeListItem *parent);
+ CTreeListItem *GetItem(int i);
+ void DeselectAll();
+ void SelectAndShowItem(const CTreeListItem *item, bool showWholePath);
+ void DrawNode(CDC *pdc, CRect& rc, CRect& rcPlusMinus, const CTreeListItem *item, int *width);
+ void SelectItem(const CTreeListItem *item);
+ void Sort();
+ void EnsureItemVisible(const CTreeListItem *item);
+ void ExpandItem(CTreeListItem *item);
+ int FindTreeItem(const CTreeListItem *item);
+ int GetItemScrollPosition(CTreeListItem *item);
+ void SetItemScrollPosition(CTreeListItem *item, int top);
+
+ virtual bool HasImages();
+
+protected:
+ void InsertItem(int i, CTreeListItem *item);
+ void DeleteItem(int i);
+ void CollapseItem(int i);
+ void ExpandItem(int i, bool scroll = true);
+ void ToggleExpansion(int i);
+ void SelectItem(int i);
+
+ CBitmap m_bmNodes; // The bitmaps needed to draw the treecontrol-like branches
+ CImageList *m_imageList; // We don't use the system-supplied SetImageList(), but MySetImageList().
+
+ DECLARE_MESSAGE_MAP()
+
+ afx_msg void MeasureItem(LPMEASUREITEMSTRUCT mis);
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+};
+
+
diff --git a/windirstat/aboutdlg.cpp b/windirstat/aboutdlg.cpp
new file mode 100644
index 0000000..a844a93
--- /dev/null
+++ b/windirstat/aboutdlg.cpp
@@ -0,0 +1,269 @@
+// aboutdlg.cpp - Implementation of the StartAboutDialog() function
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include ".\aboutdlg.h"
+
+namespace
+{
+ enum
+ {
+ RE_CONTROL = 4711 // Id of the RichEdit Control
+ };
+
+ // Tabs
+ enum
+ {
+ TAB_ABOUT,
+ TAB_THANKSTO,
+ TAB_LICENSE
+ };
+
+ // Retrieve the GPL text from our resources
+ CString GetTextResource(UINT id)
+ {
+ CString s;
+
+ HGLOBAL hresource = NULL;
+ try
+ {
+ HRSRC hrsrc= FindResource(NULL, MAKEINTRESOURCE(id), _T("TEXT"));
+ if (hrsrc == NULL)
+ MdThrowLastWinerror();
+
+ DWORD dwSize= SizeofResource(AfxGetInstanceHandle(), hrsrc);
+ if (dwSize == 0)
+ MdThrowLastWinerror();
+
+ hresource= LoadResource(NULL, hrsrc);
+ const BYTE *pData= (const BYTE *)LockResource(hresource);
+
+ CComBSTR bstr(dwSize, (LPCSTR)pData);
+
+ s= bstr;
+ }
+ catch (CException *pe)
+ {
+ pe->ReportError();
+ pe->Delete();
+ }
+
+ if (hresource != NULL)
+ FreeResource(hresource);
+
+ return s;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void StartAboutDialog()
+{
+ AfxBeginThread(RUNTIME_CLASS(CAboutThread), NULL);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_DYNCREATE(CAboutThread, CWinThread);
+
+BOOL CAboutThread::InitInstance()
+{
+ CWinThread::InitInstance();
+
+ CAboutDlg dlg;
+ dlg.DoModal();
+ return false;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CAboutDlg::CMyTabControl::Initialize()
+{
+ ModifyStyle(0, WS_CLIPCHILDREN);
+
+ InsertItem(TAB_ABOUT, LoadString(IDS_ABOUT_ABOUT));
+ InsertItem(TAB_THANKSTO, LoadString(IDS_ABOUT_THANKSTO));
+ InsertItem(TAB_LICENSE, LoadString(IDS_ABOUT_LICENSEAGREEMENT));
+
+ CRect rc;
+ GetClientRect(rc);
+
+ CRect rcItem;
+ GetItemRect(0, rcItem);
+
+ rc.top= rcItem.bottom;
+
+ VERIFY(m_text.CreateEx(0, WS_CHILD|WS_VISIBLE|WS_BORDER | ES_CENTER|ES_MULTILINE|ES_READONLY, rc, this, RE_CONTROL));
+ SetPageText(TAB_ABOUT);
+}
+
+void CAboutDlg::CMyTabControl::SetPageText(int tab)
+{
+ CString text;
+ DWORD newStyle= ES_CENTER;
+
+ switch (tab)
+ {
+ case TAB_ABOUT:
+ text.FormatMessage(IDS_ABOUT_ABOUTTEXTss, GetAuthorEmail(), GetWinDirStatHomepage());
+ break;
+ case TAB_THANKSTO:
+ text.LoadString(IDS_ABOUT_THANKSTOTEXT);
+ break;
+ case TAB_LICENSE:
+ text= GetTextResource(IDR_LICENSE);
+ newStyle= ES_LEFT;
+ break;
+ default:
+ ASSERT(0);
+ }
+ CRect rc;
+ m_text.GetWindowRect(rc);
+ ScreenToClient(rc);
+
+ DWORD style= m_text.GetStyle();
+ style&= ~ES_CENTER;
+ style|= newStyle;
+ style|= WS_VSCROLL;
+
+ DWORD exstyle= m_text.GetExStyle();
+
+ m_text.DestroyWindow();
+ m_text.CreateEx(exstyle, style, rc, this, RE_CONTROL);
+
+ m_text.SetAutoURLDetect();
+ m_text.SetEventMask(ENM_LINK);
+ m_text.SetFont(GetFont());
+
+ m_text.SetWindowText(text);
+ m_text.HideCaret();
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg::CMyTabControl, CTabCtrl)
+ ON_NOTIFY(EN_LINK, RE_CONTROL, OnEnLinkText)
+ ON_WM_SIZE()
+END_MESSAGE_MAP()
+
+void CAboutDlg::CMyTabControl::OnEnLinkText(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ ENLINK *el= reinterpret_cast<ENLINK *>(pNMHDR);
+ *pResult = 0;
+
+ if (el->msg == WM_LBUTTONDOWN)
+ {
+ CString link;
+ m_text.GetTextRange(el->chrg.cpMin, el->chrg.cpMax, link);
+
+ ShellExecute(*this, NULL, link, NULL, _T(""), SW_SHOWNORMAL);
+ }
+}
+
+void CAboutDlg::CMyTabControl::OnSize(UINT nType, int cx, int cy)
+{
+ CTabCtrl::OnSize(nType, cx, cy);
+
+ if (IsWindow(m_text.m_hWnd))
+ {
+ CRect rc;
+ GetClientRect(rc);
+
+ CRect rcItem;
+ GetItemRect(0, rcItem);
+
+ rc.top= rcItem.bottom;
+
+ m_text.MoveWindow(rc);
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+CAboutDlg::CAboutDlg()
+ : CDialog(CAboutDlg::IDD)
+ , m_layout(this, _T("aboutdlg"))
+{
+}
+
+CString CAboutDlg::GetAppVersion()
+{
+ CString s;
+ s.Format(_T("WinDirStat 1.0.0"));
+ return s;
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_CAPTION, m_caption);
+ DDX_Control(pDX, IDC_TAB, m_tab);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+ ON_NOTIFY(TCN_SELCHANGE, IDC_TAB, OnTcnSelchangeTab)
+ ON_WM_SIZE()
+ ON_WM_GETMINMAXINFO()
+ ON_WM_DESTROY()
+END_MESSAGE_MAP()
+
+BOOL CAboutDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ m_layout.AddControl(IDC_CAPTION, 0.5, 0, 0, 0);
+ m_layout.AddControl(IDC_TAB, 0, 0, 1, 1);
+ m_layout.AddControl(IDOK, 0.5, 1, 0, 0);
+
+ m_layout.OnInitDialog(true);
+
+ m_tab.Initialize();
+ m_caption.SetWindowText(GetAppVersion());
+
+ return true;
+}
+
+void CAboutDlg::OnTcnSelchangeTab(NMHDR * /* pNMHDR */, LRESULT *pResult)
+{
+ *pResult = 0;
+ m_tab.SetPageText(m_tab.GetCurSel());
+}
+
+void CAboutDlg::OnSize(UINT nType, int cx, int cy)
+{
+ CDialog::OnSize(nType, cx, cy);
+ m_layout.OnSize();
+}
+
+
+void CAboutDlg::OnGetMinMaxInfo(MINMAXINFO* mmi)
+{
+ m_layout.OnGetMinMaxInfo(mmi);
+ CDialog::OnGetMinMaxInfo(mmi);
+
+}
+
+void CAboutDlg::OnDestroy()
+{
+ m_layout.OnDestroy();
+ CDialog::OnDestroy();
+}
diff --git a/windirstat/aboutdlg.h b/windirstat/aboutdlg.h
new file mode 100644
index 0000000..98249c0
--- /dev/null
+++ b/windirstat/aboutdlg.h
@@ -0,0 +1,75 @@
+// aboutdlg.h - Declaration of StartAboutDialog(), CAboutThread and CAboutDlg
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+
+#pragma once
+
+#include "layout.h"
+
+
+void StartAboutDialog();
+
+
+class CAboutThread: public CWinThread
+{
+ DECLARE_DYNCREATE(CAboutThread);
+protected:
+ virtual BOOL InitInstance();
+};
+
+
+class CAboutDlg : public CDialog
+{
+ enum { IDD = IDD_ABOUTBOX };
+
+ class CMyTabControl: public CTabCtrl
+ {
+ public:
+ void Initialize();
+ void SetPageText(int tab);
+
+ protected:
+ CRichEditCtrl m_text;
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnEnLinkText(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ };
+
+public:
+ CAboutDlg();
+ static CString GetAppVersion();
+
+protected:
+ virtual BOOL OnInitDialog();
+ virtual void DoDataExchange(CDataExchange* pDX);
+
+ CStatic m_caption;
+ CMyTabControl m_tab;
+ CLayout m_layout;
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnTcnSelchangeTab(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
+ afx_msg void OnDestroy();
+};
+
diff --git a/windirstat/colorbutton.cpp b/windirstat/colorbutton.cpp
new file mode 100644
index 0000000..aa2d9c4
--- /dev/null
+++ b/windirstat/colorbutton.cpp
@@ -0,0 +1,137 @@
+// colorbutton.cpp - Implementation of CColorButton
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include ".\colorbutton.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+BEGIN_MESSAGE_MAP(CColorButton::CPreview, CWnd)
+ ON_WM_PAINT()
+ ON_WM_LBUTTONDOWN()
+END_MESSAGE_MAP()
+
+CColorButton::CPreview::CPreview()
+{
+ m_color= 0;
+}
+
+COLORREF CColorButton::CPreview::GetColor()
+{
+ return m_color;
+}
+
+void CColorButton::CPreview::SetColor(COLORREF color)
+{
+ m_color= color;
+ if (IsWindow(m_hWnd))
+ InvalidateRect(NULL);
+}
+
+void CColorButton::CPreview::OnPaint()
+{
+ CPaintDC dc(this);
+
+ CRect rc;
+ GetClientRect(rc);
+
+ dc.DrawEdge(rc, EDGE_BUMP, BF_RECT|BF_ADJUST);
+
+ COLORREF color= m_color;
+ if ((GetParent()->GetStyle() & WS_DISABLED) != 0)
+ color= GetSysColor(COLOR_BTNFACE);
+ dc.FillSolidRect(rc, color);
+}
+
+void CColorButton::CPreview::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ ClientToScreen(&point);
+ GetParent()->ScreenToClient(&point);
+ GetParent()->SendMessage(WM_LBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+BEGIN_MESSAGE_MAP(CColorButton, CButton)
+ ON_WM_PAINT()
+ ON_WM_DESTROY()
+ ON_CONTROL_REFLECT(BN_CLICKED, OnBnClicked)
+ ON_WM_ENABLE()
+END_MESSAGE_MAP()
+
+COLORREF CColorButton::GetColor()
+{
+ return m_preview.GetColor();
+}
+
+void CColorButton::SetColor(COLORREF color)
+{
+ m_preview.SetColor(color);
+}
+
+void CColorButton::OnPaint()
+{
+ if (m_preview.m_hWnd == NULL)
+ {
+ CRect rc;
+ GetClientRect(rc);
+
+ rc.right= rc.left + rc.Width() / 3;
+ rc.DeflateRect(4, 4);
+
+ VERIFY(m_preview.Create(AfxRegisterWndClass(0, 0, 0, 0), _T(""), WS_CHILD|WS_VISIBLE, rc, this, 4711));
+
+ ModifyStyle(0, WS_CLIPCHILDREN);
+ }
+ CButton::OnPaint();
+}
+
+void CColorButton::OnDestroy()
+{
+ if (IsWindow(m_preview.m_hWnd))
+ m_preview.DestroyWindow();
+ CButton::OnDestroy();
+}
+
+void CColorButton::OnBnClicked()
+{
+ CColorDialog dlg(GetColor());
+ if (IDOK == dlg.DoModal())
+ {
+ SetColor(dlg.GetColor());
+ NMHDR hdr;
+ hdr.hwndFrom= m_hWnd;
+ hdr.idFrom= GetDlgCtrlID();
+ hdr.code= COLBN_CHANGED;
+
+ GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&hdr);
+ }
+}
+
+
+void CColorButton::OnEnable(BOOL bEnable)
+{
+ if (IsWindow(m_preview.m_hWnd))
+ m_preview.InvalidateRect(NULL);
+ CButton::OnEnable(bEnable);
+}
diff --git a/windirstat/colorbutton.h b/windirstat/colorbutton.h
new file mode 100644
index 0000000..499c3a0
--- /dev/null
+++ b/windirstat/colorbutton.h
@@ -0,0 +1,72 @@
+// colorbutton.h - Declaration of CColorButton
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#define COLBN_CHANGED 0x87 // this is a value, I hope, that is nowhere used as notification code.
+
+//
+// CColorButton. A Pushbutton which allows to choose a color and
+// shows this color on its surface.
+//
+// In the resource editor, the button should be set to "right align text",
+// as the color will be shown in the left third.
+//
+// When the user chose a color, the parent is notified via WM_NOTIFY
+// and the notification code COLBN_CHANGED.
+//
+class CColorButton: public CButton
+{
+public:
+ COLORREF GetColor();
+ void SetColor(COLORREF color);
+
+private:
+ // The color preview is an own little child window of the button.
+ class CPreview: public CWnd
+ {
+ public:
+ CPreview();
+ COLORREF GetColor();
+ void SetColor(COLORREF color);
+
+ private:
+ COLORREF m_color;
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnPaint();
+ public:
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ };
+
+ CPreview m_preview;
+
+protected:
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnPaint();
+ afx_msg void OnDestroy();
+ afx_msg void OnBnClicked();
+ afx_msg void OnEnable(BOOL bEnable);
+};
+
+
+
+
diff --git a/windirstat/dirstatdoc.cpp b/windirstat/dirstatdoc.cpp
new file mode 100644
index 0000000..2ee56d2
--- /dev/null
+++ b/windirstat/dirstatdoc.cpp
@@ -0,0 +1,1427 @@
+// dirstatdoc.cpp: Implementation of CDirstatDoc
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "item.h"
+#include "mainframe.h"
+#include "osspecific.h"
+#include "deletewarningdlg.h"
+#include "modalshellapi.h"
+#include ".\dirstatdoc.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+namespace
+{
+ const COLORREF _cushionColors[] = {
+ RGB(0, 0, 255),
+ RGB(255, 0, 0),
+ RGB(0, 255, 0),
+ RGB(0, 255, 255),
+ RGB(255, 0, 255),
+ RGB(255, 255, 0),
+ RGB(150, 150, 255),
+ RGB(255, 150, 150),
+ RGB(150, 255, 150),
+ RGB(150, 255, 255),
+ RGB(255, 150, 255),
+ RGB(255, 255, 150),
+ RGB(255, 255, 255)
+ };
+}
+
+CDirstatDoc *_theDocument;
+
+CDirstatDoc *GetDocument()
+{
+ return _theDocument;
+}
+
+
+IMPLEMENT_DYNCREATE(CDirstatDoc, CDocument)
+
+
+CDirstatDoc::CDirstatDoc()
+{
+ ASSERT(_theDocument == NULL);
+ _theDocument= this;
+ m_rootItem= NULL;
+ m_workingItem= NULL;
+ m_zoomItem= NULL;
+ m_selectedItem= NULL;
+
+ m_showFreeSpace= CPersistence::GetShowFreeSpace();
+ m_showUnknown= CPersistence::GetShowUnknown();
+ m_extensionDataValid= false;
+}
+
+CDirstatDoc::~CDirstatDoc()
+{
+ CPersistence::SetShowFreeSpace(m_showFreeSpace);
+ CPersistence::SetShowUnknown(m_showUnknown);
+
+ delete m_rootItem;
+ _theDocument= NULL;
+}
+
+// Encodes a selection from the CSelectDrivesDlg into a string which can be routed as a pseudo
+// document "path" through MFC and finally arrives in OnOpenDocument().
+//
+CString CDirstatDoc::EncodeSelection(RADIO radio, CString folder, const CStringArray& drives)
+{
+ CString ret;
+ switch (radio)
+ {
+ case RADIO_ALLLOCALDRIVES:
+ case RADIO_SOMEDRIVES:
+ {
+ for (int i=0; i < drives.GetSize(); i++)
+ {
+ if (i > 0)
+ ret+= CString(GetEncodingSeparator());
+ ret+= drives[i];
+ }
+ }
+ break;
+
+ case RADIO_AFOLDER:
+ ret.Format(_T("%s"), folder);
+ break;
+ }
+ return ret;
+}
+
+// The inverse of EncodeSelection
+//
+void CDirstatDoc::DecodeSelection(CString s, CString& folder, CStringArray& drives)
+{
+ folder.Empty();
+ drives.RemoveAll();
+
+ // s is either something like "C:\programme"
+ // or something like "C:|D:|E:".
+
+ CStringArray sa;
+ int i=0;
+
+ while (i < s.GetLength())
+ {
+ CString token;
+ while (i < s.GetLength() && s[i] != GetEncodingSeparator())
+ token+= s[i++];
+
+ token.TrimLeft();
+ token.TrimRight();
+ ASSERT(!token.IsEmpty());
+ sa.Add(token);
+
+ if (i < s.GetLength())
+ i++;
+ }
+
+ ASSERT(sa.GetSize() > 0);
+
+ if (sa.GetSize() > 1)
+ {
+ for (int i=0; i < sa.GetSize(); i++)
+ {
+ CString d= sa[i];
+ ASSERT(d.GetLength() == 2);
+ ASSERT(d[1] == _T(':'));
+
+ drives.Add(d + _T("\\"));
+ }
+ }
+ else
+ {
+ CString f= sa[0];
+ if (f.GetLength() == 2 && f[1] == _T(':'))
+ {
+ drives.Add(f + _T("\\"));
+ }
+ else
+ {
+ folder= f;
+ }
+ }
+}
+
+TCHAR CDirstatDoc::GetEncodingSeparator()
+{
+ return _T('|'); // This character must be one, which is not allowed in file names.
+}
+
+void CDirstatDoc::DeleteContents()
+{
+ delete m_rootItem;
+ m_rootItem= NULL;
+ SetWorkingItem(NULL);
+ m_zoomItem= NULL;
+ m_selectedItem= NULL;
+ GetApp()->ReReadMountPoints();
+}
+
+BOOL CDirstatDoc::OnNewDocument()
+{
+ if (!CDocument::OnNewDocument())
+ return FALSE;
+
+ UpdateAllViews(NULL, HINT_NEWROOT);
+ return TRUE;
+}
+
+BOOL CDirstatDoc::OnOpenDocument(LPCTSTR lpszPathName)
+{
+ CDocument::OnNewDocument(); // --> DeleteContents()
+
+ CString spec= lpszPathName;
+ CString folder;
+ CStringArray drives;
+ DecodeSelection(spec, folder, drives);
+
+ CStringArray rootFolders;
+ if (drives.GetSize() > 0)
+ {
+ m_showMyComputer= (drives.GetSize() > 1);
+ for (int i=0; i < drives.GetSize(); i++)
+ rootFolders.Add(drives[i]);
+ }
+ else
+ {
+ ASSERT(!folder.IsEmpty());
+ m_showMyComputer= false;
+ rootFolders.Add(folder);
+ }
+
+ CArray<CItem *, CItem *> driveItems;
+
+ if (m_showMyComputer)
+ {
+ m_rootItem= new CItem((ITEMTYPE)(IT_MYCOMPUTER|ITF_ROOTITEM), LoadString(IDS_MYCOMPUTER));
+ for (int i=0; i < rootFolders.GetSize(); i++)
+ {
+ CItem *drive= new CItem(IT_DRIVE, rootFolders[i]);
+ driveItems.Add(drive);
+ m_rootItem->AddChild(drive);
+ }
+ }
+ else
+ {
+ ITEMTYPE type= IsDrive(rootFolders[0]) ? IT_DRIVE : IT_DIRECTORY;
+ m_rootItem= new CItem((ITEMTYPE)(type|ITF_ROOTITEM), rootFolders[0], false);
+ if (m_rootItem->GetType() == IT_DRIVE)
+ driveItems.Add(m_rootItem);
+ m_rootItem->UpdateLastChange();
+ }
+ m_zoomItem= m_rootItem;
+
+ for (int i=0; i < driveItems.GetSize(); i++)
+ {
+ if (OptionShowFreeSpace())
+ driveItems[i]->CreateFreeSpaceItem();
+ if (OptionShowUnknown())
+ driveItems[i]->CreateUnknownItem();
+ }
+
+ SetWorkingItem(m_rootItem);
+
+ GetMainFrame()->MinimizeGraphView();
+ GetMainFrame()->MinimizeTypeView();
+
+ UpdateAllViews(NULL, HINT_NEWROOT);
+ return true;
+}
+
+// We don't want MFCs AfxFullPath()-Logic, because lpszPathName
+// is not a path. So we have overridden this.
+//
+void CDirstatDoc::SetPathName(LPCTSTR lpszPathName, BOOL /*bAddToMRU*/)
+{
+ // MRU would be fine but is not implemented yet.
+
+ m_strPathName= lpszPathName;
+ ASSERT(!m_strPathName.IsEmpty()); // must be set to something
+ m_bEmbedded = FALSE;
+ SetTitle(lpszPathName);
+
+ ASSERT_VALID(this);
+}
+
+void CDirstatDoc::Serialize(CArchive& /*ar*/)
+{
+}
+
+// Prefix the window title (with percentage or "Scanning")
+//
+void CDirstatDoc::SetTitlePrefix(CString prefix)
+{
+ CString docName= prefix + GetTitle();
+ GetMainFrame()->UpdateFrameTitleForDocument(docName);
+}
+
+COLORREF CDirstatDoc::GetCushionColor(LPCTSTR ext)
+{
+ SExtensionRecord r;
+ VERIFY(GetExtensionData()->Lookup(ext, r));
+ return r.color;
+}
+
+COLORREF CDirstatDoc::GetZoomColor()
+{
+ return RGB(0,0,255);
+}
+
+bool CDirstatDoc::OptionShowFreeSpace()
+{
+ return m_showFreeSpace;
+}
+
+bool CDirstatDoc::OptionShowUnknown()
+{
+ return m_showUnknown;
+}
+
+const CExtensionData *CDirstatDoc::GetExtensionData()
+{
+ if (!m_extensionDataValid)
+ RebuildExtensionData();
+ return &m_extensionData;
+}
+
+void CDirstatDoc::ForgetItemTree()
+{
+ // The program is closing.
+ // As "delete m_rootItem" can last a long time (many minutes), if
+ // we have been paged out, we simply forget our item tree here and
+ // hope that the system will free all our memory anyway.
+ m_rootItem= NULL;
+
+ m_zoomItem= NULL;
+ m_selectedItem= NULL;
+
+}
+
+// This method does some work for ticks ms.
+// return: true if done or suspended.
+//
+bool CDirstatDoc::Work(DWORD ticks)
+{
+ if (m_rootItem == NULL)
+ return true;
+
+ if (GetMainFrame()->IsProgressSuspended())
+ return true;
+
+ if (!m_rootItem->IsDone())
+ {
+ m_rootItem->DoSomeWork(ticks);
+ if (m_rootItem->IsDone())
+ {
+ m_extensionDataValid= false;
+
+ GetMainFrame()->SetProgressPos100();
+ GetMainFrame()->RestoreTypeView();
+ GetMainFrame()->RestoreGraphView();
+ }
+ else
+ {
+ GetMainFrame()->SetProgressPos(m_workingItem->GetProgressPos());
+ }
+
+ UpdateAllViews(NULL);
+ }
+ if (m_rootItem->IsDone())
+ {
+ SetWorkingItem(NULL);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool CDirstatDoc::IsDrive(CString spec)
+{
+ return (spec.GetLength() == 3 && spec[1] == _T(':') && spec[2] == _T('\\'));
+}
+
+// Starts a refresh of all mount points in our tree.
+// Called when the user changes the follow mount points option.
+//
+void CDirstatDoc::RefreshMountPointItems()
+{
+ CWaitCursor wc;
+
+ CItem *root= GetRootItem();
+ if (root == NULL)
+ return;
+
+ RecurseRefreshMountPointItems(root);
+}
+
+bool CDirstatDoc::IsRootDone()
+{
+ return m_rootItem != NULL && m_rootItem->IsDone();
+}
+
+CItem *CDirstatDoc::GetRootItem()
+{
+ return m_rootItem;
+}
+
+CItem *CDirstatDoc::GetZoomItem()
+{
+ return m_zoomItem;
+}
+
+bool CDirstatDoc::IsZoomed()
+{
+ return GetZoomItem() != GetRootItem();
+}
+
+void CDirstatDoc::SetSelection(const CItem *item, bool keepReselectChildStack)
+{
+ CItem *newzoom= CItem::FindCommonAncestor(m_zoomItem, item);
+ if (newzoom != m_zoomItem)
+ SetZoomItem(newzoom);
+
+ bool keep= keepReselectChildStack || m_selectedItem == item;
+
+ m_selectedItem= const_cast<CItem *>(item);
+ SetSelectionMessageText();
+
+ if (!keep)
+ ClearReselectChildStack();
+}
+
+CItem *CDirstatDoc::GetSelection()
+{
+ return m_selectedItem;
+}
+
+// Sets the status bar text to the path of the selection.
+//
+void CDirstatDoc::SetSelectionMessageText()
+{
+ if (GetSelection() != NULL)
+ GetMainFrame()->SetMessageText(GetSelection()->GetPath());
+ else
+ GetMainFrame()->SetMessageText(AFX_IDS_IDLEMESSAGE);
+}
+
+// The very root has been deleted.
+//
+void CDirstatDoc::UnlinkRoot()
+{
+ DeleteContents();
+ UpdateAllViews(NULL, HINT_NEWROOT);
+}
+
+// Determines, wheter an UDC works for a given item.
+//
+bool CDirstatDoc::UserDefinedCleanupWorksForItem(const USERDEFINEDCLEANUP *udc, const CItem *item)
+{
+ bool works= false;
+
+ if (item != NULL)
+ {
+ switch (item->GetType())
+ {
+ case IT_DRIVE:
+ works= udc->worksForDrives;
+ break;
+
+ case IT_DIRECTORY:
+ works= udc->worksForDirectories;
+ break;
+
+ case IT_FILESFOLDER:
+ works= udc->worksForFilesFolder;
+ break;
+
+ case IT_FILE:
+ works= udc->worksForFiles;
+ break;
+ }
+ }
+
+ return works;
+}
+
+LONGLONG CDirstatDoc::GetWorkingItemReadJobs()
+{
+ if (m_workingItem != NULL)
+ return m_workingItem->GetReadJobs();
+ else
+ return 0;
+}
+
+void CDirstatDoc::RecurseRefreshMountPointItems(CItem *item)
+{
+ if (item->GetType() == IT_DIRECTORY && item != GetRootItem() && GetApp()->IsMountPoint(item->GetPath()))
+ {
+ RefreshItem(item);
+ }
+ for (int i=0; i < item->GetChildrenCount(); i++)
+ {
+ RecurseRefreshMountPointItems(item->GetChild(i));
+ }
+}
+
+// Gets all items of type IT_DRIVE.
+//
+void CDirstatDoc::GetDriveItems(CArray<CItem *, CItem *>& drives)
+{
+ drives.RemoveAll();
+
+ CItem *root= GetRootItem();
+ if (root->GetType() == IT_MYCOMPUTER)
+ {
+ for (int i=0; i < root->GetChildrenCount(); i++)
+ {
+ CItem *drive= root->GetChild(i);
+ ASSERT(drive->GetType() == IT_DRIVE);
+ drives.Add(drive);
+ }
+ }
+ else if (root->GetType() == IT_DRIVE)
+ {
+ drives.Add(root);
+ }
+}
+
+void CDirstatDoc::RefreshRecyclers()
+{
+ CArray<CItem *, CItem *> drives;
+ GetDriveItems(drives);
+
+ for (int i=0; i < drives.GetSize(); i++)
+ {
+ drives[i]->RefreshRecycler();
+ }
+
+ SetWorkingItem(GetRootItem());
+}
+
+void CDirstatDoc::RebuildExtensionData()
+{
+ CWaitCursor wc;
+
+ m_extensionData.RemoveAll();
+ m_rootItem->RecurseCollectExtensionData(&m_extensionData);
+
+ CStringArray sortedExtensions;
+ SortExtensionData(sortedExtensions);
+ SetExtensionColors(sortedExtensions);
+
+ m_extensionDataValid= true;
+}
+
+void CDirstatDoc::SortExtensionData(CStringArray& sortedExtensions)
+{
+ sortedExtensions.SetSize(m_extensionData.GetCount());
+
+ int i= 0;
+ POSITION pos= m_extensionData.GetStartPosition();
+ while (pos != NULL)
+ {
+ CString ext;
+ SExtensionRecord r;
+ m_extensionData.GetNextAssoc(pos, ext, r);
+
+ sortedExtensions[i++]= ext;
+ }
+
+ _pqsortExtensionData= &m_extensionData;
+ qsort(sortedExtensions.GetData(), sortedExtensions.GetSize(), sizeof(CString), &_compareExtensions);
+ _pqsortExtensionData= NULL;
+}
+
+void CDirstatDoc::SetExtensionColors(const CStringArray& sortedExtensions)
+{
+ static CArray<COLORREF, COLORREF> colors;
+
+ if (colors.GetSize() == 0)
+ {
+ if (Is256Colors())
+ {
+ ASSERT(countof(_cushionColors) >= 6);
+ colors.SetSize(7);
+ for (int i=0; i < 6; i++)
+ {
+ colors[i]= _cushionColors[i];
+ }
+ colors[6]= RGB(100, 100, 100);
+ }
+ else
+ {
+ colors.SetSize(countof(_cushionColors));
+
+ for (int i=0; i < countof(_cushionColors); i++)
+ {
+ COLORREF c= _cushionColors[i];
+
+ double dred= GetRValue(c) / 255.0;
+ double dgreen= GetGValue(c) / 255.0;
+ double dblue= GetBValue(c) / 255.0;
+
+ double f= BASE_BRIGHTNESS / (dred + dgreen + dblue);
+ dred*= f;
+ dgreen*= f;
+ dblue*= f;
+
+ int red = (int)(dred * 255);
+ int green = (int)(dgreen * 255);
+ int blue = (int)(dblue * 255);
+
+ NormalizeColor(red, green, blue);
+
+ colors[i]= RGB(red, green, blue);
+ }
+ }
+ }
+
+ for (int i=0; i < sortedExtensions.GetSize(); i++)
+ {
+ COLORREF c= colors[colors.GetSize() - 1];
+ if (i < colors.GetSize())
+ c= colors[i];
+ m_extensionData[sortedExtensions[i]].color= c;
+ }
+}
+
+CExtensionData *CDirstatDoc::_pqsortExtensionData;
+
+int __cdecl CDirstatDoc::_compareExtensions(const void *item1, const void *item2)
+{
+ CString *ext1= (CString *)item1;
+ CString *ext2= (CString *)item2;
+ SExtensionRecord r1;
+ SExtensionRecord r2;
+ VERIFY(_pqsortExtensionData->Lookup(*ext1, r1));
+ VERIFY(_pqsortExtensionData->Lookup(*ext2, r2));
+ return signum(r2.bytes - r1.bytes);
+}
+
+void CDirstatDoc::SetWorkingItem(CItem *item)
+{
+ if (GetMainFrame() != NULL)
+ {
+ if (item != NULL)
+ GetMainFrame()->ShowProgress(item->GetProgressRange());
+ else
+ GetMainFrame()->HideProgress();
+ }
+ m_workingItem= item;
+}
+
+// Deletes a file or directory via SHFileOperation.
+// Return: false, if canceled
+//
+bool CDirstatDoc::DeletePhysicalItem(CItem *item, bool toTrashBin)
+{
+ if (CPersistence::GetShowDeleteWarning())
+ {
+ CDeleteWarningDlg warning;
+ warning.m_fileName= item->GetPath();
+ if (IDYES != warning.DoModal())
+ {
+ return false;
+ }
+ CPersistence::SetShowDeleteWarning(!warning.m_dontShowAgain);
+ }
+
+ ASSERT(item->GetParent() != NULL);
+
+ CModalShellApi msa;
+ msa.DeleteFile(item->GetPath(), toTrashBin);
+
+ RefreshItem(item);
+ return true;
+}
+
+void CDirstatDoc::SetZoomItem(CItem *item)
+{
+ m_zoomItem= item;
+ UpdateAllViews(NULL, HINT_ZOOMCHANGED);
+}
+
+// Starts a refresh of an item.
+// If the physical item has been deleted,
+// updates selection, zoom and working item accordingly.
+//
+void CDirstatDoc::RefreshItem(CItem *item)
+{
+ ASSERT(item != NULL);
+
+ CWaitCursor wc;
+
+ ClearReselectChildStack();
+
+ if (item->IsAncestorOf(GetZoomItem()))
+ SetZoomItem(item);
+
+ if (item->IsAncestorOf(GetSelection()))
+ {
+ SetSelection(item);
+ UpdateAllViews(NULL, HINT_SELECTIONCHANGED);
+ }
+
+ if (m_workingItem != NULL)
+ SetWorkingItem(CItem::FindCommonAncestor(m_workingItem, item));
+ else
+ SetWorkingItem(item);
+
+ CItem *parent= item->GetParent();
+
+ if (!item->StartRefresh())
+ {
+ if (GetZoomItem() == item)
+ SetZoomItem(parent);
+ if (GetSelection() == item)
+ {
+ SetSelection(parent);
+ UpdateAllViews(NULL, HINT_SELECTIONCHANGED);
+ }
+ if (m_workingItem == item)
+ SetWorkingItem(parent);
+ }
+
+ UpdateAllViews(NULL);
+}
+
+// UDC confirmation Dialog.
+//
+void CDirstatDoc::AskForConfirmation(const USERDEFINEDCLEANUP *udc, CItem *item) throw (CUserException *)
+{
+ if (!udc->askForConfirmation)
+ return;
+
+ CString msg;
+ msg.FormatMessage(udc->recurseIntoSubdirectories ? IDS_RUDC_CONFIRMATIONss : IDS_UDC_CONFIRMATIONss,
+ udc->title, item->GetPath()
+ );
+
+ if (IDYES != AfxMessageBox(msg, MB_YESNO))
+ AfxThrowUserException();
+}
+
+void CDirstatDoc::PerformUserDefinedCleanup(const USERDEFINEDCLEANUP *udc, CItem *item) throw(CException *)
+{
+ CWaitCursor wc;
+
+ CString path= item->GetPath();
+
+ bool isDirectory= item->GetType() == IT_DRIVE || item->GetType() == IT_DIRECTORY || item->GetType() == IT_FILESFOLDER;
+
+ // Verify that path still exists
+ if (isDirectory)
+ {
+ if (!FolderExists(path) && !DriveExists(path))
+ MdThrowStringExceptionF(IDS_THEDIRECTORYsDOESNOTEXIST, path);
+ }
+ else
+ {
+ ASSERT(item->GetType() == IT_FILE);
+
+ if (!FileExists(path))
+ MdThrowStringExceptionF(IDS_THEFILEsDOESNOTEXIST, path);
+ }
+
+ if (udc->recurseIntoSubdirectories && item->GetType() != IT_FILESFOLDER)
+ {
+ ASSERT(item->GetType() == IT_DRIVE || item->GetType() == IT_DIRECTORY);
+
+ RecursiveUserDefinedCleanup(udc, path, path);
+ }
+ else
+ {
+ CallUserDefinedCleanup(isDirectory, udc->commandLine, path, path, udc->showConsoleWindow, udc->waitForCompletion);
+ }
+}
+
+void CDirstatDoc::RefreshAfterUserDefinedCleanup(const USERDEFINEDCLEANUP *udc, CItem *item)
+{
+ switch (udc->refreshPolicy)
+ {
+ case RP_NO_REFRESH:
+ break;
+
+ case RP_REFRESH_THIS_ENTRY:
+ RefreshItem(item);
+ break;
+
+ case RP_REFRESH_THIS_ENTRYS_PARENT:
+ RefreshItem(item->GetParent() == NULL ? item : item->GetParent());
+ break;
+
+ // case RP_ASSUME_ENTRY_HAS_BEEN_DELETED:
+ // Feature not implemented.
+ // break;
+
+ default:
+ ASSERT(0);
+ }
+}
+
+void CDirstatDoc::RecursiveUserDefinedCleanup(const USERDEFINEDCLEANUP *udc, const CString& rootPath, const CString& currentPath)
+{
+ // (Depth first.)
+
+ CFileFind finder;
+ BOOL b= finder.FindFile(currentPath + _T("\\*.*"));
+ while (b)
+ {
+ b= finder.FindNextFile();
+ if (finder.IsDots())
+ continue;
+ if (!finder.IsDirectory())
+ continue;
+ if (GetApp()->IsMountPoint(finder.GetFilePath()) && !GetOptions()->IsFollowMountPoints())
+ continue;
+
+ RecursiveUserDefinedCleanup(udc, rootPath, finder.GetFilePath());
+ }
+
+ CallUserDefinedCleanup(true, udc->commandLine, rootPath, currentPath, udc->showConsoleWindow, true);
+}
+
+void CDirstatDoc::CallUserDefinedCleanup(bool isDirectory, const CString& format, const CString& rootPath, const CString& currentPath, bool showConsoleWindow, bool wait)
+{
+ CString userCommandLine= BuildUserDefinedCleanupCommandLine(format, rootPath, currentPath);
+
+ CString app= GetCOMSPEC();
+ CString cmdline;
+ cmdline.Format(_T("%s /C %s"), GetBaseNameFromPath(app), userCommandLine);
+ CString directory= isDirectory ? currentPath : GetFolderNameFromPath(currentPath);
+
+ STARTUPINFO si;
+ ZeroMemory(&si, sizeof(si));
+ si.cb= sizeof(si);
+ si.dwFlags= STARTF_USESHOWWINDOW;
+ si.wShowWindow= showConsoleWindow ? SW_SHOWNORMAL : SW_HIDE;
+
+ PROCESS_INFORMATION pi;
+ ZeroMemory(&pi, sizeof(pi));
+
+ BOOL b= CreateProcess(
+ app,
+ cmdline.GetBuffer(),
+ NULL,
+ NULL,
+ false,
+ 0,
+ NULL,
+ directory,
+ &si,
+ &pi
+ );
+ cmdline.ReleaseBuffer();
+ if (!b)
+ {
+ MdThrowStringExceptionF(IDS_COULDNOTCREATEPROCESSssss,
+ app, cmdline, directory, MdGetWinerrorText(GetLastError())
+ );
+ return;
+ }
+
+ CloseHandle(pi.hThread);
+
+ if (wait)
+ WaitForHandleWithRepainting(pi.hProcess);
+
+ CloseHandle(pi.hProcess);
+}
+
+
+CString CDirstatDoc::BuildUserDefinedCleanupCommandLine(LPCTSTR format, LPCTSTR rootPath, LPCTSTR currentPath)
+{
+ CString rootName= GetBaseNameFromPath(rootPath);
+ CString currentName= GetBaseNameFromPath(currentPath);
+
+ CString s= format;
+
+ // Because file names can contain "%", we first replace our placeholders with
+ // strings which contain a forbidden character.
+ s.Replace(_T("%p"), _T(">p"));
+ s.Replace(_T("%n"), _T(">n"));
+ s.Replace(_T("%sp"), _T(">sp"));
+ s.Replace(_T("%sn"), _T(">sn"));
+
+ // Now substitute
+ s.Replace(_T(">p"), rootPath);
+ s.Replace(_T(">n"), rootName);
+ s.Replace(_T(">sp"), currentPath);
+ s.Replace(_T(">sn"), currentName);
+
+ return s;
+}
+
+
+void CDirstatDoc::PushReselectChild(CItem *item)
+{
+ m_reselectChildStack.AddHead(item);
+}
+
+CItem *CDirstatDoc::PopReselectChild()
+{
+ return m_reselectChildStack.RemoveHead();
+}
+
+void CDirstatDoc::ClearReselectChildStack()
+{
+ m_reselectChildStack.RemoveAll();
+}
+
+bool CDirstatDoc::IsReselectChildAvailable()
+{
+ return !m_reselectChildStack.IsEmpty();
+}
+
+BEGIN_MESSAGE_MAP(CDirstatDoc, CDocument)
+ ON_COMMAND(ID_REFRESHSELECTED, OnRefreshselected)
+ ON_UPDATE_COMMAND_UI(ID_REFRESHSELECTED, OnUpdateRefreshselected)
+ ON_COMMAND(ID_REFRESHALL, OnRefreshall)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
+ ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
+ ON_COMMAND(ID_CLEANUP_EMPTYRECYCLEBIN, OnCleanupEmptyrecyclebin)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWFREESPACE, OnUpdateViewShowfreespace)
+ ON_COMMAND(ID_VIEW_SHOWFREESPACE, OnViewShowfreespace)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWUNKNOWN, OnUpdateViewShowunknown)
+ ON_COMMAND(ID_VIEW_SHOWUNKNOWN, OnViewShowunknown)
+ ON_UPDATE_COMMAND_UI(ID_TREEMAP_SELECTPARENT, OnUpdateTreemapSelectparent)
+ ON_COMMAND(ID_TREEMAP_SELECTPARENT, OnTreemapSelectparent)
+ ON_UPDATE_COMMAND_UI(ID_TREEMAP_ZOOMIN, OnUpdateTreemapZoomin)
+ ON_COMMAND(ID_TREEMAP_ZOOMIN, OnTreemapZoomin)
+ ON_UPDATE_COMMAND_UI(ID_TREEMAP_ZOOMOUT, OnUpdateTreemapZoomout)
+ ON_COMMAND(ID_TREEMAP_ZOOMOUT, OnTreemapZoomout)
+ ON_UPDATE_COMMAND_UI(ID_CLEANUP_OPENINEXPLORER, OnUpdateExplorerHere)
+ ON_COMMAND(ID_CLEANUP_OPENINEXPLORER, OnExplorerHere)
+ ON_UPDATE_COMMAND_UI(ID_CLEANUP_OPENINCONSOLE, OnUpdateCommandPromptHere)
+ ON_COMMAND(ID_CLEANUP_OPENINCONSOLE, OnCommandPromptHere)
+ ON_UPDATE_COMMAND_UI(ID_CLEANUP_DELETETOTRASHBIN, OnUpdateCleanupDeletetotrashbin)
+ ON_COMMAND(ID_CLEANUP_DELETETOTRASHBIN, OnCleanupDeletetotrashbin)
+ ON_UPDATE_COMMAND_UI(ID_CLEANUP_DELETE, OnUpdateCleanupDelete)
+ ON_COMMAND(ID_CLEANUP_DELETE, OnCleanupDelete)
+ ON_UPDATE_COMMAND_UI_RANGE(ID_USERDEFINEDCLEANUP0, ID_USERDEFINEDCLEANUP9, OnUpdateUserdefinedcleanup)
+ ON_COMMAND_RANGE(ID_USERDEFINEDCLEANUP0, ID_USERDEFINEDCLEANUP9, OnUserdefinedcleanup)
+ ON_UPDATE_COMMAND_UI(ID_REFRESHALL, OnUpdateRefreshall)
+ ON_UPDATE_COMMAND_UI(ID_TREEMAP_RESELECTCHILD, OnUpdateTreemapReselectchild)
+ ON_COMMAND(ID_TREEMAP_RESELECTCHILD, OnTreemapReselectchild)
+ ON_UPDATE_COMMAND_UI(ID_CLEANUP_OPEN, OnUpdateCleanupOpen)
+ ON_COMMAND(ID_CLEANUP_OPEN, OnCleanupOpen)
+ ON_UPDATE_COMMAND_UI(ID_CLEANUP_PROPERTIES, OnUpdateCleanupProperties)
+ ON_COMMAND(ID_CLEANUP_PROPERTIES, OnCleanupProperties)
+END_MESSAGE_MAP()
+
+
+void CDirstatDoc::OnUpdateRefreshselected(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(
+ GetSelection() != NULL
+ && GetSelection()->GetType() != IT_FREESPACE
+ && GetSelection()->GetType() != IT_UNKNOWN
+ );
+}
+
+void CDirstatDoc::OnRefreshselected()
+{
+ RefreshItem(GetSelection());
+}
+
+void CDirstatDoc::OnUpdateRefreshall(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(GetRootItem() != NULL);
+}
+
+void CDirstatDoc::OnRefreshall()
+{
+ RefreshItem(GetRootItem());
+}
+
+void CDirstatDoc::OnUpdateEditCopy(CCmdUI *pCmdUI)
+{
+ const CItem *item= GetSelection();
+ pCmdUI->Enable(
+ item != NULL &&
+ item->GetType() != IT_MYCOMPUTER &&
+ item->GetType() != IT_FILESFOLDER &&
+ item->GetType() != IT_FREESPACE &&
+ item->GetType() != IT_UNKNOWN
+ );
+}
+
+void CDirstatDoc::OnEditCopy()
+{
+ const CItem *item= GetSelection();
+ ASSERT(item != NULL);
+ ASSERT(item->GetType() == IT_DRIVE || item->GetType() == IT_DIRECTORY || item->GetType() == IT_FILE);
+
+ GetMainFrame()->CopyToClipboard(item->GetPath());
+}
+
+void CDirstatDoc::OnCleanupEmptyrecyclebin()
+{
+ CModalShellApi msa;
+
+ if (!msa.IsRecycleBinApiSupported())
+ return;
+
+ msa.EmptyRecycleBin();
+
+ RefreshRecyclers();
+ UpdateAllViews(NULL);
+}
+
+void CDirstatDoc::OnUpdateViewShowfreespace(CCmdUI *pCmdUI)
+{
+ pCmdUI->SetCheck(m_showFreeSpace);
+}
+
+void CDirstatDoc::OnViewShowfreespace()
+{
+ CArray<CItem *, CItem *> drives;
+ GetDriveItems(drives);
+
+ if (m_showFreeSpace)
+ {
+ for (int i=0; i < drives.GetSize(); i++)
+ {
+ CItem *free= drives[i]->FindFreeSpaceItem();
+ ASSERT(free != NULL);
+
+ if (GetSelection() == free)
+ SetSelection(free->GetParent());
+
+ if (GetZoomItem() == free)
+ m_zoomItem= free->GetParent();
+
+ drives[i]->RemoveFreeSpaceItem();
+ }
+ m_showFreeSpace= false;
+ }
+ else
+ {
+ for (int i=0; i < drives.GetSize(); i++)
+ drives[i]->CreateFreeSpaceItem();
+ m_showFreeSpace= true;
+ }
+ UpdateAllViews(NULL);
+}
+
+void CDirstatDoc::OnUpdateViewShowunknown(CCmdUI *pCmdUI)
+{
+ pCmdUI->SetCheck(m_showUnknown);
+}
+
+void CDirstatDoc::OnViewShowunknown()
+{
+ CArray<CItem *, CItem *> drives;
+ GetDriveItems(drives);
+
+ if (m_showUnknown)
+ {
+ for (int i=0; i < drives.GetSize(); i++)
+ {
+ CItem *unknown= drives[i]->FindUnknownItem();
+ ASSERT(unknown != NULL);
+
+ if (GetSelection() == unknown)
+ SetSelection(unknown->GetParent());
+
+ if (GetZoomItem() == unknown)
+ m_zoomItem= unknown->GetParent();
+
+ drives[i]->RemoveUnknownItem();
+ }
+ m_showUnknown= false;
+ }
+ else
+ {
+ for (int i=0; i < drives.GetSize(); i++)
+ drives[i]->CreateUnknownItem();
+ m_showUnknown= true;
+ }
+ UpdateAllViews(NULL);
+}
+
+void CDirstatDoc::OnUpdateTreemapZoomin(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(
+ m_rootItem != NULL && m_rootItem->IsDone()
+ && GetSelection() != NULL && GetSelection() != GetZoomItem()
+ );
+}
+
+void CDirstatDoc::OnTreemapZoomin()
+{
+ CItem *p= GetSelection();
+ CItem *z= NULL;
+ while (p != GetZoomItem())
+ {
+ z= p;
+ p= p->GetParent();
+ }
+ ASSERT(z != NULL);
+ SetZoomItem(z);
+}
+
+void CDirstatDoc::OnUpdateTreemapZoomout(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(
+ m_rootItem != NULL && m_rootItem->IsDone()
+ && GetZoomItem() != m_rootItem
+ );
+}
+
+void CDirstatDoc::OnTreemapZoomout()
+{
+ SetZoomItem(GetZoomItem()->GetParent());
+}
+
+
+void CDirstatDoc::OnUpdateExplorerHere(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(GetSelection() != NULL
+ && GetSelection()->GetType() != IT_FREESPACE
+ && GetSelection()->GetType() != IT_UNKNOWN
+ );
+}
+
+void CDirstatDoc::OnExplorerHere()
+{
+ try
+ {
+ const CItem *item= GetSelection();
+ ASSERT(item != NULL);
+
+ if (item->GetType() == IT_MYCOMPUTER)
+ {
+ SHELLEXECUTEINFO sei;
+ ZeroMemory(&sei, sizeof(sei));
+ sei.cbSize= sizeof(sei);
+ sei.hwnd= *AfxGetMainWnd();
+ sei.lpVerb= _T("explore");
+ sei.nShow= SW_SHOWNORMAL;
+
+ CCoTaskMem<LPITEMIDLIST> pidl;
+ GetPidlOfMyComputer(&pidl);
+
+ sei.lpIDList= pidl;
+ sei.fMask|= SEE_MASK_IDLIST;
+
+ BOOL b= ShellExecuteEx(&sei);
+ if (!b)
+ MdThrowStringExceptionF(_T("ShellExecuteEx(explore) failed: %1!s!"), MdGetWinerrorText(GetLastError()));
+ }
+ else
+ {
+ MyShellExecute(*AfxGetMainWnd(), _T("explore"), item->GetFolderPath(), NULL, NULL, SW_SHOWNORMAL);
+ }
+ }
+ catch (CException *pe)
+ {
+ pe->ReportError();
+ pe->Delete();
+ }
+}
+
+void CDirstatDoc::OnUpdateCommandPromptHere(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(GetSelection() != NULL
+ && GetSelection()->GetType() != IT_MYCOMPUTER
+ && GetSelection()->GetType() != IT_FREESPACE
+ && GetSelection()->GetType() != IT_UNKNOWN
+ );
+}
+
+void CDirstatDoc::OnCommandPromptHere()
+{
+ try
+ {
+ CItem *item= GetSelection();
+ ASSERT(item != NULL);
+
+ CString cmd= GetCOMSPEC();
+
+ MyShellExecute(*AfxGetMainWnd(), _T("open"), cmd, NULL, item->GetFolderPath(), SW_SHOWNORMAL);
+ }
+ catch (CException *pe)
+ {
+ pe->ReportError();
+ pe->Delete();
+ }
+}
+
+void CDirstatDoc::OnUpdateCleanupDeletetotrashbin(CCmdUI *pCmdUI)
+{
+ CItem *item= GetSelection();
+
+ pCmdUI->Enable(item != NULL
+ && (item->GetType() == IT_DIRECTORY || item->GetType() == IT_FILE)
+ && !item->IsRootItem()
+ );
+}
+
+void CDirstatDoc::OnCleanupDeletetotrashbin()
+{
+ CItem *item= GetSelection();
+
+ if (item == NULL || item->GetType() != IT_DIRECTORY && item->GetType() != IT_FILE || item->IsRootItem())
+ return;
+
+ if (DeletePhysicalItem(item, true))
+ {
+ RefreshRecyclers();
+ UpdateAllViews(NULL);
+ }
+}
+
+void CDirstatDoc::OnUpdateCleanupDelete(CCmdUI *pCmdUI)
+{
+ CItem *item= GetSelection();
+
+ pCmdUI->Enable(item != NULL
+ && (item->GetType() == IT_DIRECTORY || item->GetType() == IT_FILE)
+ && !item->IsRootItem()
+ );
+}
+
+void CDirstatDoc::OnCleanupDelete()
+{
+ CItem *item= GetSelection();
+
+ if (item == NULL || item->GetType() != IT_DIRECTORY && item->GetType() != IT_FILE || item->IsRootItem())
+ return;
+
+ if (DeletePhysicalItem(item, false))
+ {
+ SetWorkingItem(GetRootItem());
+ UpdateAllViews(NULL);
+ }
+}
+
+void CDirstatDoc::OnUpdateUserdefinedcleanup(CCmdUI *pCmdUI)
+{
+ int i= pCmdUI->m_nID - ID_USERDEFINEDCLEANUP0;
+ CItem *item= GetSelection();
+
+ pCmdUI->Enable(
+ GetOptions()->IsUserDefinedCleanupEnabled(i)
+ && UserDefinedCleanupWorksForItem(GetOptions()->GetUserDefinedCleanup(i), item)
+ );
+}
+
+void CDirstatDoc::OnUserdefinedcleanup(UINT id)
+{
+ const USERDEFINEDCLEANUP *udc= GetOptions()->GetUserDefinedCleanup(id - ID_USERDEFINEDCLEANUP0);
+ CItem *item= GetSelection();
+
+ ASSERT(UserDefinedCleanupWorksForItem(udc, item));
+ if (!UserDefinedCleanupWorksForItem(udc, item))
+ return;
+
+ ASSERT(item != NULL);
+
+ try
+ {
+ AskForConfirmation(udc, item);
+ PerformUserDefinedCleanup(udc, item);
+ RefreshAfterUserDefinedCleanup(udc, item);
+ }
+ catch (CUserException *pe)
+ {
+ pe->Delete();
+ }
+ catch (CException *pe)
+ {
+ pe->ReportError();
+ pe->Delete();
+ }
+}
+
+void CDirstatDoc::OnUpdateTreemapSelectparent(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(GetSelection() != NULL && GetSelection()->GetParent() != NULL);
+}
+
+void CDirstatDoc::OnTreemapSelectparent()
+{
+ PushReselectChild(GetSelection());
+ CItem *p= GetSelection()->GetParent();
+ SetSelection(p, true);
+ UpdateAllViews(NULL, HINT_SHOWNEWSELECTION);
+}
+
+void CDirstatDoc::OnUpdateTreemapReselectchild(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(IsReselectChildAvailable());
+}
+
+void CDirstatDoc::OnTreemapReselectchild()
+{
+ CItem *item= PopReselectChild();
+ SetSelection(item, true);
+ UpdateAllViews(NULL, HINT_SHOWNEWSELECTION);
+}
+
+void CDirstatDoc::OnUpdateCleanupOpen(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(GetSelection() != NULL
+ && GetSelection()->GetType() != IT_FILESFOLDER
+ && GetSelection()->GetType() != IT_FREESPACE
+ && GetSelection()->GetType() != IT_UNKNOWN
+ );
+}
+
+void CDirstatDoc::OnCleanupOpen()
+{
+ try
+ {
+ CString path;
+
+ const CItem *item= GetSelection();
+ ASSERT(item != NULL);
+
+ switch (item->GetType())
+ {
+ case IT_MYCOMPUTER:
+ {
+ SHELLEXECUTEINFO sei;
+ ZeroMemory(&sei, sizeof(sei));
+ sei.cbSize= sizeof(sei);
+ sei.hwnd= *AfxGetMainWnd();
+ sei.lpVerb= _T("open");
+ //sei.fMask= SEE_MASK_INVOKEIDLIST;
+ sei.nShow= SW_SHOWNORMAL;
+ CCoTaskMem<LPITEMIDLIST> pidl;
+
+ GetPidlOfMyComputer(&pidl);
+ sei.lpIDList= pidl;
+ sei.fMask|= SEE_MASK_IDLIST;
+
+ BOOL b= ShellExecuteEx(&sei);
+ if (!b)
+ MdThrowStringExceptionF(_T("ShellExecuteEx(properties) failed: %1!s!"), MdGetWinerrorText(GetLastError()));
+ return;
+ }
+ break;
+
+ case IT_DRIVE:
+ case IT_DIRECTORY:
+ path= item->GetFolderPath();
+ break;
+
+ case IT_FILE:
+ path= item->GetPath();
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ ShellExecuteWithAssocDialog(*AfxGetMainWnd(), path);
+ }
+ catch (CException *pe)
+ {
+ pe->ReportError();
+ pe->Delete();
+ }
+}
+
+void CDirstatDoc::OnUpdateCleanupProperties(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(GetSelection() != NULL
+ && GetSelection()->GetType() != IT_FREESPACE
+ && GetSelection()->GetType() != IT_UNKNOWN
+ && GetSelection()->GetType() != IT_FILESFOLDER
+ );
+}
+
+void CDirstatDoc::OnCleanupProperties()
+{
+ try
+ {
+ SHELLEXECUTEINFO sei;
+ ZeroMemory(&sei, sizeof(sei));
+ sei.cbSize= sizeof(sei);
+ sei.hwnd= *AfxGetMainWnd();
+ sei.lpVerb= _T("properties");
+ sei.fMask= SEE_MASK_INVOKEIDLIST;
+
+ CCoTaskMem<LPITEMIDLIST> pidl;
+ CString path;
+
+ const CItem *item= GetSelection();
+ ASSERT(item != NULL);
+
+ switch (item->GetType())
+ {
+ case IT_MYCOMPUTER:
+ GetPidlOfMyComputer(&pidl);
+ sei.lpIDList= pidl;
+ sei.fMask|= SEE_MASK_IDLIST;
+ break;
+
+ case IT_DRIVE:
+ case IT_DIRECTORY:
+ path= item->GetFolderPath();
+ sei.lpFile= path; // Must not be a temporary variable
+ break;
+
+ case IT_FILE:
+ path= item->GetPath();
+ sei.lpFile= path; // Must not be temporary variable
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ BOOL b= ShellExecuteEx(&sei);
+ if (!b)
+ MdThrowStringExceptionF(_T("ShellExecuteEx(properties) failed: %1!s!"), MdGetWinerrorText(GetLastError()));
+ }
+ catch (CException *pe)
+ {
+ pe->ReportError();
+ pe->Delete();
+ }
+}
+
+// CDirstatDoc Diagnostics
+#ifdef _DEBUG
+void CDirstatDoc::AssertValid() const
+{
+ CDocument::AssertValid();
+}
+
+void CDirstatDoc::Dump(CDumpContext& dc) const
+{
+ CDocument::Dump(dc);
+}
+#endif //_DEBUG
+
+
diff --git a/windirstat/dirstatdoc.h b/windirstat/dirstatdoc.h
new file mode 100644
index 0000000..8e5ee39
--- /dev/null
+++ b/windirstat/dirstatdoc.h
@@ -0,0 +1,206 @@
+// dirstatdoc.h - Declaration of the CDirstatDoc class
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "selectdrivesdlg.h"
+
+class CItem;
+
+//
+// The treemap colors as calculated in CDirstatDoc::SetExtensionColors()
+// all have the "brightness" BASE_BRIGHTNESS.
+// I define brightness as a number from 0 to 3.0: r+g+b/255.
+// RGB(127, 255, 0), for example, has a brightness of 2.5.
+//
+#define BASE_BRIGHTNESS 1.8
+
+//
+// Data stored for each extension.
+//
+struct SExtensionRecord
+{
+ LONGLONG files;
+ LONGLONG bytes;
+ COLORREF color;
+};
+
+//
+// Maps an extension (".bmp") to an SExtensionRecord.
+//
+typedef CMap<CString, LPCTSTR, SExtensionRecord, SExtensionRecord&> CExtensionData;
+
+//
+// Hints for UpdateAllViews()
+//
+enum
+{
+ HINT_NULL, // General update
+ HINT_NEWROOT, // Root item has changed - clear everything.
+ HINT_SELECTIONCHANGED, // The selection has changed, EnsureVisible.
+ HINT_SHOWNEWSELECTION, // The selection has changed, Show Path
+ HINT_ZOOMCHANGED, // Only zoom item has changed.
+ HINT_REDRAWWINDOW, // Only graphically redraw views.
+
+ HINT_TREELISTSTYLECHANGED, // Options: Treelist style (grid) changed
+ HINT_TREEMAPSTYLECHANGED, // Options: Treemap style (grid, colors etc.) changed
+ HINT_CUSHIONSHADINGCHANGED, // Options: Wether or not cushion shading is used changed
+};
+
+//
+// CDirstatDoc. The "Document" class.
+// Owner of the root item and various other data (see data members).
+//
+class CDirstatDoc : public CDocument
+{
+protected:
+ CDirstatDoc(); // Created by MFC only
+ DECLARE_DYNCREATE(CDirstatDoc)
+
+public:
+ virtual ~CDirstatDoc();
+
+ static CString EncodeSelection(RADIO radio, CString folder, const CStringArray& drives);
+ static void DecodeSelection(CString s, CString& folder, CStringArray& drives);
+ static TCHAR GetEncodingSeparator();
+
+ virtual void DeleteContents();
+ virtual BOOL OnNewDocument();
+ virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
+ virtual void SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU);
+ virtual void Serialize(CArchive& ar);
+
+ void SetTitlePrefix(CString prefix);
+
+ COLORREF GetCushionColor(LPCTSTR ext);
+ COLORREF GetZoomColor();
+
+ bool OptionShowFreeSpace();
+ bool OptionShowUnknown();
+
+ const CExtensionData *GetExtensionData();
+
+ void ForgetItemTree();
+ bool Work(DWORD ticks); // return: true if done.
+ bool IsDrive(CString spec);
+ void RefreshMountPointItems();
+
+ bool IsRootDone();
+ CItem *GetRootItem();
+ CItem *GetZoomItem();
+ bool IsZoomed();
+ void SetSelection(const CItem *item, bool keepReselectChildStack = false);
+ CItem *GetSelection();
+ void SetSelectionMessageText();
+ void UnlinkRoot();
+ bool UserDefinedCleanupWorksForItem(const USERDEFINEDCLEANUP *udc, const CItem *item);
+ LONGLONG GetWorkingItemReadJobs();
+
+protected:
+ void RecurseRefreshMountPointItems(CItem *item);
+ void GetDriveItems(CArray<CItem *, CItem *>& drives);
+ void RefreshRecyclers();
+ void RebuildExtensionData();
+ void SortExtensionData(CStringArray& sortedExtensions);
+ void SetExtensionColors(const CStringArray& sortedExtensions);
+ static CExtensionData *_pqsortExtensionData;
+ static int __cdecl _compareExtensions(const void *ext1, const void *ext2);
+ void SetWorkingItem(CItem *item);
+ bool DeletePhysicalItem(CItem *item, bool toTrashBin);
+ void SetZoomItem(CItem *item);
+ void RefreshItem(CItem *item);
+ void AskForConfirmation(const USERDEFINEDCLEANUP *udc, CItem *item) throw (CUserException *);
+ void PerformUserDefinedCleanup(const USERDEFINEDCLEANUP *udc, CItem *item) throw(CException *);
+ void RefreshAfterUserDefinedCleanup(const USERDEFINEDCLEANUP *udc, CItem *item);
+ void RecursiveUserDefinedCleanup(const USERDEFINEDCLEANUP *udc, const CString& rootPath, const CString& currentPath);
+ void CallUserDefinedCleanup(bool isDirectory, const CString& format, const CString& rootPath, const CString& currentPath, bool showConsoleWindow, bool wait);
+ CString BuildUserDefinedCleanupCommandLine(LPCTSTR format, LPCTSTR rootPath, LPCTSTR currentPath);
+ void PushReselectChild(CItem *item);
+ CItem *PopReselectChild();
+ void ClearReselectChildStack();
+ bool IsReselectChildAvailable();
+
+
+ bool m_showFreeSpace; // Whether to show the <Free Space> item
+ bool m_showUnknown; // Whether to show the <Unknown> item
+
+ bool m_showMyComputer; // True, if the user selected more than one drive for scanning.
+ // In this case, we need a root pseudo item ("My Computer").
+
+ CItem *m_rootItem; // The very root item
+ CItem *m_selectedItem; // Currently selected item, or NULL
+ CItem *m_zoomItem; // Current "zoom root"
+ CItem *m_workingItem; // Current item we are working on. For progress indication
+
+ bool m_extensionDataValid; // If this is false, m_extensionData must be rebuilt
+ CExtensionData m_extensionData; // Base for the extension view and cushion colors
+
+ CList<CItem *, CItem *> m_reselectChildStack; // Stack for the "Re-select Child"-Feature
+
+protected:
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnUpdateRefreshselected(CCmdUI *pCmdUI);
+ afx_msg void OnRefreshselected();
+ afx_msg void OnUpdateRefreshall(CCmdUI *pCmdUI);
+ afx_msg void OnRefreshall();
+ afx_msg void OnUpdateEditCopy(CCmdUI *pCmdUI);
+ afx_msg void OnEditCopy();
+ afx_msg void OnCleanupEmptyrecyclebin();
+ afx_msg void OnUpdateViewShowfreespace(CCmdUI *pCmdUI);
+ afx_msg void OnViewShowfreespace();
+ afx_msg void OnUpdateViewShowunknown(CCmdUI *pCmdUI);
+ afx_msg void OnViewShowunknown();
+ afx_msg void OnUpdateTreemapZoomin(CCmdUI *pCmdUI);
+ afx_msg void OnTreemapZoomin();
+ afx_msg void OnUpdateTreemapZoomout(CCmdUI *pCmdUI);
+ afx_msg void OnTreemapZoomout();
+ afx_msg void OnUpdateExplorerHere(CCmdUI *pCmdUI);
+ afx_msg void OnExplorerHere();
+ afx_msg void OnUpdateCommandPromptHere(CCmdUI *pCmdUI);
+ afx_msg void OnCommandPromptHere();
+ afx_msg void OnUpdateCleanupDeletetotrashbin(CCmdUI *pCmdUI);
+ afx_msg void OnCleanupDeletetotrashbin();
+ afx_msg void OnUpdateCleanupDelete(CCmdUI *pCmdUI);
+ afx_msg void OnCleanupDelete();
+ afx_msg void OnUpdateUserdefinedcleanup(CCmdUI *pCmdUI);
+ afx_msg void OnUserdefinedcleanup(UINT id);
+ afx_msg void OnUpdateTreemapSelectparent(CCmdUI *pCmdUI);
+ afx_msg void OnTreemapSelectparent();
+ afx_msg void OnUpdateTreemapReselectchild(CCmdUI *pCmdUI);
+ afx_msg void OnTreemapReselectchild();
+ afx_msg void OnUpdateCleanupOpen(CCmdUI *pCmdUI);
+ afx_msg void OnCleanupOpen();
+ afx_msg void OnUpdateCleanupProperties(CCmdUI *pCmdUI);
+ afx_msg void OnCleanupProperties();
+
+public:
+ #ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+ #endif
+};
+
+//
+// The document is needed in many places.
+//
+extern CDirstatDoc *GetDocument();
+
+
diff --git a/windirstat/dirstatview.cpp b/windirstat/dirstatview.cpp
new file mode 100644
index 0000000..e080587
--- /dev/null
+++ b/windirstat/dirstatview.cpp
@@ -0,0 +1,308 @@
+// dirstatview.cpp : Implementation of CDirstatView
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "dirstatdoc.h"
+#include "item.h"
+#include "mainframe.h"
+#include ".\dirstatview.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+namespace
+{
+ const UINT _nIdTreeListControl = 4711;
+}
+
+CMyTreeListControl::CMyTreeListControl()
+: CTreeListControl(20)
+{
+}
+
+bool CMyTreeListControl::GetAscendingDefault(int column)
+{
+ return (column == COL_NAME || column == COL_LASTCHANGE);
+}
+
+BEGIN_MESSAGE_MAP(CMyTreeListControl, CTreeListControl)
+ ON_WM_CONTEXTMENU()
+END_MESSAGE_MAP()
+
+
+void CMyTreeListControl::OnContextMenu(CWnd* /*pWnd*/, CPoint ptscreen)
+{
+ CPoint point= ptscreen;
+ ScreenToClient(&point);
+
+ LVHITTESTINFO hti;
+ ZeroMemory(&hti, sizeof(hti));
+ hti.pt= point;
+
+ int i= HitTest(&hti);
+ if (i == -1)
+ return;
+
+ if (hti.iSubItem != 0)
+ return;
+
+ CTreeListItem *item= GetItem(i);
+
+ CRect rc;
+ GetItemRect(i, rc, LVIR_BOUNDS);
+ CRect rcTitle= item->GetTitleRect() + rc.TopLeft();
+ if (!rcTitle.PtInRect(point))
+ return;
+
+ COwnerDrawnListControl::OnLButtonDown(0, point);
+
+ CPoint ptmenu(rcTitle.right, rcTitle.top + rcTitle.Height() / 2);
+ ClientToScreen(&ptmenu);
+
+ CMenu menu;
+ menu.LoadMenu(IDR_POPUPLIST);
+ CMenu *sub= menu.GetSubMenu(0);
+
+ GetMainFrame()->AppendUserDefinedCleanups(sub);
+
+ sub->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, ptmenu.x, ptmenu.y, AfxGetMainWnd());
+}
+
+
+IMPLEMENT_DYNCREATE(CDirstatView, CView)
+
+CDirstatView::CDirstatView()
+{
+ m_treeListControl.SetSorting(COL_SUBTREETOTAL, false);
+}
+
+CDirstatView::~CDirstatView()
+{
+}
+
+CString CDirstatView::GenerateReport()
+{
+ CString report= LoadString(IDS_PLEASECHECKYOURDISKUSAGE);
+
+ CItem *root= GetDocument()->GetSelection();
+ ASSERT(root != NULL);
+ ASSERT(root->IsVisible());
+
+ int r= m_treeListControl.FindTreeItem(root);
+
+ for (
+ int i=r;
+ i < m_treeListControl.GetItemCount()
+ && (i == r || m_treeListControl.GetItem(i)->GetIndent() > root->GetIndent());
+ i++
+ )
+ {
+ CItem *item= (CItem *)m_treeListControl.GetItem(i);
+
+ if (item->GetType() == IT_MYCOMPUTER)
+ continue;
+
+ report.AppendFormat(_T("%s %s\r\n"), PadWidthBlanks(FormatLongLongHuman(item->GetSize()), 11), item->GetReportPath());
+ }
+
+ report+= LoadString(IDS_DISKUSAGEREPORTGENERATEDBYWINDIRSTAT);
+ report.AppendFormat(_T("http://%s\r\n"), GetWinDirStatHomepage());
+
+ return report;
+}
+
+// Just a shortcut for CMainFrame to obtain
+// the small font for the suspend button.
+CFont *CDirstatView::GetSmallFont()
+{
+ return m_treeListControl.GetFont();
+}
+BOOL CDirstatView::PreCreateWindow(CREATESTRUCT& cs)
+{
+ return CView::PreCreateWindow(cs);
+}
+
+void CDirstatView::OnInitialUpdate()
+{
+ CView::OnInitialUpdate();
+}
+void CDirstatView::OnDraw(CDC* pDC)
+{
+ CView::OnDraw(pDC);
+}
+
+#ifdef _DEBUG
+CDirstatDoc* CDirstatView::GetDocument() const // Non debug version is inline
+{
+ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDirstatDoc)));
+ return (CDirstatDoc*)m_pDocument;
+}
+#endif
+
+BEGIN_MESSAGE_MAP(CDirstatView, CView)
+ ON_WM_SIZE()
+ ON_WM_CREATE()
+ ON_WM_ERASEBKGND()
+ ON_WM_DESTROY()
+ ON_WM_SETFOCUS()
+ ON_NOTIFY(LVN_ITEMCHANGED, _nIdTreeListControl, OnLvnItemchanged)
+END_MESSAGE_MAP()
+
+void CDirstatView::OnSize(UINT nType, int cx, int cy)
+{
+ CView::OnSize(nType, cx, cy);
+ if (IsWindow(m_treeListControl.m_hWnd))
+ {
+ CRect rc(0, 0, cx, cy);
+ m_treeListControl.MoveWindow(rc);
+ }
+}
+
+int CDirstatView::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CView::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ RECT rect= { 0, 0, 0, 0 };
+ VERIFY(m_treeListControl.CreateEx(0, WS_CHILD|WS_VISIBLE|LVS_REPORT|LVS_SHOWSELALWAYS, rect, this, _nIdTreeListControl));
+ m_treeListControl.AddExtendedStyle(LVS_EX_HEADERDRAGDROP);
+ if (GetOptions()->IsTreelistGrid())
+ m_treeListControl.ShowGrid(true);
+
+ m_treeListControl.InsertColumn(COL_NAME, LoadString(IDS_TREECOL_NAME), LVCFMT_LEFT, 200, COL_NAME);
+ m_treeListControl.InsertColumn(COL_SUBTREEPERCENTAGE, LoadString(IDS_TREECOL_SUBTREEPERCENTAGE), LVCFMT_RIGHT, CItem::GetSubtreePercentageWidth(), COL_SUBTREEPERCENTAGE);
+ m_treeListControl.InsertColumn(COL_PERCENTAGE, LoadString(IDS_TREECOL_PERCENTAGE), LVCFMT_RIGHT, 55, COL_PERCENTAGE);
+ m_treeListControl.InsertColumn(COL_SUBTREETOTAL, LoadString(IDS_TREECOL_SIZE), LVCFMT_RIGHT, 100, COL_SUBTREETOTAL);
+ m_treeListControl.InsertColumn(COL_ITEMS, LoadString(IDS_TREECOL_ITEMS), LVCFMT_RIGHT, 55, COL_ITEMS);
+ m_treeListControl.InsertColumn(COL_FILES, LoadString(IDS_TREECOL_FILES), LVCFMT_RIGHT, 55, COL_FILES);
+ m_treeListControl.InsertColumn(COL_SUBDIRS, LoadString(IDS_TREECOL_SUBDIRS), LVCFMT_RIGHT, 55, COL_SUBDIRS);
+ m_treeListControl.InsertColumn(COL_LASTCHANGE, LoadString(IDS_TREECOL_LASTCHANGE), LVCFMT_LEFT, 120, COL_LASTCHANGE);
+
+ m_treeListControl.OnColumnsInserted();
+
+ m_treeListControl.MySetImageList(GetMyImageList());
+
+ return 0;
+}
+
+BOOL CDirstatView::OnEraseBkgnd(CDC* /*pDC*/)
+{
+ return true;
+}
+
+void CDirstatView::OnDestroy()
+{
+ m_treeListControl.MySetImageList(NULL);
+ CView::OnDestroy();
+}
+
+void CDirstatView::OnSetFocus(CWnd* /*pOldWnd*/)
+{
+ m_treeListControl.SetFocus();
+}
+
+void CDirstatView::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
+
+ if ((pNMLV->uChanged & LVIF_STATE) != 0)
+ {
+ if (pNMLV->iItem == -1)
+ {
+ ASSERT(false); // mal gucken
+ }
+ else
+ {
+ // This is not true (don't know why): ASSERT(m_treeListControl.GetItemState(pNMLV->iItem, LVIS_SELECTED) == pNMLV->uNewState);
+ bool selected= ((m_treeListControl.GetItemState(pNMLV->iItem, LVIS_SELECTED) & LVIS_SELECTED) != 0);
+ CItem *item= (CItem *)m_treeListControl.GetItem(pNMLV->iItem);
+ ASSERT(item != NULL);
+ if (selected)
+ {
+ GetDocument()->SetSelection(item);
+ GetDocument()->UpdateAllViews(this, HINT_SELECTIONCHANGED);
+ }
+ }
+ }
+
+ *pResult = 0;
+}
+
+void CDirstatView::OnUpdate(CView *pSender, LPARAM lHint, CObject *pHint)
+{
+ switch (lHint)
+ {
+ case HINT_NEWROOT:
+ m_treeListControl.SetRootItem(GetDocument()->GetRootItem());
+ m_treeListControl.Sort();
+ m_treeListControl.RedrawItems(0, m_treeListControl.GetItemCount() - 1);
+ break;
+
+ case HINT_SELECTIONCHANGED:
+ m_treeListControl.SelectAndShowItem(GetDocument()->GetSelection(), false);
+ break;
+
+ case HINT_SHOWNEWSELECTION:
+ m_treeListControl.SelectAndShowItem(GetDocument()->GetSelection(), true);
+ break;
+
+ case HINT_REDRAWWINDOW:
+ m_treeListControl.RedrawWindow();
+ break;
+
+ case HINT_ZOOMCHANGED:
+ CView::OnUpdate(pSender, lHint, pHint);
+ break;
+
+ case HINT_TREELISTSTYLECHANGED:
+ m_treeListControl.ShowGrid(GetOptions()->IsTreelistGrid());
+ break;
+
+ case 0:
+ m_treeListControl.Sort();
+ m_treeListControl.EnsureItemVisible(GetDocument()->GetSelection());
+ m_treeListControl.RedrawItems(0, m_treeListControl.GetItemCount() - 1);
+ break;
+
+ default:
+ break;
+ }
+}
+
+// CDirstatView Diagnostics
+
+#ifdef _DEBUG
+void CDirstatView::AssertValid() const
+{
+ CView::AssertValid();
+}
+
+void CDirstatView::Dump(CDumpContext& dc) const
+{
+ CView::Dump(dc);
+}
+
+#endif //_DEBUG
+
+
+
diff --git a/windirstat/dirstatview.h b/windirstat/dirstatview.h
new file mode 100644
index 0000000..e101a38
--- /dev/null
+++ b/windirstat/dirstatview.h
@@ -0,0 +1,86 @@
+// dirstatview.h - Declaration of CMyTreeListControl and CDirstatView
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "TreeListControl.h"
+
+class CDirstatDoc;
+class CItem;
+
+//
+// CMyTreeListControl. I had to derive from CTreeListControl because
+// CTreeListControl doesn't know about the column constants (COL_***).
+//
+class CMyTreeListControl: public CTreeListControl
+{
+public:
+ CMyTreeListControl();
+ virtual bool GetAscendingDefault(int column);
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/);
+};
+
+
+//
+// CDirstatView. The upper left view, which consists of the TreeList.
+//
+class CDirstatView: public CView
+{
+protected:
+ CDirstatView(); // Created by MFC only
+ DECLARE_DYNCREATE(CDirstatView)
+
+public:
+ virtual ~CDirstatView();
+ CString GenerateReport();
+ CFont *GetSmallFont();
+
+protected:
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ virtual void OnInitialUpdate();
+ virtual void OnDraw(CDC* pDC);
+ CDirstatDoc* GetDocument() const;
+
+ CMyTreeListControl m_treeListControl; // The tree list
+
+protected:
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg void OnDestroy();
+ afx_msg void OnSetFocus(CWnd* pOldWnd);
+ afx_msg void OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult);
+ virtual void OnUpdate(CView *pSender, LPARAM lHint, CObject *pHint);
+
+public:
+ #ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+ #endif
+};
+
+#ifndef _DEBUG // Debug version in dirstatview.cpp
+inline CDirstatDoc* CDirstatView::GetDocument() const
+ { return reinterpret_cast<CDirstatDoc*>(m_pDocument); }
+#endif
+
diff --git a/windirstat/getosplatformstring.cpp b/windirstat/getosplatformstring.cpp
new file mode 100644
index 0000000..d5826f1
--- /dev/null
+++ b/windirstat/getosplatformstring.cpp
@@ -0,0 +1,97 @@
+// getosplatformstring.cpp - Implementation of GetOsPlatformString()
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "getosplatformstring.h"
+
+CString GetOsPlatformString()
+{
+ CString ret;
+
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(osvi));
+ osvi.dwOSVersionInfoSize= sizeof(osvi);
+
+ if (!GetVersionEx(&osvi))
+ {
+ return LoadString(IDS__UNKNOWN_);
+ }
+
+ switch (osvi.dwPlatformId)
+ {
+ case VER_PLATFORM_WIN32_NT:
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
+ ret= _T("Windows Server 2003");
+ else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
+ ret= _T("Windows XP");
+ else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
+ ret= _T("Windows 2000");
+ else if (osvi.dwMajorVersion <= 4)
+ ret= _T("Windows NT");
+ else
+ ret.Format(_T("Windows %u.%u"), osvi.dwMajorVersion, osvi.dwMinorVersion);
+ if (lstrlen(osvi.szCSDVersion) > 0)
+ {
+ CString s;
+ s.Format(_T(" (%s)"), osvi.szCSDVersion);
+ ret+= s;
+ }
+ break;
+
+ case VER_PLATFORM_WIN32_WINDOWS:
+ if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
+ {
+ ret= _T("Windows 95");
+ if (osvi.szCSDVersion[1] == _T('C') || osvi.szCSDVersion[1] == _T('B'))
+ ret+= _T(" OSR2");
+ }
+ else if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
+ {
+ ret= _T("Windows 98");
+ if (osvi.szCSDVersion[1] == _T('A'))
+ ret+= _T(" SE");
+ }
+ else if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
+ {
+ ret= _T("Windows ME");
+ }
+ else
+ {
+ ret.Format(_T("<platform %u %u.%u>"), osvi.dwPlatformId, osvi.dwMajorVersion, osvi.dwMinorVersion);
+ }
+ break;
+
+ case VER_PLATFORM_WIN32s:
+ ret= _T("Win32s\n"); // ooops!!
+ break;
+
+ default:
+ ret.Format(_T("<platform id %u>"), osvi.dwPlatformId);
+ break;
+ }
+
+ return ret;
+}
+
+
+
+
diff --git a/windirstat/getosplatformstring.h b/windirstat/getosplatformstring.h
new file mode 100644
index 0000000..09bce92
--- /dev/null
+++ b/windirstat/getosplatformstring.h
@@ -0,0 +1,27 @@
+// getosplatformstring.cpp - Declaration of
+// PlatformIsWindows9x() and GetOsPlatformString()
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+bool PlatformIsWindows9x();
+
+CString GetOsPlatformString();
diff --git a/windirstat/globalhelpers.cpp b/windirstat/globalhelpers.cpp
new file mode 100644
index 0000000..6fbd1db
--- /dev/null
+++ b/windirstat/globalhelpers.cpp
@@ -0,0 +1,505 @@
+// globalhelpers.cpp - Implementation of global helper functions
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "globalhelpers.h"
+
+namespace
+{
+ CString FormatLongLongNormal(LONGLONG n)
+ {
+ // Returns formatted number like "123.456.789".
+
+ ASSERT(n >= 0);
+
+ CString all;
+
+ do
+ {
+ int rest= (int)(n % 1000);
+ n/= 1000;
+
+ CString s;
+ if (n > 0)
+ s.Format(_T("%s%03d"), GetLocaleThousandSeparator(), rest);
+ else
+ s.Format(_T("%d"), rest);
+
+ all= s + all;
+ } while (n > 0);
+
+ return all;
+ }
+
+ void DistributeFirst(int& first, int& second, int& third)
+ {
+ int h= (first - 255) / 2;
+ first= 255;
+ second+= h;
+ third+= h;
+
+ if (second > 255)
+ {
+ int h= second - 255;
+ second= 255;
+ third+= h;
+ ASSERT(third <= 255);
+ }
+ else if (third > 255)
+ {
+ int h= third - 255;
+ third= 255;
+ second+= h;
+ ASSERT(second <= 255);
+ }
+ }
+
+}
+
+CString GetLocaleString(LCTYPE lctype, LANGID langid)
+{
+ LCID lcid= MAKELCID(langid, SORT_DEFAULT);
+
+ int len= GetLocaleInfo(lcid, lctype, NULL, 0);
+ CString s;
+
+ GetLocaleInfo(lcid, lctype, s.GetBuffer(len), len);
+ s.ReleaseBuffer();
+
+ return s;
+}
+
+CString GetLocaleLanguage(LANGID langid)
+{
+ return GetLocaleString(LOCALE_SNATIVELANGNAME, langid) + _T(" - ") + GetLocaleString(LOCALE_SNATIVECTRYNAME, langid);
+}
+
+CString GetLocaleThousandSeparator()
+{
+ return GetLocaleString(LOCALE_STHOUSAND, GetApp()->GetLangid());
+}
+
+CString GetLocaleDecimalSeparator()
+{
+ return GetLocaleString(LOCALE_SDECIMAL, GetApp()->GetLangid());
+}
+
+CString FormatBytes(LONGLONG n)
+{
+ if (GetOptions()->IsHumanFormat())
+ return FormatLongLongHuman(n);
+ else
+ return FormatLongLongNormal(n);
+}
+
+CString FormatLongLongHuman(LONGLONG n)
+{
+ // Returns formatted number like "12,4 GB".
+ ASSERT(n >= 0);
+ const int base = 1024;
+ const int half = base / 2;
+
+ CString s;
+
+ double B = (int)(n % base);
+ n/= base;
+
+ double KB = (int)(n % base);
+ n/= base;
+
+ double MB = (int)(n % base);
+ n/= base;
+
+ double GB = (int)(n % base);
+ n/= base;
+
+ double TB = (int)(n);
+
+ if (TB != 0 || GB == base - 1 && MB >= half)
+ s= FormatDouble(TB + GB/base) + _T(" TB");
+ else if (GB != 0 || MB == base - 1 && KB >= half)
+ s= FormatDouble(GB + MB/base) + _T(" GB");
+ else if (MB != 0 || KB == base - 1 && B >= half)
+ s= FormatDouble(MB + KB/base) + _T(" MB");
+ else if (KB != 0)
+ s= FormatDouble(KB + B/base) + _T(" KB");
+ else if (B != 0)
+ s.Format(_T("%d Bytes"), (int)B);
+ else
+ s= _T("0");
+
+ return s;
+}
+
+
+CString FormatCount(LONGLONG n)
+{
+ return FormatLongLongNormal(n);
+}
+
+CString FormatDouble(double d) // "98,4" or "98.4"
+{
+ ASSERT(d >= 0);
+
+ d+= 0.05;
+
+ int i= (int)floor(d);
+ int r= (int)(10 * fmod(d, 1));
+
+ CString s;
+ s.Format(_T("%d%s%d"), i, GetLocaleDecimalSeparator(), r);
+
+ return s;
+}
+
+CString PadWidthBlanks(CString n, int width)
+{
+ int blankCount= width - n.GetLength();
+ if (blankCount > 0)
+ {
+ CString b;
+ LPTSTR psz= b.GetBuffer(blankCount + 1);
+ for (int i=0; i < blankCount; i++)
+ psz[i]= _T(' ');
+ psz[i]= 0;
+ b.ReleaseBuffer();
+
+ n= b + n;
+ }
+ return n;
+}
+
+CString FormatFileTime(const FILETIME& t)
+{
+ SYSTEMTIME st;
+ if (!FileTimeToSystemTime(&t, &st))
+ return MdGetWinerrorText(GetLastError());
+
+ CString date;
+ VERIFY(0 < GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, date.GetBuffer(256), 256));
+ date.ReleaseBuffer();
+
+ CString time;
+ VERIFY(0 < GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, time.GetBuffer(256), 256));
+ time.ReleaseBuffer();
+
+ return date + _T(" ") + time;
+}
+
+CString FormatMilliseconds(DWORD ms)
+{
+ CString ret;
+ DWORD sec= (ms + 500) / 1000;
+
+ DWORD s= sec % 60;
+ DWORD min= sec / 60;
+
+ DWORD m= min % 60;
+
+ DWORD h= min / 60;
+
+ if (h > 0)
+ ret.Format(_T("%u:%02u:%02u"), h, m, s);
+ else
+ ret.Format(_T("%u:%02u"), m, s);
+ return ret;
+}
+
+bool GetVolumeName(LPCTSTR rootPath, CString& volumeName)
+{
+ CString ret;
+ DWORD dummy;
+
+ UINT old= SetErrorMode(SEM_FAILCRITICALERRORS);
+
+ bool b= GetVolumeInformation(rootPath, volumeName.GetBuffer(256), 256, &dummy, &dummy, &dummy, NULL, 0);
+ volumeName.ReleaseBuffer();
+
+ if (!b)
+ TRACE(_T("GetVolumeInformation(%s) failed: %u\n"), rootPath, GetLastError());
+
+ SetErrorMode(old);
+
+ return b;
+}
+
+// Given a root path like "C:\", this function
+// obtains the volume name and returns a complete display string
+// like "BOOT (C:)".
+CString FormatVolumeName(CString rootPath)
+{
+ CString ret;
+ CString volumeName;
+ bool b= GetVolumeName(rootPath, volumeName);
+ if (b)
+ {
+ ret.Format(_T("%s (%s)"), volumeName, rootPath.Left(2));
+ }
+ else
+ {
+ ret= rootPath;
+ }
+ return ret;
+}
+
+// The inverse of FormatVolumeName().
+// Given a name like "BOOT (C:)", it returns "C:" (without trailing backslash).
+// Or, if name like "C:\", it returns "C:".
+CString PathFromVolumeName(CString name)
+{
+ int i= name.ReverseFind(_T(')'));
+ if (i == -1)
+ {
+ ASSERT(name.GetLength() == 3);
+ return name.Left(2);
+ }
+
+ ASSERT(i != -1);
+ int k= name.ReverseFind(_T('('));
+ ASSERT(k != -1);
+ ASSERT(k < i);
+ CString path= name.Mid(k + 1, i - k - 1);
+ ASSERT(path.GetLength() == 2);
+ ASSERT(path[1] == _T(':'));
+
+ return path;
+}
+
+// Retrieve the "fully qualified parse name" of "My Computer"
+CString GetParseNameOfMyComputer() throw (CException *)
+{
+ CComPtr<IShellFolder> sf;
+ HRESULT hr= SHGetDesktopFolder(&sf);
+ MdThrowFailed(hr, _T("SHGetDesktopFolder"));
+
+ CCoTaskMem<LPITEMIDLIST> pidl;
+ hr= SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidl);
+ MdThrowFailed(hr, _T("SHGetSpecialFolderLocation(CSIDL_DRIVES)"));
+
+ STRRET name;
+ ZeroMemory(&name, sizeof(name));
+ name.uType= STRRET_CSTR;
+ hr= sf->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &name);
+ MdThrowFailed(hr, _T("GetDisplayNameOf(My Computer)"));
+
+ return MyStrRetToString(pidl, &name);
+}
+
+void GetPidlOfMyComputer(LPITEMIDLIST *ppidl) throw (CException *)
+{
+ CComPtr<IShellFolder> sf;
+ HRESULT hr= SHGetDesktopFolder(&sf);
+ MdThrowFailed(hr, _T("SHGetDesktopFolder"));
+
+ hr= SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, ppidl);
+ MdThrowFailed(hr, _T("SHGetSpecialFolderLocation(CSIDL_DRIVES)"));
+}
+
+void ShellExecuteWithAssocDialog(HWND hwnd, LPCTSTR filename) throw (CException *)
+{
+ CWaitCursor wc;
+
+ UINT u= (UINT)ShellExecute(hwnd, NULL, filename, NULL, NULL, SW_SHOWNORMAL);
+ if (u == SE_ERR_NOASSOC)
+ {
+ // Q192352
+ CString sysDir;
+ //-- Get the system directory so that we know where Rundll32.exe resides.
+ GetSystemDirectory(sysDir.GetBuffer(_MAX_PATH), _MAX_PATH);
+ sysDir.ReleaseBuffer();
+
+ CString parameters = _T("shell32.dll,OpenAs_RunDLL ");
+ u= (UINT)ShellExecute(hwnd, _T("open"), _T("RUNDLL32.EXE"), parameters + filename, sysDir, SW_SHOWNORMAL);
+ }
+
+ if (u <= 32)
+ {
+ MdThrowStringExceptionF(_T("ShellExecute failed: %1!s!"), GetShellExecuteError(u));
+ }
+}
+
+void MyGetDiskFreeSpace(LPCTSTR pszRootPath, LONGLONG& total, LONGLONG& unused)
+{
+ ULARGE_INTEGER uavailable;
+ ULARGE_INTEGER utotal;
+ ULARGE_INTEGER ufree;
+ uavailable.QuadPart= 0;
+ utotal.QuadPart= 0;
+ ufree.QuadPart= 0;
+
+ // On NT 4.0, the 2nd Parameter to this function must NOT be NULL.
+ BOOL b= GetDiskFreeSpaceEx(pszRootPath, &uavailable, &utotal, &ufree);
+ if (!b)
+ TRACE(_T("GetDiskFreeSpaceEx(%s) failed.\n"), pszRootPath);
+
+ total= (LONGLONG)utotal.QuadPart; // will fail, when more than 2^63 Bytes free ....
+ unused= (LONGLONG)ufree.QuadPart;
+
+ ASSERT(unused <= total);
+}
+
+// Returns true, if the System has 256 Colors or less
+bool Is256Colors()
+{
+ CClientDC dc(CWnd::GetDesktopWindow());
+ return (dc.GetDeviceCaps(NUMCOLORS) != -1);
+}
+
+CString GetFolderNameFromPath(LPCTSTR path)
+{
+ CString s= path;
+ int i= s.ReverseFind(_T('\\'));
+ if (i < 0)
+ return s;
+ return s.Left(i);
+}
+
+CString GetCOMSPEC()
+{
+ CString cmd;
+
+ DWORD dw= GetEnvironmentVariable(_T("COMSPEC"), cmd.GetBuffer(_MAX_PATH), _MAX_PATH);
+ cmd.ReleaseBuffer();
+
+ if (dw == 0)
+ {
+ TRACE(_T("COMSPEC not set.\n"));
+ cmd= _T("cmd.exe");
+ }
+ return cmd;
+}
+
+void WaitForHandleWithRepainting(HANDLE h)
+{
+ // Code derived from MSDN sample "Waiting in a Message Loop".
+
+ while (true)
+ {
+ // Read all of the messages in this next loop, removing each message as we read it.
+ MSG msg;
+ while (PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE))
+ {
+ DispatchMessage(&msg);
+ }
+
+ // Wait for WM_PAINT message sent or posted to this queue
+ // or for one of the passed handles be set to signaled.
+ DWORD r= MsgWaitForMultipleObjects(1, &h, FALSE, INFINITE, QS_PAINT);
+
+ // The result tells us the type of event we have.
+ if (r == WAIT_OBJECT_0 + 1)
+ {
+ // New messages have arrived.
+ // Continue to the top of the always while loop to dispatch them and resume waiting.
+ continue;
+ }
+ else
+ {
+ // The handle became signaled.
+ break;
+ }
+ }
+}
+
+void NormalizeColor(int& red, int& green, int& blue)
+{
+ ASSERT(red + green + blue <= 3 * 255);
+
+ if (red > 255)
+ {
+ DistributeFirst(red, green, blue);
+ }
+ else if (green > 255)
+ {
+ DistributeFirst(green, red, blue);
+ }
+ else if (blue > 255)
+ {
+ DistributeFirst(blue, red, green);
+ }
+}
+
+bool FolderExists(LPCTSTR path)
+{
+ CFileFind finder;
+ BOOL b= finder.FindFile(path);
+ if (b)
+ {
+ finder.FindNextFile();
+ return finder.IsDirectory();
+ }
+ else
+ {
+ // Here we land, if path is an UNC drive. In this case we
+ // try another FindFile:
+ b= finder.FindFile(CString(path) + "\\*.*");
+ if (b)
+ return true;
+
+ return false;
+ }
+}
+
+bool DriveExists(const CString& path)
+{
+ if (path.GetLength() != 3 || path[1] != _T(':') || path[2] != _T('\\'))
+ return false;
+
+ CString letter= path.Left(1);
+ letter.MakeLower();
+ int d= letter[0] - _T('a');
+
+ DWORD mask= 0x1 << d;
+
+ if ((mask & GetLogicalDrives()) == 0)
+ return false;
+
+ CString dummy;
+ if (!GetVolumeName(path, dummy))
+ return false;
+
+ return true;
+}
+
+CString GetUserName()
+{
+ CString s;
+ DWORD size= UNLEN + 1;
+ (void)GetUserName(s.GetBuffer(size), &size);
+ s.ReleaseBuffer();
+ return s;
+}
+
+bool IsHexDigit(int c)
+{
+ if (isdigit(c))
+ return true;
+
+ if (_T('a') <= c && c <= _T('f'))
+ return true;
+
+ if (_T('A') <= c && c <= _T('F'))
+ return true;
+
+ return false;
+}
+
diff --git a/windirstat/globalhelpers.h b/windirstat/globalhelpers.h
new file mode 100644
index 0000000..08cf640
--- /dev/null
+++ b/windirstat/globalhelpers.h
@@ -0,0 +1,53 @@
+// globalhelpers.h - Declaration of global helper functions
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+
+CString GetLocaleString(LCTYPE lctype, LANGID langid);
+CString GetLocaleLanguage(LANGID langid);
+CString GetLocaleThousandSeparator();
+CString GetLocaleDecimalSeparator();
+CString FormatBytes(LONGLONG n);
+CString FormatLongLongHuman(LONGLONG n);
+CString FormatCount(LONGLONG n);
+CString FormatDouble(double d);
+CString PadWidthBlanks(CString n, int width);
+CString FormatFileTime(const FILETIME& t);
+CString FormatMilliseconds(DWORD ms);
+CString GetParseNameOfMyComputer() throw (CException *);
+void GetPidlOfMyComputer(LPITEMIDLIST *ppidl) throw (CException *);
+void ShellExecuteWithAssocDialog(HWND hwnd, LPCTSTR filename) throw (CException *);
+bool GetVolumeName(LPCTSTR rootPath, CString& volumeName);
+CString FormatVolumeName(CString rootPath);
+CString PathFromVolumeName(CString name);
+void MyGetDiskFreeSpace(LPCTSTR pszRootPath, LONGLONG& total, LONGLONG& unused);
+bool Is256Colors();
+CString GetFolderNameFromPath(LPCTSTR path);
+CString GetCOMSPEC();
+void WaitForHandleWithRepainting(HANDLE h);
+void NormalizeColor(int& red, int& green, int& blue);
+bool FolderExists(LPCTSTR path);
+bool DriveExists(const CString& path);
+CString GetUserName();
+bool IsHexDigit(int c);
+//CString GetAppFileName();
+//CString GetAppFolder();
diff --git a/windirstat/graphview.cpp b/windirstat/graphview.cpp
new file mode 100644
index 0000000..17d7f22
--- /dev/null
+++ b/windirstat/graphview.cpp
@@ -0,0 +1,438 @@
+// graphview.cpp: Implementation of CGraphView
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "mainframe.h"
+#include "dirstatdoc.h"
+#include "dirstatview.h"
+#include "item.h"
+
+#include ".\graphview.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+IMPLEMENT_DYNCREATE(CGraphView, CView)
+
+BEGIN_MESSAGE_MAP(CGraphView, CView)
+ ON_WM_SIZE()
+ ON_WM_LBUTTONDOWN()
+ ON_WM_SETFOCUS()
+ ON_WM_CONTEXTMENU()
+ ON_WM_MOUSEMOVE()
+ ON_WM_DESTROY()
+ ON_WM_TIMER()
+ ON_COMMAND(ID_POPUP_CANCEL, OnPopupCancel)
+END_MESSAGE_MAP()
+
+
+CGraphView::CGraphView()
+{
+ m_recalculationSuspended= false;
+ m_showTreemap= true;
+ m_size.cx= m_size.cy= 0;
+ m_dimmedSize.cx= m_dimmedSize.cy= 0;
+ m_timer= 0;
+}
+
+CGraphView::~CGraphView()
+{
+}
+
+void CGraphView::SuspendRecalculation(bool suspend)
+{
+ m_recalculationSuspended= suspend;
+ if (!suspend)
+ Invalidate();
+}
+
+bool CGraphView::IsShowTreemap()
+{
+ return m_showTreemap;
+}
+
+void CGraphView::ShowTreemap(bool show)
+{
+ m_showTreemap= show;
+}
+
+BOOL CGraphView::PreCreateWindow(CREATESTRUCT& cs)
+{
+ // We don't want a background brush
+ VERIFY(CView::PreCreateWindow(cs)); // this registeres a wndclass
+
+ WNDCLASS wc;
+ VERIFY(GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wc));
+ wc.hbrBackground= NULL;
+ wc.lpszClassName= _T("windirstat_graphview_class");
+ cs.lpszClass= (LPCTSTR)RegisterClass(&wc);
+
+ return true;
+}
+
+void CGraphView::OnInitialUpdate()
+{
+ CView::OnInitialUpdate();
+}
+
+void CGraphView::DrawEmptyView()
+{
+ CClientDC dc(this);
+ DrawEmptyView(&dc);
+}
+
+void CGraphView::DrawEmptyView(CDC *pDC)
+{
+ const COLORREF gray= RGB(160, 160, 160);
+
+ Inactivate();
+
+ CRect rc;
+ GetClientRect(rc);
+
+ if (m_dimmed.m_hObject == NULL)
+ {
+ pDC->FillSolidRect(rc, gray);
+ }
+ else
+ {
+ CDC dcmem;
+ dcmem.CreateCompatibleDC(pDC);
+ CSelectObject sobmp(&dcmem, &m_dimmed);
+ pDC->BitBlt(rc.left, rc.top, m_dimmedSize.cx, m_dimmedSize.cy, &dcmem, 0, 0, SRCCOPY);
+
+ if (rc.Width() > m_dimmedSize.cx)
+ {
+ CRect r= rc;
+ r.left= r.left + m_dimmedSize.cx;
+ pDC->FillSolidRect(r, gray);
+ }
+
+ if (rc.Height() > m_dimmedSize.cy)
+ {
+ CRect r= rc;
+ r.top= r.top + m_dimmedSize.cy;
+ pDC->FillSolidRect(r, gray);
+ }
+ }
+}
+
+void CGraphView::OnDraw(CDC* pDC)
+{
+ CItem *root= GetDocument()->GetRootItem();
+ if (root != NULL && root->IsDone())
+ {
+ if (m_recalculationSuspended || !m_showTreemap)
+ {
+ // TODO: draw something interesting, e.g. outline of the first level.
+ DrawEmptyView(pDC);
+ }
+ else
+ {
+ CRect rc;
+ GetClientRect(rc);
+ ASSERT(m_size == rc.Size());
+ ASSERT(rc.TopLeft() == CPoint(0, 0));
+
+ CDC dcmem;
+ dcmem.CreateCompatibleDC(pDC);
+
+ if (!IsDrawn())
+ {
+ CWaitCursor wc;
+
+ m_bitmap.CreateCompatibleBitmap(pDC, m_size.cx, m_size.cy);
+
+ CSelectObject sobmp(&dcmem, &m_bitmap);
+
+ if (GetDocument()->IsZoomed())
+ DrawZoomFrame(&dcmem, rc);
+
+ if (rc.Width() > 0 && rc.Height() > 0)
+ GetDocument()->GetZoomItem()->DrawGraph(&dcmem, rc);
+
+ // Cause OnIdle() to be called once.
+ PostAppMessage(GetCurrentThreadId(), WM_NULL, 0, 0);
+ }
+
+ CSelectObject sobmp2(&dcmem, &m_bitmap);
+
+ pDC->BitBlt(0, 0, m_size.cx, m_size.cy, &dcmem, 0, 0, SRCCOPY);
+
+ DrawSelection(pDC);
+ }
+ }
+ else
+ {
+ DrawEmptyView(pDC);
+ }
+}
+
+void CGraphView::DrawZoomFrame(CDC *pdc, CRect& rc)
+{
+ const int w = 4;
+ CRect r;
+
+ r= rc;
+ r.bottom= r.top + w;
+ pdc->FillSolidRect(r, GetDocument()->GetZoomColor());
+
+ r= rc;
+ r.top= r.bottom - w;
+ pdc->FillSolidRect(r, GetDocument()->GetZoomColor());
+
+ r= rc;
+ r.right= r.left + w;
+ pdc->FillSolidRect(r, GetDocument()->GetZoomColor());
+
+ r= rc;
+ r.left= r.right - w;
+ pdc->FillSolidRect(r, GetDocument()->GetZoomColor());
+
+ rc.DeflateRect(w, w);
+}
+
+void CGraphView::DrawSelection(CDC *pdc)
+{
+ const CItem *item= GetDocument()->GetSelection();
+ if (item == NULL)
+ return;
+
+ CRect rcClient;
+ GetClientRect(rcClient);
+
+ CRect rc= item->GetRect();
+ if (GetOptions()->IsTreemapGrid())
+ {
+ rc.right++;
+ rc.bottom++;
+ }
+
+ if (rcClient.left < rc.left)
+ rc.left--;
+ if (rcClient.top < rc.top)
+ rc.top--;
+ if (rc.right < rcClient.right)
+ rc.right++;
+ if (rc.bottom < rcClient.bottom)
+ rc.bottom++;
+
+ CSelectStockObject sobrush(pdc, NULL_BRUSH);
+
+ CPen pen(PS_SOLID, 1, GetOptions()->GetTreemapHighlightColor());
+ CSelectObject sopen(pdc, &pen);
+
+ pdc->Rectangle(rc);
+ rc.DeflateRect(1, 1);
+ pdc->Rectangle(rc);
+ rc.DeflateRect(1, 1);
+ pdc->Rectangle(rc);
+}
+
+
+#ifdef _DEBUG
+void CGraphView::AssertValid() const
+{
+ CView::AssertValid();
+}
+
+void CGraphView::Dump(CDumpContext& dc) const
+{
+ CView::Dump(dc);
+}
+
+CDirstatDoc* CGraphView::GetDocument() // Nicht-Debugversion ist inline
+{
+ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDirstatDoc)));
+ return (CDirstatDoc*)m_pDocument;
+}
+#endif //_DEBUG
+
+
+
+void CGraphView::OnSize(UINT nType, int cx, int cy)
+{
+ CView::OnSize(nType, cx, cy);
+ CSize sz(cx, cy);
+ if (sz != m_size)
+ {
+ Inactivate();
+ m_size= sz;
+ }
+}
+
+void CGraphView::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ CItem *root= GetDocument()->GetRootItem();
+ if (root != NULL && root->IsDone() && IsDrawn())
+ {
+ const CItem *item= GetDocument()->GetZoomItem()->FindChildByPoint(point);
+ if (item == NULL)
+ return;
+
+ GetDocument()->SetSelection(item);
+ GetDocument()->UpdateAllViews(NULL, HINT_SHOWNEWSELECTION);
+ }
+ CView::OnLButtonDown(nFlags, point);
+}
+
+bool CGraphView::IsDrawn()
+{
+ return m_bitmap.m_hObject != NULL;
+}
+
+void CGraphView::Inactivate()
+{
+ if (m_bitmap.m_hObject != NULL)
+ {
+ // Move the old bitmap to m_dimmed
+ m_dimmed.DeleteObject();
+ m_dimmed.Attach(m_bitmap.Detach());
+ m_dimmedSize= m_size;
+
+ // Dimm m_inactive
+ CClientDC dc(this);
+ CDC dcmem;
+ dcmem.CreateCompatibleDC(&dc);
+ CSelectObject sobmp(&dcmem, &m_dimmed);
+ for (int x=0; x < m_dimmedSize.cx; x+=2)
+ for (int y=0; y < m_dimmedSize.cy; y+=2)
+ {
+ dcmem.SetPixel(x, y, RGB(100,100,100));
+ }
+ }
+}
+
+void CGraphView::EmptyView()
+{
+ if (m_bitmap.m_hObject != NULL)
+ m_bitmap.DeleteObject();
+
+ if (m_dimmed.m_hObject != NULL)
+ m_dimmed.DeleteObject();
+}
+
+void CGraphView::OnSetFocus(CWnd* /*pOldWnd*/)
+{
+ GetMainFrame()->GetDirstatView()->SetFocus();
+}
+
+void CGraphView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
+{
+ if (!GetDocument()->IsRootDone())
+ Inactivate();
+
+ switch (lHint)
+ {
+ case HINT_NEWROOT:
+ EmptyView();
+ CView::OnUpdate(pSender, lHint, pHint);
+ break;
+
+ case HINT_SELECTIONCHANGED:
+ case HINT_SHOWNEWSELECTION:
+ CView::OnUpdate(pSender, lHint, pHint);
+ break;
+
+ case HINT_ZOOMCHANGED:
+ Inactivate();
+ CView::OnUpdate(pSender, lHint, pHint);
+ break;
+
+ case HINT_REDRAWWINDOW:
+ RedrawWindow();
+ break;
+
+ case HINT_TREEMAPSTYLECHANGED:
+ case HINT_CUSHIONSHADINGCHANGED:
+ Inactivate();
+ CView::OnUpdate(pSender, lHint, pHint);
+ break;
+
+ case 0:
+ CView::OnUpdate(pSender, lHint, pHint);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void CGraphView::OnContextMenu(CWnd* /*pWnd*/, CPoint ptscreen)
+{
+ CPoint point= ptscreen;
+ ScreenToClient(&point);
+
+ CItem *root= GetDocument()->GetRootItem();
+ if (root != NULL && root->IsDone())
+ {
+ CMenu menu;
+ menu.LoadMenu(IDR_POPUPGRAPH);
+ CMenu *sub= menu.GetSubMenu(0);
+ sub->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, ptscreen.x, ptscreen.y, AfxGetMainWnd());
+ }
+}
+
+void CGraphView::OnMouseMove(UINT /*nFlags*/, CPoint point)
+{
+ CItem *root= GetDocument()->GetRootItem();
+ if (root != NULL && root->IsDone() && IsDrawn())
+ {
+ const CItem *item= GetDocument()->GetZoomItem()->FindChildByPoint(point);
+ if (item != NULL)
+ GetMainFrame()->SetMessageText(item->GetPath());
+ }
+ if (m_timer == 0)
+ m_timer= SetTimer(4711, 100, NULL);
+}
+
+void CGraphView::OnDestroy()
+{
+ if (m_timer != NULL)
+ KillTimer(m_timer);
+ m_timer= 0;
+
+ CView::OnDestroy();
+}
+
+void CGraphView::OnTimer(UINT /*nIDEvent*/)
+{
+ CPoint point;
+ GetCursorPos(&point);
+ ScreenToClient(&point);
+
+ CRect rc;
+ GetClientRect(rc);
+
+ if (!rc.PtInRect(point))
+ {
+ GetDocument()->SetSelectionMessageText();
+ KillTimer(m_timer);
+ m_timer= 0;
+ }
+}
+
+void CGraphView::OnPopupCancel()
+{
+}
diff --git a/windirstat/graphview.h b/windirstat/graphview.h
new file mode 100644
index 0000000..02b7855
--- /dev/null
+++ b/windirstat/graphview.h
@@ -0,0 +1,88 @@
+// graphview.h - Declaration of CGraphView (the Treemap view)
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+
+#pragma once
+
+class CDirstatDoc;
+class CItem;
+
+
+//
+// CGraphView. The treemap window.
+//
+class CGraphView : public CView
+{
+protected:
+ CGraphView();
+ DECLARE_DYNCREATE(CGraphView)
+public:
+ virtual ~CGraphView();
+
+ CDirstatDoc* GetDocument();
+ void SuspendRecalculation(bool suspend);
+ bool IsShowTreemap();
+ void ShowTreemap(bool show);
+ void DrawEmptyView();
+
+protected:
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ virtual void OnInitialUpdate();
+ virtual void OnDraw(CDC* pDC);
+ bool IsDrawn();
+ void Inactivate();
+ void EmptyView();
+ void DrawEmptyView(CDC *pDC);
+
+ void DrawZoomFrame(CDC *pdc, CRect& rc);
+ void DrawSelection(CDC *pdc);
+
+ bool m_recalculationSuspended; // True while the user is resizing the window.
+ bool m_showTreemap; // False, if the user switched off the treemap (by F9).
+ CSize m_size; // Current size of view
+ CBitmap m_bitmap; // Cached view. If m_hObject is NULL, the view must be recalculated.
+ CSize m_dimmedSize; // Size of bitmap m_dimmed
+ CBitmap m_dimmed; // Dimmed view. Used during refresh to avoid the ooops-effect.
+ UINT_PTR m_timer; // We need a timer to realize when the mouse left our window.
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnSetFocus(CWnd* pOldWnd);
+ virtual void OnUpdate(CView * pSender, LPARAM lHint, CObject *pHint);
+ afx_msg void OnContextMenu(CWnd *pWnd, CPoint point);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ afx_msg void OnDestroy();
+ afx_msg void OnTimer(UINT nIDEvent);
+
+public:
+ #ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+ #endif
+ afx_msg void OnPopupCancel();
+};
+
+#ifndef _DEBUG // Debugversion in graphview.cpp
+inline CDirstatDoc* CGraphView::GetDocument()
+ { return reinterpret_cast<CDirstatDoc*>(m_pDocument); }
+#endif
+
diff --git a/windirstat/helpmap.h b/windirstat/helpmap.h
new file mode 100644
index 0000000..357762b
--- /dev/null
+++ b/windirstat/helpmap.h
@@ -0,0 +1,24 @@
+// helpmap.h - Definition of contextual help ids
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#define IDH_StartPage 1001
+#define IDH_UserDefinedCleanups 1002
+#define IDH_Treemap 1003
diff --git a/windirstat/item.cpp b/windirstat/item.cpp
new file mode 100644
index 0000000..7e25502
--- /dev/null
+++ b/windirstat/item.cpp
@@ -0,0 +1,1814 @@
+// item.cpp - Implementation of CItem
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "dirstatdoc.h" // GetItemColor()
+#include "mainframe.h"
+#include "item.h"
+
+namespace
+{
+ CString GetFreeSpaceItemName() { return LoadString(IDS_FREESPACE_ITEM); }
+ CString GetUnknownItemName() { return LoadString(IDS_UNKNOWN_ITEM); }
+
+ const SIZE sizeDeflatePacman = { 0, 2 };
+}
+
+
+DWORD CItem::_m_lastRamUsageUpdate;
+
+CItem::CItem(ITEMTYPE type, LPCTSTR name, bool dontFollow)
+ : m_type(type)
+ , m_name(name)
+ , m_size(0)
+ , m_files(0)
+ , m_subdirs(0)
+ , m_done(false)
+ , m_ticksWorked(0)
+ , m_readJobs(0)
+{
+ if (GetType() == IT_FILE || dontFollow || GetType() == IT_FREESPACE || GetType() == IT_UNKNOWN || GetType() == IT_MYCOMPUTER)
+ {
+ SetReadJobDone();
+ m_readJobs= 0;
+ }
+ else if (GetType() == IT_DIRECTORY || GetType() == IT_DRIVE || GetType() == IT_FILESFOLDER)
+ {
+ SetReadJobDone(false);
+ }
+
+ if (GetType() == IT_DRIVE)
+ {
+ m_name= FormatVolumeName(m_name);
+ }
+
+ ZeroMemory(&m_lastChange, sizeof(m_lastChange));
+}
+
+CItem::~CItem()
+{
+ for (int i=0; i < m_children.GetSize(); i++)
+ delete m_children[i];
+}
+
+bool CItem::DrawSubitem(int subitem, CDC *pdc, CRect rc, UINT state, int *width) const
+{
+ if (subitem == COL_NAME)
+ {
+ return CTreeListItem::DrawSubitem(subitem, pdc, rc, state, width);
+ }
+ if (subitem != COL_SUBTREEPERCENTAGE)
+ return false;
+
+ bool showReadJobs= MustShowReadJobs();
+
+ if (showReadJobs && !GetOptions()->IsPacmanAnimation())
+ return false;
+
+ if (showReadJobs && IsDone())
+ return false;
+
+ if (width != NULL)
+ {
+ *width= GetSubtreePercentageWidth();
+ return true;
+ }
+
+ if (showReadJobs)
+ {
+ rc.DeflateRect(sizeDeflatePacman);
+ DrawPacman(pdc, rc);
+ }
+ else
+ {
+ rc.DeflateRect(2, 3);
+ for (int i=0; i < GetIndent(); i++)
+ rc.left+= rc.Width() / 10;
+
+ CPen pen(PS_SOLID, 1, RGB(0,0,0));
+ CSelectObject sopen(pdc, &pen);
+ CSelectStockObject sobrush(pdc, NULL_BRUSH);
+ pdc->Rectangle(rc);
+
+ rc.DeflateRect(1, 1);
+
+ CRect rcLeft= rc;
+ rcLeft.right= (int)(rcLeft.left + rc.Width() * GetFraction());
+ pdc->FillSolidRect(rcLeft, GetPercentageColor());
+
+ CRect rcRight= rc;
+ rcRight.left= rcLeft.right;
+ pdc->FillSolidRect(rcRight, RGB(220,220,220));
+ }
+ return true;
+}
+
+CString CItem::GetText(int subitem) const
+{
+ CString s;
+ switch (subitem)
+ {
+ case COL_NAME:
+ s= m_name;
+ break;
+
+ case COL_SUBTREEPERCENTAGE:
+ if (IsDone())
+ {
+ ASSERT(m_readJobs == 0);
+ //s= "ok";
+ }
+ else
+ {
+ if (m_readJobs == 1)
+ s.LoadString(IDS_ONEREADJOB);
+ else
+ s.FormatMessage(IDS_sREADJOBS, FormatCount(m_readJobs));
+ }
+ break;
+
+ case COL_PERCENTAGE:
+ if (MustShowReadJobs() || IsRootItem())
+ {
+ s.Format(_T("[%s s]"), FormatMilliseconds(GetTicksWorked()));
+ }
+ else
+ {
+ s.Format(_T("%s%%"), FormatDouble(GetFraction() * 100));
+ }
+ break;
+
+ case COL_SUBTREETOTAL:
+ s= FormatBytes(GetSize());
+ break;
+
+ case COL_ITEMS:
+ if (GetType() != IT_FILE && GetType() != IT_FREESPACE && GetType() != IT_UNKNOWN)
+ s= FormatCount(GetItemsCount());
+ break;
+
+ case COL_FILES:
+ if (GetType() != IT_FILE && GetType() != IT_FREESPACE && GetType() != IT_UNKNOWN)
+ s= FormatCount(GetFilesCount());
+ break;
+
+ case COL_SUBDIRS:
+ if (GetType() != IT_FILE && GetType() != IT_FREESPACE && GetType() != IT_UNKNOWN)
+ s= FormatCount(GetSubdirsCount());
+ break;
+
+ case COL_LASTCHANGE:
+ if (GetType() != IT_FREESPACE && GetType() != IT_UNKNOWN)
+ {
+ s= FormatFileTime(m_lastChange);
+ }
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+ return s;
+}
+
+int CItem::CompareSibling(const CTreeListItem *tlib, int subitem) const
+{
+ CItem *other= (CItem *)tlib;
+
+ int r=0;
+ switch (subitem)
+ {
+ case COL_NAME:
+ if (GetType() == IT_DRIVE)
+ {
+ ASSERT(other->GetType() == IT_DRIVE);
+ r= GetPath().CompareNoCase(other->GetPath());
+ }
+ else
+ {
+ r= m_name.CompareNoCase(other->m_name);
+ }
+ break;
+
+ case COL_SUBTREEPERCENTAGE:
+ if (MustShowReadJobs())
+ r= signum(m_readJobs - other->m_readJobs);
+ else
+ r= signum(GetFraction() - other->GetFraction());
+ break;
+
+ case COL_PERCENTAGE:
+ r= signum(GetFraction() - other->GetFraction());
+ break;
+
+ case COL_SUBTREETOTAL:
+ r= signum(GetSize() - other->GetSize());
+ break;
+
+ case COL_ITEMS:
+ r= signum(GetItemsCount() - other->GetItemsCount());
+ break;
+
+ case COL_FILES:
+ r= signum(GetFilesCount() - other->GetFilesCount());
+ break;
+
+ case COL_SUBDIRS:
+ r= signum(GetSubdirsCount() - other->GetSubdirsCount());
+ break;
+
+ case COL_LASTCHANGE:
+ {
+ if (m_lastChange < other->m_lastChange)
+ return -1;
+ else if (m_lastChange == other->m_lastChange)
+ return 0;
+ else
+ return 1;
+ }
+ break;
+
+ default:
+ ASSERT(false);
+ break;
+ }
+ return r;
+}
+
+int CItem::GetChildrenCount() const
+{
+ return m_children.GetSize();
+}
+
+CTreeListItem *CItem::GetTreeListChild(int i) const
+{
+ return m_children[i];
+}
+
+int CItem::GetImageToCache() const
+{
+ // (Caching is done in CTreeListItem::m_vi.)
+
+ int image;
+
+ if (GetType() == IT_MYCOMPUTER)
+ {
+ image= GetMyImageList()->GetMyComputerImage();
+ }
+ else if (GetType() == IT_FILESFOLDER)
+ {
+ image= GetMyImageList()->GetFilesFolderImage();
+ }
+ else if (GetType() == IT_FREESPACE)
+ {
+ image= GetMyImageList()->GetFreeSpaceImage();
+ }
+ else if (GetType() == IT_UNKNOWN)
+ {
+ image= GetMyImageList()->GetUnknownImage();
+ }
+ else
+ {
+ CString path= GetPath();
+
+ if (GetType() == IT_DIRECTORY && GetApp()->IsMountPoint(path))
+ {
+ image= GetMyImageList()->GetMountPointImage();
+ }
+ else
+ {
+ image= GetMyImageList()->GetFileImage(path);
+ }
+ }
+ return image;
+}
+
+void CItem::DrawAdditionalState(CDC *pdc, const CRect& rcLabel) const
+{
+ if (!IsRootItem() && this == GetDocument()->GetZoomItem())
+ {
+ CRect rc= rcLabel;
+ rc.InflateRect(1, 0);
+ rc.bottom++;
+
+ CSelectStockObject sobrush(pdc, NULL_BRUSH);
+ CPen pen(PS_SOLID, 2, GetDocument()->GetZoomColor());
+ CSelectObject sopen(pdc, &pen);
+
+ pdc->Rectangle(rc);
+ }
+}
+
+int CItem::GetSubtreePercentageWidth()
+{
+ return 105;
+}
+
+CItem *CItem::FindCommonAncestor(const CItem *item1, const CItem *item2)
+{
+ const CItem *parent= item1;
+ while (!parent->IsAncestorOf(item2))
+ parent= parent->GetParent();
+ ASSERT(parent != NULL);
+ return const_cast<CItem *>(parent);
+}
+
+bool CItem::IsAncestorOf(const CItem *item) const
+{
+ const CItem *p= item;
+ while (p != NULL)
+ {
+ if (p == this)
+ break;
+ p= p->GetParent();
+ }
+ return (p != NULL);
+}
+
+LONGLONG CItem::GetProgressRange() const
+{
+ switch (GetType())
+ {
+ case IT_MYCOMPUTER:
+ return GetProgressRangeMyComputer();
+
+ case IT_DRIVE:
+ return GetProgressRangeDrive();
+
+ case IT_DIRECTORY:
+ case IT_FILESFOLDER:
+ case IT_FILE:
+ return 0;
+
+ case IT_FREESPACE:
+ case IT_UNKNOWN:
+ default:
+ ASSERT(0);
+ return 0;
+ }
+}
+
+LONGLONG CItem::GetProgressPos() const
+{
+ switch (GetType())
+ {
+ case IT_MYCOMPUTER:
+ return GetProgressPosMyComputer();
+
+ case IT_DRIVE:
+ return GetProgressPosDrive();
+
+ case IT_DIRECTORY:
+ return m_files + m_subdirs;
+
+ case IT_FILE:
+ case IT_FILESFOLDER:
+ case IT_FREESPACE:
+ case IT_UNKNOWN:
+ default:
+ ASSERT(0);
+ return 0;
+ }
+}
+
+const CItem *CItem::UpwardGetRoot() const
+{
+ if (GetParent() == NULL)
+ return this;
+ else
+ return GetParent()->UpwardGetRoot();
+}
+
+void CItem::UpdateLastChange()
+{
+ ZeroMemory(&m_lastChange, sizeof(m_lastChange));
+ if (GetType() == IT_DIRECTORY || GetType() == IT_FILE)
+ {
+ CString path= GetPath();
+
+ int i= path.ReverseFind(_T('\\'));
+ CString basename= path.Mid(i + 1);
+ CString pattern;
+ pattern.Format(_T("%s\\..\\%s"), path, basename);
+ CFileFind finder;
+ BOOL b= finder.FindFile(pattern);
+ if (!b)
+ return; // no chance
+ finder.FindNextFile();
+ finder.GetLastWriteTime(&m_lastChange);
+ }
+}
+
+CItem *CItem::GetChild(int i) const
+{
+ return m_children[i];
+}
+
+CItem *CItem::GetParent() const
+{
+ return (CItem *)CTreeListItem::GetParent();
+}
+
+int CItem::FindChildIndex(const CItem *child) const
+{
+ for (int i=0; i < GetChildrenCount(); i++)
+ if (child == m_children[i])
+ return i;
+ ASSERT(0);
+ return 0;
+}
+
+void CItem::AddChild(CItem *child)
+{
+ ASSERT(!IsDone()); // SetDone() computed m_childrenBySize
+
+ // This sequence is essential: First add numbers, then CTreeListControl::OnChildAdded(),
+ // because the treelist will display it immediately.
+ // If we did it the other way round, CItem::GetFraction() could ASSERT.
+ UpwardAddSize(child->GetSize());
+ UpwardAddReadJobs(child->GetReadJobs());
+ UpwardUpdateLastChange(child->GetLastChange());
+
+ m_children.Add(child);
+ child->SetParent(this);
+
+ GetTreeListControl()->OnChildAdded(this, child);
+}
+
+void CItem::RemoveChild(int i)
+{
+ CItem *child= GetChild(i);
+ m_children.RemoveAt(i);
+ GetTreeListControl()->OnChildRemoved(this, child);
+ delete child;
+}
+
+void CItem::RemoveAllChildren()
+{
+ GetTreeListControl()->OnRemovingAllChildren(this);
+
+ for (int i=0; i < GetChildrenCount(); i++)
+ {
+ delete m_children[i];
+ }
+ m_children.SetSize(0);
+}
+
+void CItem::UpwardAddSubdirs(LONGLONG dirCount)
+{
+ m_subdirs+= dirCount;
+ if (GetParent() != NULL)
+ GetParent()->UpwardAddSubdirs(dirCount);
+}
+
+void CItem::UpwardAddFiles(LONGLONG fileCount)
+{
+ m_files+= fileCount;
+ if (GetParent() != NULL)
+ GetParent()->UpwardAddFiles(fileCount);
+}
+
+void CItem::UpwardAddSize(LONGLONG bytes)
+{
+ m_size+= bytes;
+ if (GetParent() != NULL)
+ GetParent()->UpwardAddSize(bytes);
+}
+
+void CItem::UpwardAddReadJobs(/* signed */LONGLONG count)
+{
+ m_readJobs+= count;
+ if (GetParent() != NULL)
+ GetParent()->UpwardAddReadJobs(count);
+}
+
+// This method increases the last change
+void CItem::UpwardUpdateLastChange(const FILETIME& t)
+{
+ if (m_lastChange < t)
+ {
+ m_lastChange= t;
+ if (GetParent() != NULL)
+ GetParent()->UpwardUpdateLastChange(t);
+ }
+}
+
+// This method may also decrease the last change
+void CItem::UpwardRecalcLastChange()
+{
+ UpdateLastChange();
+
+ for (int i=0; i < GetChildrenCount(); i++)
+ {
+ if (m_lastChange < GetChild(i)->GetLastChange())
+ m_lastChange= GetChild(i)->GetLastChange();
+ }
+ if (GetParent() != NULL)
+ GetParent()->UpwardRecalcLastChange();
+}
+
+LONGLONG CItem::GetSize() const
+{
+ return m_size;
+}
+
+void CItem::SetSize(LONGLONG ownSize)
+{
+ ASSERT(IsLeaf(GetType()));
+ ASSERT(ownSize >= 0);
+ m_size= ownSize;
+}
+
+LONGLONG CItem::GetReadJobs() const
+{
+ return m_readJobs;
+}
+
+FILETIME CItem::GetLastChange() const
+{
+ return m_lastChange;
+}
+
+void CItem::SetLastChange(const FILETIME& t)
+{
+ m_lastChange= t;
+}
+
+double CItem::GetFraction() const
+{
+ if (GetParent() == NULL)
+ return 1.0;
+ if (GetParent()->GetSize() == 0)
+ {
+ return 1.0;
+ }
+ return (double) GetSize() / GetParent()->GetSize();
+}
+
+ITEMTYPE CItem::GetType() const
+{
+ return (ITEMTYPE)(m_type & ~ITF_FLAGS);
+}
+
+bool CItem::IsRootItem() const
+{
+ return ((m_type & ITF_ROOTITEM) != 0);
+}
+
+CString CItem::GetPath() const
+{
+ CString path= UpwardGetPathWithoutBackslash();
+ if (GetType() == IT_DRIVE || GetType() == IT_FILESFOLDER && GetParent()->GetType() == IT_DRIVE)
+ path+= _T("\\");
+ return path;
+}
+
+CString CItem::GetFindPattern() const
+{
+ CString pattern= GetPath();
+ if (pattern.Right(1) != _T('\\'))
+ pattern+= _T("\\");
+ pattern+= _T("*.*");
+ return pattern;
+}
+
+// Returns the path for "Explorer here" or "Command Prompt here"
+CString CItem::GetFolderPath() const
+{
+ CString path;
+
+ if (GetType() == IT_MYCOMPUTER)
+ {
+ path= GetParseNameOfMyComputer();
+ }
+ else
+ {
+ path= GetPath();
+ if (GetType() == IT_FILE)
+ {
+ int i= path.ReverseFind(_T('\\'));
+ ASSERT(i != -1);
+ path= path.Left(i + 1);
+ }
+ }
+ return path;
+}
+
+// returns the path for the mail-report
+CString CItem::GetReportPath() const
+{
+ CString path= UpwardGetPathWithoutBackslash();
+ if (GetType() == IT_DRIVE || GetType() == IT_FILESFOLDER)
+ path+= _T("\\");
+ if (GetType() == IT_FILESFOLDER
+ || GetType() == IT_FREESPACE
+ || GetType() == IT_UNKNOWN)
+ path+= GetName();
+
+ return path;
+}
+
+CString CItem::GetName() const
+{
+ return m_name;
+}
+
+CString CItem::GetExtension() const
+{
+ CString ext;
+
+ switch (GetType())
+ {
+ case IT_FILE:
+ {
+ int i= GetName().ReverseFind(_T('.'));
+ if (i == -1)
+ ext= _T(".");
+ else
+ ext= GetName().Mid(i);
+ ext.MakeLower();
+ break;
+ }
+ case IT_FREESPACE:
+ case IT_UNKNOWN:
+ ext= GetName();
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ return ext;
+}
+
+LONGLONG CItem::GetFilesCount() const
+{
+ return m_files;
+}
+
+LONGLONG CItem::GetSubdirsCount() const
+{
+ return m_subdirs;
+}
+
+LONGLONG CItem::GetItemsCount() const
+{
+ return m_files + m_subdirs;
+}
+
+bool CItem::IsReadJobDone() const
+{
+ return m_readJobDone;
+}
+
+void CItem::SetReadJobDone(bool done)
+{
+ if (!IsReadJobDone() && done)
+ {
+ UpwardAddReadJobs(-1);
+ }
+ else
+ {
+ UpwardAddReadJobs(1 - m_readJobs);
+ }
+ m_readJobDone= done;
+
+}
+
+bool CItem::IsDone() const
+{
+ return m_done;
+}
+
+void CItem::SetDone()
+{
+ if (m_done)
+ return;
+
+ if (GetType() == IT_DRIVE && GetDocument()->OptionShowUnknown())
+ {
+ UpdateFreeSpaceItem();
+
+ CItem *unknown= FindUnknownItem();
+
+ LONGLONG total;
+ LONGLONG free;
+ MyGetDiskFreeSpace(GetPath(), total, free);
+
+ LONGLONG unknownspace= total - GetSize();
+ if (!GetDocument()->OptionShowFreeSpace())
+ unknownspace-= free;
+
+ // For CDs, the GetDiskFreeSpaceEx()-function is not correct.
+ if (unknownspace < 0)
+ {
+ TRACE(_T("GetDiskFreeSpace(%s) incorrect.\n"), GetPath());
+ unknownspace= 0;
+ }
+ unknown->SetSize(unknownspace);
+
+ UpwardAddSize(unknownspace);
+ }
+
+ for (int i=0; i < GetChildrenCount(); i++)
+ ASSERT(GetChild(i)->IsDone());
+
+ //m_children.FreeExtra(); // Doesn't help much.
+ qsort(m_children.GetData(), m_children.GetSize(), sizeof(CItem *), &_compareBySize);
+
+ m_rect.SetRectEmpty();
+
+ m_done= true;
+}
+
+DWORD CItem::GetTicksWorked() const
+{
+ return m_ticksWorked;
+}
+
+void CItem::AddTicksWorked(DWORD more)
+{
+ m_ticksWorked+= more;
+}
+
+void CItem::DoSomeWork(DWORD ticks)
+{
+ if (IsDone())
+ return;
+
+ StartPacman(true);
+
+ DriveVisualUpdateDuringWork();
+
+ DWORD start= GetTickCount();
+
+ if (GetType() == IT_DRIVE || GetType() == IT_DIRECTORY)
+ {
+ if (!IsReadJobDone())
+ {
+ LONGLONG dirCount= 0;
+ LONGLONG fileCount= 0;
+
+ CList<FILEINFO, FILEINFO> files;
+
+
+ CFileFind finder;
+ BOOL b= finder.FindFile(GetFindPattern());
+ while (b)
+ {
+ DriveVisualUpdateDuringWork();
+
+ b= finder.FindNextFile();
+ if (finder.IsDots())
+ continue;
+ if (finder.IsDirectory())
+ {
+ dirCount++;
+ AddDirectory(finder);
+ }
+ else
+ {
+ fileCount++;
+
+ FILEINFO fi;
+ fi.name= finder.GetFileName();
+ fi.length= finder.GetLength();
+ finder.GetLastWriteTime(&fi.lastWriteTime);
+ // (We don't use GetLastWriteTime(CTime&) here, because, if the file has
+ // an invalid timestamp, that function would ASSERT and throw an Exception.)
+
+ files.AddTail(fi);
+ }
+ }
+
+ CItem *filesFolder= 0;
+ if (dirCount > 0 && fileCount > 1)
+ {
+ filesFolder= new CItem(IT_FILESFOLDER, LoadString(IDS_FILES_ITEM));
+ filesFolder->SetReadJobDone();
+ AddChild(filesFolder);
+ }
+ else if (fileCount > 0)
+ {
+ filesFolder= this;
+ }
+
+ for (POSITION pos=files.GetHeadPosition(); pos != NULL; files.GetNext(pos))
+ {
+ const FILEINFO& fi= files.GetAt(pos);
+ filesFolder->AddFile(fi);
+ }
+
+ if (filesFolder != NULL)
+ {
+ filesFolder->UpwardAddFiles(fileCount);
+ if (dirCount > 0 && fileCount > 1)
+ filesFolder->SetDone();
+ }
+
+ UpwardAddSubdirs(dirCount);
+ SetReadJobDone();
+ AddTicksWorked(GetTickCount() - start);
+ }
+ if (GetType() == IT_DRIVE)
+ UpdateFreeSpaceItem();
+
+ if (GetTickCount() - start > ticks)
+ {
+ StartPacman(false);
+ return;
+ }
+ }
+ if (GetType() == IT_DRIVE || GetType() == IT_DIRECTORY || GetType() == IT_MYCOMPUTER)
+ {
+ ASSERT(IsReadJobDone());
+ if (IsDone())
+ {
+ StartPacman(false);
+ return;
+ }
+ if (GetChildrenCount() == 0)
+ {
+ SetDone();
+ StartPacman(false);
+ return;
+ }
+
+ DWORD startChildren= GetTickCount();
+ while (GetTickCount() - start < ticks)
+ {
+ DWORD minticks= UINT_MAX;
+ CItem *minchild= NULL;
+ for (int i=0; i < GetChildrenCount(); i++)
+ {
+ CItem *child= GetChild(i);
+ if (child->IsDone())
+ continue;
+ if (child->GetTicksWorked() < minticks)
+ {
+ minticks= child->GetTicksWorked();
+ minchild= child;
+ }
+ }
+ if (minchild == NULL)
+ {
+ SetDone();
+ break;
+ }
+ DWORD tickssofar= GetTickCount() - start;
+ if (ticks > tickssofar)
+ minchild->DoSomeWork(ticks - tickssofar);
+ }
+ AddTicksWorked(GetTickCount() - startChildren);
+ }
+ else
+ {
+ SetDone();
+ }
+ StartPacman(false);
+}
+
+// Return: false if deleted
+bool CItem::StartRefresh()
+{
+ ASSERT(GetType() != IT_FREESPACE);
+ ASSERT(GetType() != IT_UNKNOWN);
+
+ m_ticksWorked= 0;
+
+ // Special case IT_MYCOMPUTER
+ if (GetType() == IT_MYCOMPUTER)
+ {
+ ZeroMemory(&m_lastChange, sizeof(m_lastChange));
+
+ for (int i=0; i < GetChildrenCount(); i++)
+ GetChild(i)->StartRefresh();
+
+ return true;
+ }
+ ASSERT(GetType() == IT_FILE || GetType() == IT_DRIVE || GetType() == IT_DIRECTORY || GetType() == IT_FILESFOLDER);
+
+ bool wasExpanded= IsVisible() && IsExpanded();
+ int oldScrollPosition =0;
+ if (IsVisible())
+ oldScrollPosition= GetScrollPosition();
+
+ UncacheImage();
+
+ // Upward clear data
+ UpdateLastChange();
+
+ UpwardSetUndone();
+
+ UpwardAddReadJobs(-GetReadJobs());
+ ASSERT(GetReadJobs() == 0);
+
+ if (GetType() == IT_FILE)
+ GetParent()->UpwardAddFiles(-1);
+ else
+ UpwardAddFiles(-GetFilesCount());
+ ASSERT(GetFilesCount() == 0);
+
+ if (GetType() == IT_DIRECTORY || GetType() == IT_DRIVE)
+ UpwardAddSubdirs(-GetSubdirsCount());
+ ASSERT(GetSubdirsCount() == 0);
+
+ UpwardAddSize(-GetSize());
+ ASSERT(GetSize() == 0);
+
+ RemoveAllChildren();
+ UpwardRecalcLastChange();
+
+ // Special case IT_FILESFOLDER
+ if (GetType() == IT_FILESFOLDER)
+ {
+ CFileFind finder;
+ BOOL b= finder.FindFile(GetFindPattern());
+ while (b)
+ {
+ b= finder.FindNextFile();
+ if (finder.IsDirectory())
+ continue;
+
+ FILEINFO fi;
+ fi.name= finder.GetFileName();
+ fi.length= finder.GetLength();
+ finder.GetLastWriteTime(&fi.lastWriteTime);
+
+ AddFile(fi);
+ UpwardAddFiles(1);
+ }
+ SetDone();
+
+ if (wasExpanded)
+ GetTreeListControl()->ExpandItem(this);
+ return true;
+ }
+ ASSERT(GetType() == IT_FILE || GetType() == IT_DRIVE || GetType() == IT_DIRECTORY);
+
+ // The item may have been deleted.
+ bool deleted= false;
+ if (GetType() == IT_DRIVE)
+ deleted= !DriveExists(GetPath());
+ else if (GetType() == IT_FILE)
+ deleted= !FileExists(GetPath());
+ else if (GetType() == IT_DIRECTORY)
+ deleted= !FolderExists(GetPath());
+
+ if (deleted)
+ {
+ if (GetParent() == NULL)
+ {
+ GetDocument()->UnlinkRoot();
+ }
+ else
+ {
+ GetParent()->UpwardRecalcLastChange();
+ GetParent()->RemoveChild(GetParent()->FindChildIndex(this)); // --> delete this
+ }
+ return false;
+ }
+
+ // Case IT_FILE
+ if (GetType() == IT_FILE)
+ {
+ CFileFind finder;
+ BOOL b= finder.FindFile(GetPath());
+ if (b)
+ {
+ finder.FindNextFile();
+ if (!finder.IsDirectory())
+ {
+ FILEINFO fi;
+ fi.name= finder.GetFileName();
+ fi.length= finder.GetLength();
+ finder.GetLastWriteTime(&fi.lastWriteTime);
+
+ SetLastChange(fi.lastWriteTime);
+
+ UpwardAddSize(fi.length);
+ UpwardUpdateLastChange(GetLastChange());
+ UpwardAddFiles(1);
+ }
+ }
+ SetDone();
+ return true;
+ }
+
+ ASSERT(GetType() == IT_DRIVE || GetType() == IT_DIRECTORY);
+
+ if (GetType() == IT_DIRECTORY && !IsRootItem() && GetApp()->IsMountPoint(GetPath()) && !GetOptions()->IsFollowMountPoints())
+ return true;
+
+ // Initiate re-read
+ SetReadJobDone(false);
+
+ // Re-create <free space> and <unknown>
+ if (GetType() == IT_DRIVE)
+ {
+ if (GetDocument()->OptionShowFreeSpace())
+ CreateFreeSpaceItem();
+ if (GetDocument()->OptionShowUnknown())
+ CreateUnknownItem();
+ }
+
+ DoSomeWork(0);
+
+ if (wasExpanded)
+ GetTreeListControl()->ExpandItem(this);
+
+ if (IsVisible())
+ SetScrollPosition(oldScrollPosition);
+
+ return true;
+}
+
+void CItem::UpwardSetUndone()
+{
+ if (GetType() == IT_DRIVE && IsDone() && GetDocument()->OptionShowUnknown())
+ {
+ for (int i=0; i < GetChildrenCount(); i++)
+ if (GetChild(i)->GetType() == IT_UNKNOWN)
+ break;
+ CItem *unknown= GetChild(i);
+
+ UpwardAddSize(- unknown->GetSize());
+
+ unknown->SetSize(0);
+ }
+
+ m_done= false;
+
+ if (GetParent() != NULL)
+ GetParent()->UpwardSetUndone();
+}
+
+void CItem::RefreshRecycler()
+{
+ ASSERT(GetType() == IT_DRIVE);
+ DWORD dummy;
+ CString system;
+ BOOL b= GetVolumeInformation(GetPath(), NULL, 0, NULL, &dummy, &dummy, system.GetBuffer(128), 128);
+ system.ReleaseBuffer();
+ if (!b)
+ {
+ TRACE(_T("GetVolumeInformation(%s) failed.\n"), GetPath());
+ return; // nix zu machen
+ }
+
+ CString recycler;
+ if (system.CompareNoCase(_T("NTFS")) == 0)
+ {
+ recycler= _T("recycler");
+ }
+ else if (system.CompareNoCase(_T("FAT32")) == 0)
+ {
+ recycler= _T("recycled");
+ }
+ else
+ {
+ TRACE(_T("%s: unknown file system type %s\n"), GetPath(), system);
+ return; // nix zu machen.
+ }
+
+ for (int i=0; i < GetChildrenCount(); i++)
+ {
+ if (GetChild(i)->GetName().CompareNoCase(recycler) == 0)
+ break;
+ }
+ if (i >= GetChildrenCount())
+ {
+ TRACE(_T("%s: Recycler(%s) not found.\n"), GetPath(), recycler);
+ return; // nicht gefunden
+ }
+
+ GetChild(i)->StartRefresh();
+}
+
+void CItem::CreateFreeSpaceItem()
+{
+ ASSERT(GetType() == IT_DRIVE);
+
+ UpwardSetUndone();
+
+ LONGLONG total;
+ LONGLONG free;
+ MyGetDiskFreeSpace(GetPath(), total, free);
+
+ CItem *freespace= new CItem(IT_FREESPACE, GetFreeSpaceItemName());
+ freespace->SetSize(free);
+ freespace->SetDone();
+
+ AddChild(freespace);
+}
+
+CItem *CItem::FindFreeSpaceItem() const
+{
+ int i= FindFreeSpaceItemIndex();
+ if (i < GetChildrenCount())
+ return GetChild(i);
+ else
+ return NULL;
+}
+
+
+void CItem::UpdateFreeSpaceItem()
+{
+ ASSERT(GetType() == IT_DRIVE);
+
+ if (!GetDocument()->OptionShowFreeSpace())
+ return;
+
+ CItem *freeSpaceItem= FindFreeSpaceItem();
+ ASSERT(freeSpaceItem != NULL);
+
+ LONGLONG total;
+ LONGLONG free;
+ MyGetDiskFreeSpace(GetPath(), total, free);
+
+ LONGLONG before= freeSpaceItem->GetSize();
+ LONGLONG diff= free - before;
+
+ freeSpaceItem->UpwardAddSize(diff);
+}
+
+void CItem::RemoveFreeSpaceItem()
+{
+ ASSERT(GetType() == IT_DRIVE);
+
+ UpwardSetUndone();
+
+ int i= FindFreeSpaceItemIndex();
+ ASSERT(i < GetChildrenCount());
+
+ CItem *freespace= GetChild(i);
+
+ UpwardAddSize(-freespace->GetSize());
+
+ RemoveChild(i);
+}
+
+void CItem::CreateUnknownItem()
+{
+ ASSERT(GetType() == IT_DRIVE);
+
+ UpwardSetUndone();
+
+ CItem *unknown= new CItem(IT_UNKNOWN, GetUnknownItemName());
+ unknown->SetDone();
+
+ AddChild(unknown);
+}
+
+CItem *CItem::FindUnknownItem() const
+{
+ int i= FindUnknownItemIndex();
+ if (i < GetChildrenCount())
+ return GetChild(i);
+ else
+ return NULL;
+}
+
+void CItem::RemoveUnknownItem()
+{
+ ASSERT(GetType() == IT_DRIVE);
+
+ UpwardSetUndone();
+
+ int i= FindUnknownItemIndex();
+ ASSERT(i < GetChildrenCount());
+
+ CItem *unknown= GetChild(i);
+
+ UpwardAddSize(-unknown->GetSize());
+
+ RemoveChild(i);
+}
+
+CItem *CItem::FindDirectoryByPath(const CString& path)
+{
+ CString myPath= GetPath();
+ myPath.MakeLower();
+
+ int i=0;
+ while (i < myPath.GetLength() && i < path.GetLength() && myPath[i] == path[i])
+ i++;
+
+ if (i < myPath.GetLength())
+ return NULL;
+
+ if (i >= path.GetLength())
+ {
+ ASSERT(myPath == path);
+ return this;
+ }
+
+ for (i=0; i < GetChildrenCount(); i++)
+ {
+ CItem *item= GetChild(i)->FindDirectoryByPath(path);
+ if (item != NULL)
+ return item;
+ }
+
+ return NULL;
+}
+
+void CItem::RecurseCollectExtensionData(CExtensionData *ed)
+{
+ UpdateRamUsage();
+
+ if (IsLeaf(GetType()))
+ {
+ if (GetType() == IT_FILE)
+ {
+ CString ext= GetExtension();
+ SExtensionRecord r;
+ if (ed->Lookup(ext, r))
+ {
+ r.bytes+= GetSize();
+ r.files++;
+ }
+ else
+ {
+ r.bytes= GetSize();
+ r.files= 1;
+ }
+ ed->SetAt(ext, r);
+ }
+ }
+ else
+ {
+ for (int i=0; i < GetChildrenCount(); i++)
+ {
+ GetChild(i)->RecurseCollectExtensionData(ed);
+ }
+ }
+}
+
+void CItem::DrawGraph(CDC *pdc, CRect rc) const
+{
+ //pdc->FillSolidRect(rc, RGB(255,0,0)); // This is a test. There shouldn't be any leaks
+
+/* DWORD start= GetTickCount(); */
+
+ // Pen for grid. This pen remains selected during the recursive drawing.
+ CPen pen(PS_SOLID, 1, GetOptions()->GetTreemapGridColor());
+ CSelectObject sopen(pdc, &pen);
+
+ if (GetOptions()->IsTreemapGrid())
+ {
+ pdc->FillSolidRect(rc, GetOptions()->GetTreemapGridColor());
+ }
+
+ double surface[4];
+ for (int i=0; i < 4; i++)
+ surface[i]= 0;
+
+ RecurseDrawGraph(pdc, rc, true, surface, GetOptions()->GetHeightFactor()/100.0, GetOptions()->GetScaleFactor() / 100.0);
+
+/* DWORD time= GetTickCount() - start;
+ CString s;
+ s.Format("%d ms", time);
+ AfxMessageBox(s);
+*/
+
+#ifdef _STRONG_DEBUG
+ int bottom= rc.bottom;
+ int right= rc.right;
+ if (GetOptions()->IsTreemapGrid())
+ {
+ bottom--;
+ right--;
+ }
+ for (int y=rc.top; y < bottom; y++)
+ for (int x=rc.left; x < right; x++)
+ ASSERT(NULL != FindChildByPoint(CPoint(x, y)));
+#endif
+}
+
+CRect CItem::GetRect() const
+{
+ return m_rect;
+}
+
+const CItem *CItem::FindChildByPoint(CPoint point) const
+{
+ ASSERT(IsDone());
+
+ const CItem *item= NULL;
+
+ if (m_rect.PtInRect(point))
+ {
+ for (int i=0; i < GetChildrenCount(); i++)
+ {
+ if (GetChild(i)->GetRect().PtInRect(point))
+ {
+ item= GetChild(i)->FindChildByPoint(point);
+ break;
+ }
+ }
+ if (item == NULL)
+ {
+ item= this;
+ }
+ }
+ return item;
+}
+
+int __cdecl CItem::_compareBySize(const void *p1, const void *p2)
+{
+ CItem *item1= *(CItem **)p1;
+ CItem *item2= *(CItem **)p2;
+
+ LONGLONG size1= item1->GetSize();
+ LONGLONG size2= item2->GetSize();
+
+ // TODO: Use 2nd sort column (as set in our TreeListView?)
+
+ return signum(size2 - size1); // biggest first
+}
+
+LONGLONG CItem::GetProgressRangeMyComputer() const
+{
+ ASSERT(GetType() == IT_MYCOMPUTER);
+
+ LONGLONG range= 0;
+ for (int i=0; i < GetChildrenCount(); i++)
+ {
+ range+= GetChild(i)->GetProgressRangeDrive();
+ }
+ return range;
+}
+
+LONGLONG CItem::GetProgressPosMyComputer() const
+{
+ ASSERT(GetType() == IT_MYCOMPUTER);
+
+ LONGLONG pos= 0;
+ for (int i=0; i < GetChildrenCount(); i++)
+ {
+ pos+= GetChild(i)->GetProgressPosDrive();
+ }
+ return pos;
+}
+
+LONGLONG CItem::GetProgressRangeDrive() const
+{
+ LONGLONG total;
+ LONGLONG free;
+ MyGetDiskFreeSpace(GetPath(), total, free);
+
+ LONGLONG range= total - free;
+
+ ASSERT(range >= 0);
+ return range;
+}
+
+LONGLONG CItem::GetProgressPosDrive() const
+{
+ LONGLONG pos= GetSize();
+
+ CItem *fs= FindFreeSpaceItem();
+ if (fs != NULL)
+ {
+ pos-= fs->GetSize();
+ }
+
+ return pos;
+}
+
+void CItem::RecurseDrawGraph(
+ CDC *pdc, // Device Context
+ const CRect& rc, // Rectangle, where to draw item
+ bool asroot, // If we are the root (zoom) item
+ const double *psurface, // Coefficients so far
+ double h, // Height factor
+ double f // Scale factor
+) const
+{
+ ASSERT(IsDone());
+ ASSERT(rc.Width() >= 0);
+ ASSERT(rc.Height() >= 0);
+
+ // The application may have been paged out by the system.
+ // When the user tops it again an manipulates, for example, the splitter,
+ // then the treemap is repainted and so everything must be paged in again.
+ // That can last a long time (30 sec).
+ // In order to give some visual feedback, we periodically update the RAM usage indicator.
+ UpdateRamUsage();
+
+ m_rect= rc;
+
+ int gridWidth= GetOptions()->IsTreemapGrid() ? 1 : 0;
+
+ if (m_rect.Width() <= gridWidth || m_rect.Height() <= gridWidth)
+ {
+ return;
+ }
+
+ double surface[4];
+
+ if (GetOptions()->IsCushionShading())
+ {
+ for (int i=0; i < 4; i++)
+ surface[i]= psurface[i];
+
+ if (!asroot)
+ AddRidge(m_rect, surface, h);
+ }
+
+ if (GetChildrenCount() > 0)
+ {
+ CArray<double, double> rows; // Our rectangle is divided into rows, each of which gets this height (fraction of total height).
+ CArray<int, int> childrenPerRow;// childrenPerRow[i] = # of children in rows[i]
+
+ CArray<double, double> childWidth; // Widths of the children (fraction of row width).
+ childWidth.SetSize(GetChildrenCount());
+
+ bool horizontalRows= ArrangeChildren(childWidth, rows, childrenPerRow);
+
+ const int width= horizontalRows ? rc.Width() : rc.Height();
+ const int height= horizontalRows ? rc.Height() : rc.Width();
+ ASSERT(width >= 0);
+ ASSERT(height >= 0);
+
+ int c = 0;
+ double top= horizontalRows ? rc.top : rc.left;
+ for (int row=0; row < rows.GetSize(); row++)
+ {
+ double fBottom= top + rows[row] * height;
+ int bottom= (int)fBottom;
+ if (row == rows.GetSize() - 1)
+ bottom= horizontalRows ? rc.bottom : rc.right;
+ double left= horizontalRows ? rc.left : rc.top;
+ for (int i=0; i < childrenPerRow[row]; i++, c++)
+ {
+ CItem *child= GetChild(c);
+ ASSERT(child->IsDone());
+ ASSERT(childWidth[c] >= 0);
+ double fRight= left + childWidth[c] * width;
+ int right= (int)fRight;
+ if (i == childrenPerRow[row] - 1)
+ right= horizontalRows ? rc.right : rc.bottom;
+
+ CRect rcChild;
+ if (horizontalRows)
+ {
+ rcChild.left= (int)left;
+ rcChild.right= right;
+ rcChild.top= (int)top;
+ rcChild.bottom= bottom;
+ }
+ else
+ {
+ rcChild.left= (int)top;
+ rcChild.right= bottom;
+ rcChild.top= (int)left;
+ rcChild.bottom= right;
+ }
+
+ #ifdef _DEBUG
+ if (rcChild.Width() > 0 && rcChild.Height() > 0)
+ {
+ CRect test;
+ test.IntersectRect(m_rect, rcChild);
+ ASSERT(test == rcChild);
+ }
+ #endif
+
+ child->RecurseDrawGraph(pdc, rcChild, false, surface, h * f, f);
+ left= fRight;
+ }
+ // This asserts due to rounding error: ASSERT(left == (horizontalRows ? rc.right : rc.bottom));
+ top= fBottom;
+ }
+ // This asserts due to rounding error: ASSERT(top == (horizontalRows ? rc.bottom : rc.right));
+ }
+ else
+ {
+ RenderLeaf(pdc, surface);
+ }
+}
+
+// return: whether the rows are horizontal.
+bool CItem::ArrangeChildren(
+ CArray<double, double>& childWidth,
+ CArray<double, double>& rows,
+ CArray<int, int>& childrenPerRow
+) const
+{
+ ASSERT(IsDone());
+ ASSERT(GetChildrenCount() > 0);
+
+ if (GetSize() == 0)
+ {
+ rows.Add(1.0);
+ childrenPerRow.Add(GetChildrenCount());
+ for (int i=0; i < GetChildrenCount(); i++)
+ childWidth[i]= 1.0 / GetChildrenCount();
+ return true;
+ }
+
+ bool horizontalRows= (m_rect.Width() >= m_rect.Height());
+
+ double width= 1.0;
+ if (horizontalRows)
+ {
+ if (m_rect.Height() > 0)
+ width= (double)m_rect.Width() / m_rect.Height();
+ }
+ else
+ {
+ if (m_rect.Width() > 0)
+ width= (double)m_rect.Height() / m_rect.Width();
+ }
+
+ int nextChild= 0;
+ while (nextChild < GetChildrenCount())
+ {
+ int childrenUsed;
+ rows.Add(CalcutateNextRow(nextChild, width, childrenUsed, childWidth));
+ childrenPerRow.Add(childrenUsed);
+ nextChild+= childrenUsed;
+ }
+
+ return horizontalRows;
+}
+
+double CItem::CalcutateNextRow(const int nextChild, double width, int& childrenUsed, CArray<double, double>& childWidth) const
+{
+ ASSERT(IsDone());
+
+ static const double _minProportion = 0.4;
+ ASSERT(_minProportion < 1);
+
+ ASSERT(nextChild < GetChildrenCount());
+ ASSERT(width >= 1.0);
+
+ const double mySize= (double)GetSize();
+ ASSERT(mySize > 0);
+ LONGLONG sizeUsed= 0;
+ double rowHeight= 0;
+
+ for (int i=nextChild; i < GetChildrenCount(); i++)
+ {
+ LONGLONG childSize= GetChild(i)->GetSize();
+ if (childSize == 0)
+ {
+ ASSERT(i > nextChild); // first child has size > 0
+ break;
+ }
+
+ sizeUsed+= childSize;
+ double virtualRowHeight= sizeUsed / mySize;
+ ASSERT(virtualRowHeight > 0);
+ ASSERT(virtualRowHeight <= 1);
+
+ // Rectangle(mySize) = width * 1.0
+ // Rectangle(childSize) = childWidth * virtualRowHeight
+ // Rectangle(childSize) = childSize / mySize * width
+
+ double childWidth= childSize / mySize * width / virtualRowHeight;
+
+ if (childWidth / virtualRowHeight < _minProportion)
+ {
+ ASSERT(i > nextChild); // because width >= 1 and _minProportion < 1.
+ // For the first child we have:
+ // childWidth / rowHeight
+ // = childSize / mySize * width / rowHeight / rowHeight
+ // = childSize * width / sizeUsed / sizeUsed * mySize
+ // > childSize * mySize / sizeUsed / sizeUsed
+ // > childSize * childSize / childSize / childSize
+ // = 1 > _minProportion.
+ break;
+ }
+ rowHeight= virtualRowHeight;
+ }
+ ASSERT(i > nextChild);
+
+ // Now i-1 is the last child used
+ // and rowHeight is the height of the row.
+
+ // We add the rest of the children, if their size is 0.
+ while (i < GetChildrenCount() && GetChild(i)->GetSize() == 0)
+ i++;
+
+ childrenUsed= i - nextChild;
+
+ // Now as we know the rowHeight, we compute the widths of our children.
+ for (i=0; i < childrenUsed; i++)
+ {
+ // Rectangle(1.0 * 1.0) = mySize
+ double rowSize= mySize * rowHeight;
+ double childSize= (double)GetChild(nextChild + i)->GetSize();
+ double cw= childSize / rowSize;
+ ASSERT(cw >= 0);
+ childWidth[nextChild + i]= cw;
+ }
+
+ return rowHeight;
+}
+
+COLORREF CItem::GetGraphColor() const
+{
+ COLORREF color;
+
+ switch (GetType())
+ {
+ case IT_UNKNOWN:
+ color= RGB(255,255,0);
+ break;
+
+ case IT_FREESPACE:
+ color= RGB(100,100,100);
+ break;
+
+ case IT_FILE:
+ color= GetDocument()->GetCushionColor(GetExtension());
+ break;
+
+ default:
+ color= RGB(0,0,0);
+ break;
+ }
+
+ return color;
+}
+
+bool CItem::MustShowReadJobs() const
+{
+ if (GetParent() != NULL)
+ {
+ return !GetParent()->IsDone();
+ }
+ else
+ {
+ return !IsDone();
+ }
+}
+
+COLORREF CItem::GetPercentageColor() const
+{
+ int i= GetIndent() % GetOptions()->GetTreelistColorCount();
+ return GetOptions()->GetTreelistColor(i);
+}
+
+int CItem::FindFreeSpaceItemIndex() const
+{
+ for (int i=0; i < GetChildrenCount(); i++)
+ {
+ if (GetChild(i)->GetType() == IT_FREESPACE)
+ break;
+ }
+ return i; // maybe == GetChildrenCount() (=> not found)
+}
+
+int CItem::FindUnknownItemIndex() const
+{
+ for (int i=0; i < GetChildrenCount(); i++)
+ {
+ if (GetChild(i)->GetType() == IT_UNKNOWN)
+ break;
+ }
+ return i; // maybe == GetChildrenCount() (=> not found)
+}
+
+void CItem::RenderLeaf(CDC *pdc, const double *surface) const
+{
+ CRect rc= m_rect;
+ if (GetOptions()->IsTreemapGrid())
+ {
+ rc.top++;
+ rc.left++;
+ if (rc.Width() <= 0 || rc.Height() <= 0)
+ return;
+ }
+
+ ::RenderRectangle(pdc, rc, surface, GetGraphColor());
+}
+
+CString CItem::UpwardGetPathWithoutBackslash() const
+{
+ CString path;
+ if (GetParent() != NULL)
+ path= GetParent()->UpwardGetPathWithoutBackslash();
+
+ switch (GetType())
+ {
+ case IT_MYCOMPUTER:
+ // empty
+ break;
+
+ case IT_DRIVE:
+ // (we don't use our parent's path here.)
+ path= PathFromVolumeName(m_name);
+ break;
+
+ case IT_DIRECTORY:
+ if (!path.IsEmpty())
+ path+= _T("\\");
+ path+= m_name;
+ break;
+
+ case IT_FILE:
+ path+= _T("\\") + m_name;
+ break;
+
+ case IT_FILESFOLDER:
+ break;
+
+ case IT_FREESPACE:
+ case IT_UNKNOWN:
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ return path;
+}
+
+void CItem::AddDirectory(CFileFind& finder)
+{
+ bool dontFollow= GetApp()->IsMountPoint(finder.GetFilePath()) && !GetOptions()->IsFollowMountPoints();
+
+ CItem *child= new CItem(IT_DIRECTORY, finder.GetFileName(), dontFollow);
+ FILETIME t;
+ finder.GetLastWriteTime(&t);
+ child->SetLastChange(t);
+ AddChild(child);
+}
+
+void CItem::AddFile(const FILEINFO& fi)
+{
+ CItem *child= new CItem(IT_FILE, fi.name);
+ child->SetSize(fi.length);
+ child->SetLastChange(fi.lastWriteTime);
+ child->SetDone();
+
+ AddChild(child);
+}
+
+void CItem::DriveVisualUpdateDuringWork()
+{
+ MSG msg;
+ while (PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE))
+ DispatchMessage(&msg);
+
+ GetMainFrame()->DrivePacman();
+ UpwardDrivePacman();
+}
+
+void CItem::UpwardDrivePacman()
+{
+ if (!GetOptions()->IsPacmanAnimation())
+ return;
+
+ DrivePacman();
+ if (GetParent() != NULL)
+ GetParent()->UpwardDrivePacman();
+}
+
+void CItem::DrivePacman()
+{
+ if (!IsVisible())
+ return;
+
+ if (!CTreeListItem::DrivePacman(GetReadJobs()))
+ return;
+
+ CClientDC dc(GetTreeListControl());
+ CRect rc= GetTreeListControl()->GetWholeSubitemRect(GetTreeListControl()->FindTreeItem(this), COL_SUBTREEPERCENTAGE);
+ rc.DeflateRect(sizeDeflatePacman);
+ DrawPacman(&dc, rc);
+}
+
+void CItem::UpdateRamUsage()
+{
+ if (GetTickCount() - _m_lastRamUsageUpdate > 1200)
+ {
+ GetApp()->UpdateRamUsage();
+ _m_lastRamUsageUpdate= GetTickCount();
+ }
+}
+
+
diff --git a/windirstat/item.h b/windirstat/item.h
new file mode 100644
index 0000000..2330c09
--- /dev/null
+++ b/windirstat/item.h
@@ -0,0 +1,224 @@
+// item.h - Declaration of CItem
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "Treelistcontrol.h"
+#include "dirstatdoc.h" // CExtensionData
+
+
+// Columns
+enum
+{
+ COL_NAME,
+ COL_SUBTREEPERCENTAGE,
+ COL_PERCENTAGE,
+ COL_SUBTREETOTAL,
+ COL_ITEMS,
+ COL_FILES,
+ COL_SUBDIRS,
+ COL_LASTCHANGE
+};
+
+// Item types
+enum ITEMTYPE
+{
+ IT_MYCOMPUTER, // Pseudo Container "My Computer"
+ IT_DRIVE, // C:\, D:\ etc.
+ IT_DIRECTORY, // Folder
+ IT_FILE, // Regular file
+ IT_FILESFOLDER, // Pseudo Folder "<Files>"
+ IT_FREESPACE, // Pseudo File "<Free Space>"
+ IT_UNKNOWN, // Pseudo File "<Unknown>"
+
+ ITF_FLAGS = 0xF000,
+ ITF_ROOTITEM = 0x8000 // This is an additional flag, not a type.
+};
+
+// Whether an item type is a leaf type
+inline bool IsLeaf(ITEMTYPE t) { return t == IT_FILE || t == IT_FREESPACE || t == IT_UNKNOWN; }
+
+// Compare FILETIMEs
+inline bool operator< (const FILETIME& t1, const FILETIME& t2)
+{
+ ULARGE_INTEGER& u1= (ULARGE_INTEGER&)t1;
+ ULARGE_INTEGER& u2= (ULARGE_INTEGER&)t2;
+
+ return (u1.QuadPart < u2.QuadPart);
+}
+
+// Compare FILETIMEs
+inline bool operator== (const FILETIME& t1, const FILETIME& t2)
+{
+ return t1.dwLowDateTime == t2.dwLowDateTime && t1.dwHighDateTime == t2.dwHighDateTime;
+}
+
+//
+// CItem. This is the object, from which the whole tree is built.
+// For every directory, file etc., we find on the Harddisks, there is one CItem.
+// It is derived from CTreeListItem because it _may_ become "visible" and therefore
+// may be inserted in the TreeList view (we don't clone any data).
+//
+// Of cource, this class and the base classes are optimized rather for size than for speed.
+//
+// The m_type indicates whether we are a file or a folder or a drive etc.
+// It may have been better to design a class hierarchy for this, but I can't help it,
+// rather than browsing to virtual functions I like to flatly see what's going on.
+// But, of course, now we have quite many switch statements in the member functions.
+//
+// Naming convention:
+// Methods which recurse down to every child (expensive) are named "RecurseDoSomething".
+// Methods which recurse up to the parent (not so expensive) are named "UpwardDoDomething".
+//
+class CItem: public CTreeListItem
+{
+ // We collect data of files in FILEINFOs before we create items for them,
+ // because we need to know their count before we can decide whether or not
+ // we have to create a <Files> item. (A <Files> item is only created, when
+ // (a) there are more than one files and (b) there are subdirectories.)
+ struct FILEINFO
+ {
+ CString name;
+ LONGLONG length;
+ FILETIME lastWriteTime;
+ };
+
+public:
+ CItem(ITEMTYPE type, LPCTSTR name, bool dontFollow=false);
+ ~CItem();
+
+ // CTreeListItem Interface
+ virtual bool DrawSubitem(int subitem, CDC *pdc, CRect rc, UINT state, int *width) const;
+ virtual CString GetText(int subitem) const;
+ virtual int CompareSibling(const CTreeListItem *tlib, int subitem) const;
+ virtual int GetChildrenCount() const;
+ virtual CTreeListItem *GetTreeListChild(int i) const;
+ virtual int GetImageToCache() const;
+ virtual void DrawAdditionalState(CDC *pdc, const CRect& rcLabel) const;
+
+ // CItem
+ static int GetSubtreePercentageWidth();
+ static CItem *FindCommonAncestor(const CItem *item1, const CItem *item2);
+
+ bool IsAncestorOf(const CItem *item) const;
+ LONGLONG GetProgressRange() const;
+ LONGLONG GetProgressPos() const;
+ const CItem *UpwardGetRoot() const;
+ void UpdateLastChange();
+ CItem *GetChild(int i) const;
+ CItem *GetParent() const;
+ int FindChildIndex(const CItem *child) const;
+ void AddChild(CItem *child);
+ void RemoveChild(int i);
+ void RemoveAllChildren();
+ void UpwardAddSubdirs(LONGLONG dirCount);
+ void UpwardAddFiles(LONGLONG fileCount);
+ void UpwardAddSize(LONGLONG bytes);
+ void UpwardAddReadJobs(/* signed */LONGLONG count);
+ void UpwardUpdateLastChange(const FILETIME& t);
+ void UpwardRecalcLastChange();
+ LONGLONG GetSize() const;
+ void SetSize(LONGLONG ownSize);
+ LONGLONG GetReadJobs() const;
+ FILETIME GetLastChange() const;
+ void SetLastChange(const FILETIME& t);
+ double GetFraction() const;
+ ITEMTYPE GetType() const;
+ bool IsRootItem() const;
+ CString GetPath() const;
+ CString GetFindPattern() const;
+ CString GetFolderPath() const;
+ CString GetReportPath() const;
+ CString GetName() const;
+ CString GetExtension() const;
+ LONGLONG GetFilesCount() const;
+ LONGLONG GetSubdirsCount() const;
+ LONGLONG GetItemsCount() const;
+ bool IsReadJobDone() const;
+ void SetReadJobDone(bool done=true);
+ bool IsDone() const;
+ void SetDone();
+ DWORD GetTicksWorked() const;
+ void AddTicksWorked(DWORD more);
+ void DoSomeWork(DWORD ticks);
+ bool StartRefresh();
+ void UpwardSetUndone();
+ void RefreshRecycler();
+ void CreateFreeSpaceItem();
+ CItem *FindFreeSpaceItem() const;
+ void UpdateFreeSpaceItem();
+ void RemoveFreeSpaceItem();
+ void CreateUnknownItem();
+ CItem *FindUnknownItem() const;
+ void RemoveUnknownItem();
+ CItem *FindDirectoryByPath(const CString& path);
+ void RecurseCollectExtensionData(CExtensionData *ed);
+
+ // for GraphView
+ void DrawGraph(CDC *pdc, CRect rc) const;
+ CRect GetRect() const;
+ const CItem *FindChildByPoint(CPoint point) const;
+
+private:
+ static int __cdecl _compareBySize(const void *p1, const void *p2);
+ LONGLONG GetProgressRangeMyComputer() const;
+ LONGLONG GetProgressPosMyComputer() const;
+ LONGLONG GetProgressRangeDrive() const;
+ LONGLONG GetProgressPosDrive() const;
+ void RecurseDrawGraph(CDC *pdc, const CRect& rc, bool asroot, const double *surface, double h, double f) const;
+ bool ArrangeChildren(CArray<double, double>& childWidth, CArray<double, double>& rows, CArray<int, int>& childrenPerRow) const;
+ double CalcutateNextRow(const int nextChild, double width, int& childrenUsed, CArray<double, double>& childWidth) const;
+ COLORREF GetGraphColor() const;
+ bool MustShowReadJobs() const;
+ COLORREF GetPercentageColor() const;
+ int FindFreeSpaceItemIndex() const;
+ int FindUnknownItemIndex() const;
+ void RenderLeaf(CDC *pdc, const double *surface) const;
+ CString UpwardGetPathWithoutBackslash() const;
+ void AddDirectory(CFileFind& finder);
+ void AddFile(const FILEINFO& fi);
+ void DriveVisualUpdateDuringWork();
+ void UpwardDrivePacman();
+ void DrivePacman();
+
+ static void UpdateRamUsage();
+ static DWORD _m_lastRamUsageUpdate; // Tick count. Used during DrawGraph().
+
+ ITEMTYPE m_type; // Indicates our type. See ITEMTYPE.
+ CString m_name; // Display name
+ LONGLONG m_size; // OwnSize, if IT_FILE or IT_FREESPACE, or IT_UNKNOWN; SubtreeTotal else.
+ LONGLONG m_files; // # Files in subtree
+ LONGLONG m_subdirs; // # Folder in subtree
+ FILETIME m_lastChange; // Last modification time OF SUBTREE
+
+ bool m_readJobDone; // FindFiles() (our own read job) is finished.
+ bool m_done; // Whole Subtree is done.
+ DWORD m_ticksWorked; // ms time spent on this item.
+ LONGLONG m_readJobs; // # "read jobs" in subtree.
+
+
+ // Our children. When "this" is set to "done", this array is sorted by child size.
+ CArray<CItem *, CItem *> m_children;
+
+ // For GraphView:
+ mutable CRect m_rect; // Finally, this is our coordinates in the Treemap view.
+};
+
diff --git a/windirstat/layout.cpp b/windirstat/layout.cpp
new file mode 100644
index 0000000..6824630
--- /dev/null
+++ b/windirstat/layout.cpp
@@ -0,0 +1,115 @@
+// layout.cpp - Implementation of CLayout
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "options.h"
+#include "layout.h"
+
+
+CLayout::CLayout(CWnd *dialog, LPCTSTR name)
+{
+ ASSERT(dialog != NULL);
+ m_dialog= dialog;
+ m_name= name;
+
+ // This is necessary because OnGetMinMaxInfo() will be called
+ // before OnInitDialog!
+ m_originalDialogSize.cx= 0;
+ m_originalDialogSize.cy= 0;
+}
+
+void CLayout::AddControl(CWnd *control, double movex, double movey, double stretchx, double stretchy)
+{
+ SControlInfo info;
+
+ info.control= control;
+ info.movex= movex;
+ info.movey= movey;
+ info.stretchx= stretchx;
+ info.stretchy= stretchy;
+
+ m_control.Add(info);
+}
+
+void CLayout::AddControl(UINT id, double movex, double movey, double stretchx, double stretchy)
+{
+ AddControl(m_dialog->GetDlgItem(id), movex, movey, stretchx, stretchy);
+}
+
+void CLayout::OnInitDialog(bool centerWindow)
+{
+ m_dialog->SetIcon(GetApp()->LoadIcon(IDR_MAINFRAME), false);
+
+ CRect rc;
+ m_dialog->GetWindowRect(rc);
+ m_originalDialogSize= rc.Size();
+
+ for (int i=0; i < m_control.GetSize(); i++)
+ {
+ CRect rc;
+ m_control[i].control->GetWindowRect(rc);
+ m_dialog->ScreenToClient(rc);
+ m_control[i].originalRectangle= rc;
+ }
+
+ CPersistence::GetDialogRectangle(m_name, rc);
+ m_dialog->MoveWindow(rc);
+ if (centerWindow)
+ m_dialog->CenterWindow();
+}
+
+void CLayout::OnDestroy()
+{
+ CRect rc;
+ m_dialog->GetWindowRect(rc);
+ CPersistence::SetDialogRectangle(m_name, rc);
+}
+
+void CLayout::OnSize()
+{
+ CRect rc;
+ m_dialog->GetWindowRect(rc);
+ CSize newDialogSize= rc.Size();
+
+ CSize diff= newDialogSize - m_originalDialogSize;
+
+ for (int i=0; i < m_control.GetSize(); i++)
+ {
+ CRect rc= m_control[i].originalRectangle;
+
+ CSize move(int(diff.cx * m_control[i].movex), int(diff.cy * m_control[i].movey));
+ CRect stretch(0, 0, int(diff.cx * m_control[i].stretchx), int(diff.cy * m_control[i].stretchy));
+
+ rc+= move;
+ rc+= stretch;
+
+ m_control[i].control->MoveWindow(rc);
+ }
+}
+
+void CLayout::OnGetMinMaxInfo(MINMAXINFO *mmi)
+{
+ mmi->ptMinTrackSize.x= m_originalDialogSize.cx;
+ mmi->ptMinTrackSize.y= m_originalDialogSize.cy;
+}
+
+
diff --git a/windirstat/layout.h b/windirstat/layout.h
new file mode 100644
index 0000000..3b50a96
--- /dev/null
+++ b/windirstat/layout.h
@@ -0,0 +1,56 @@
+// layout.h - Declaration of CLayout
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+//
+// CLayout. A poor men's dialog layout mechanism.
+// Simple, flat, and sufficient for our purposes.
+//
+class CLayout
+{
+ struct SControlInfo
+ {
+ CWnd *control;
+ double movex;
+ double movey;
+ double stretchx;
+ double stretchy;
+
+ CRect originalRectangle;
+ };
+
+public:
+ CLayout(CWnd *dialog, LPCTSTR name);
+ void AddControl(CWnd *control, double movex, double movey, double stretchx, double stretchy);
+ void AddControl(UINT id, double movex, double movey, double stretchx, double stretchy);
+
+ void OnInitDialog(bool centerWindow);
+ void OnSize();
+ void OnGetMinMaxInfo(MINMAXINFO *mmi);
+ void OnDestroy();
+
+protected:
+ CWnd *m_dialog;
+ CString m_name;
+ CSize m_originalDialogSize;
+ CArray<SControlInfo, SControlInfo&> m_control;
+};
diff --git a/windirstat/mainframe.cpp b/windirstat/mainframe.cpp
new file mode 100644
index 0000000..f4a8625
--- /dev/null
+++ b/windirstat/mainframe.cpp
@@ -0,0 +1,933 @@
+// mainframe.cpp - Implementation of CMySplitterWnd, CPacmanControl and CMainFrame
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+
+#include "graphview.h"
+#include "dirstatview.h"
+#include "typeview.h"
+#include "dirstatdoc.h"
+#include "osspecific.h"
+#include "item.h"
+#include "modalsendmail.h"
+
+#include "pagecleanups.h"
+#include "pagetreelist.h"
+#include "pagetreemap.h"
+#include "pagegeneral.h"
+
+#include ".\mainframe.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+namespace
+{
+ // This must be synchronized with the IDR_MAINFRAME menu
+ enum TOPLEVELMENU
+ {
+ TLM_FILE,
+ TLM_EDIT,
+ TLM_CLEANUP,
+ TLM_TREEMAP,
+ TLM_REPORT,
+ TLM_VIEW,
+ TLM_HELP
+ };
+
+ enum
+ {
+ // This is the position of the first "User defined cleanup" menu item in the "Cleanup" menu.
+ // !!! MUST BE SYNCHRONIZED WITH THE MENU RESOURCE !!!
+ MAINMENU_USERDEFINEDCLEANUP_POSITION = 11
+ };
+
+ enum
+ {
+ IDC_SUSPEND = 4712 // ID of "Suspend"-Button
+ };
+
+ // Clipboard-Opener
+ class COpenClipboard
+ {
+ public:
+ COpenClipboard(CWnd *owner, bool empty =true)
+ {
+ m_open= owner->OpenClipboard();
+ if (!m_open)
+ MdThrowStringException(IDS_CANNOTOPENCLIPBOARD);
+ if (empty)
+ {
+ if (!EmptyClipboard())
+ MdThrowStringException(IDS_CANNOTEMTPYCLIPBOARD);
+ }
+ }
+ ~COpenClipboard()
+ {
+ if (m_open)
+ CloseClipboard();
+ }
+ private:
+ BOOL m_open;
+ };
+
+
+ class CMyPropertySheet: public CPropertySheet
+ {
+ public:
+ CMyPropertySheet()
+ : CPropertySheet(IDS_WINDIRSTAT_SETTINGS)
+ {}
+ virtual BOOL OnInitDialog()
+ {
+ BOOL bResult= CPropertySheet::OnInitDialog();
+
+ CRect rc;
+ GetWindowRect(rc);
+ CPoint pt= rc.TopLeft();
+ CPersistence::GetConfigPosition(pt);
+ CRect rc2(pt, rc.Size());
+ MoveWindow(rc2);
+
+ SetActivePage(CPersistence::GetConfigPage(GetPageCount() - 1));
+ return bResult;
+ }
+
+ protected:
+ virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam)
+ {
+ if (LOWORD(wParam) == IDOK)
+ CPersistence::SetConfigPage(GetActiveIndex());
+
+ CRect rc;
+ GetWindowRect(rc);
+ CPersistence::SetConfigPosition(rc.TopLeft());
+
+ return CPropertySheet::OnCommand(wParam, lParam);
+ }
+
+ };
+
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+CMySplitterWnd::CMySplitterWnd(LPCTSTR name)
+: m_persistenceName(name)
+{
+ m_splitterPos= 0.5;
+ CPersistence::GetSplitterPos(m_persistenceName, m_wasTrackedByUser, m_userSplitterPos);
+}
+
+BEGIN_MESSAGE_MAP(CMySplitterWnd, CSplitterWnd)
+ ON_WM_SIZE()
+ ON_WM_DESTROY()
+END_MESSAGE_MAP()
+
+void CMySplitterWnd::StopTracking(BOOL bAccept)
+{
+ CSplitterWnd::StopTracking(bAccept);
+
+ if (bAccept)
+ {
+ CRect rcClient;
+ GetClientRect(rcClient);
+
+ if (GetColumnCount() > 1)
+ {
+ int dummy;
+ int cxLeft;
+ GetColumnInfo(0, cxLeft, dummy);
+
+ if (rcClient.Width() > 0)
+ m_splitterPos= (double)cxLeft / rcClient.Width();
+ }
+ else
+ {
+ int dummy;
+ int cyUpper;
+ GetRowInfo(0, cyUpper, dummy);
+
+ if (rcClient.Height() > 0)
+ m_splitterPos= (double)cyUpper / rcClient.Height();
+ }
+ m_wasTrackedByUser= true;
+ m_userSplitterPos= m_splitterPos;
+ }
+}
+
+double CMySplitterWnd::GetSplitterPos()
+{
+ return m_splitterPos;
+}
+
+void CMySplitterWnd::SetSplitterPos(double pos)
+{
+ m_splitterPos= pos;
+
+ CRect rcClient;
+ GetClientRect(rcClient);
+
+ if (GetColumnCount() > 1)
+ {
+ if (m_pColInfo != NULL)
+ {
+ int cxLeft= (int) (pos * rcClient.Width());
+ if (cxLeft >= 0)
+ {
+ SetColumnInfo(0, cxLeft, 0);
+ RecalcLayout();
+ }
+ }
+ }
+ else
+ {
+ if (m_pRowInfo != NULL)
+ {
+ int cyUpper= (int) (pos * rcClient.Height());
+ if (cyUpper >= 0)
+ {
+ SetRowInfo(0, cyUpper, 0);
+ RecalcLayout();
+ }
+ }
+ }
+}
+
+void CMySplitterWnd::RestoreSplitterPos(double posIfVirgin)
+{
+ if (m_wasTrackedByUser)
+ SetSplitterPos(m_userSplitterPos);
+ else
+ SetSplitterPos(posIfVirgin);
+}
+
+void CMySplitterWnd::OnSize(UINT nType, int cx, int cy)
+{
+ if (GetColumnCount() > 1)
+ {
+ int cxLeft= (int)(cx * m_splitterPos);
+ if (cxLeft > 0)
+ SetColumnInfo(0, cxLeft, 0);
+ }
+ else
+ {
+ int cyUpper= (int)(cy * m_splitterPos);
+ if (cyUpper > 0)
+ SetRowInfo(0, cyUpper, 0);
+ }
+ CSplitterWnd::OnSize(nType, cx, cy);
+}
+
+void CMySplitterWnd::OnDestroy()
+{
+ CPersistence::SetSplitterPos(m_persistenceName, m_wasTrackedByUser, m_userSplitterPos);
+ CSplitterWnd::OnDestroy();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+CPacmanControl::CPacmanControl()
+{
+ m_pacman.SetBackgroundColor(GetSysColor(COLOR_BTNFACE));
+ m_pacman.SetSpeed(0.00005);
+}
+
+void CPacmanControl::Drive(LONGLONG readJobs)
+{
+ if (IsWindow(m_hWnd) && m_pacman.Drive(readJobs))
+ RedrawWindow();
+}
+
+void CPacmanControl::Start(bool start)
+{
+ m_pacman.Start(start);
+}
+
+BEGIN_MESSAGE_MAP(CPacmanControl, CStatic)
+ ON_WM_PAINT()
+ ON_WM_CREATE()
+END_MESSAGE_MAP()
+
+int CPacmanControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CStatic::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ m_pacman.Reset();
+ m_pacman.Start(true);
+ return 0;
+}
+
+void CPacmanControl::OnPaint()
+{
+ CPaintDC dc(this);
+ CRect rc;
+ GetClientRect(rc);
+ m_pacman.Draw(&dc, rc);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
+
+BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
+ ON_WM_CREATE()
+ ON_MESSAGE(WM_ENTERSIZEMOVE, OnEnterSizeMove)
+ ON_MESSAGE(WM_EXITSIZEMOVE, OnExitSizeMove)
+ ON_WM_CLOSE()
+ ON_WM_INITMENUPOPUP()
+ ON_UPDATE_COMMAND_UI(ID_INDICATOR_MEMORYUSAGE, OnUpdateMemoryUsage)
+ ON_WM_SIZE()
+ ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWTREEMAP, OnUpdateViewShowtreemap)
+ ON_COMMAND(ID_VIEW_SHOWTREEMAP, OnViewShowtreemap)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWFILETYPES, OnUpdateViewShowfiletypes)
+ ON_COMMAND(ID_VIEW_SHOWFILETYPES, OnViewShowfiletypes)
+ ON_COMMAND(ID_CONFIGURE, OnConfigure)
+ ON_WM_DESTROY()
+ ON_UPDATE_COMMAND_UI(ID_SENDMAILTOOWNER, OnUpdateSendmailtoowner)
+ ON_COMMAND(ID_SENDMAILTOOWNER, OnSendmailtoowner)
+ ON_COMMAND(ID_TREEMAP_HELPABOUTTREEMAPS, OnTreemapHelpabouttreemaps)
+ ON_BN_CLICKED(IDC_SUSPEND, OnBnClickedSuspend)
+END_MESSAGE_MAP()
+
+static UINT indicators[] =
+{
+ ID_SEPARATOR,
+ ID_INDICATOR_MEMORYUSAGE,
+ ID_INDICATOR_CAPS,
+ ID_INDICATOR_NUM,
+ ID_INDICATOR_SCRL,
+};
+
+static UINT indicatorsWithoutMemoryUsage[] =
+{
+ ID_SEPARATOR,
+ ID_INDICATOR_CAPS,
+ ID_INDICATOR_NUM,
+ ID_INDICATOR_SCRL,
+};
+
+
+CMainFrame *CMainFrame::_theFrame;
+
+CMainFrame *CMainFrame::GetTheFrame()
+{
+ return _theFrame;
+}
+
+CMainFrame::CMainFrame()
+ : m_wndSplitter(_T("main"))
+ , m_wndSubSplitter(_T("sub"))
+{
+ _theFrame= this;
+ m_progressVisible= false;
+ m_progressRange= 100;
+}
+
+CMainFrame::~CMainFrame()
+{
+ _theFrame= NULL;
+}
+
+void CMainFrame::ShowProgress(LONGLONG range)
+{
+ // A range of 0 means that we have no range.
+ // In this case we display pacman.
+ HideProgress();
+
+ if (GetOptions()->IsFollowMountPoints())
+ range= 0;
+ m_progressRange= range;
+ m_progressPos= 0;
+ m_progressVisible= true;
+ if (range > 0)
+ CreateStatusProgress();
+ else
+ CreatePacmanProgress();
+ UpdateProgress();
+}
+
+void CMainFrame::HideProgress()
+{
+ DestroyProgress();
+ if (m_progressVisible)
+ {
+ m_progressVisible= false;
+ if (IsWindow(*GetMainFrame()))
+ {
+ GetDocument()->SetTitlePrefix(_T(""));
+ SetMessageText(AFX_IDS_IDLEMESSAGE);
+ }
+ }
+}
+
+void CMainFrame::SetProgressPos(LONGLONG pos)
+{
+ if (m_progressRange > 0 && pos > m_progressRange)
+ pos= m_progressRange;
+
+ m_progressPos= pos;
+ UpdateProgress();
+}
+
+void CMainFrame::SetProgressPos100()
+{
+ if (m_progressRange > 0)
+ SetProgressPos(m_progressRange);
+}
+
+bool CMainFrame::IsProgressSuspended()
+{
+ if (!IsWindow(m_suspendButton.m_hWnd))
+ return false;
+ bool checked= (m_suspendButton.GetState() & 0x3) != 0;
+ return checked;
+}
+
+void CMainFrame::DrivePacman()
+{
+ m_pacman.Drive(GetDocument()->GetWorkingItemReadJobs());
+}
+
+void CMainFrame::UpdateProgress()
+{
+ if (m_progressVisible)
+ {
+ CString titlePrefix;
+ CString suspended;
+
+ if (IsProgressSuspended())
+ {
+ suspended.LoadString(IDS_SUSPENDED_);
+ }
+
+ if (m_progressRange > 0)
+ {
+ int pos= (int)((double) m_progressPos * 100 / m_progressRange);
+ m_progress.SetPos(pos);
+ titlePrefix.Format(_T("%d%% %s"), pos, suspended);
+ }
+ else
+ {
+ titlePrefix= LoadString(IDS_SCANNING_) + suspended;
+ }
+
+ GetDocument()->SetTitlePrefix(titlePrefix);
+ }
+}
+
+void CMainFrame::CreateStatusProgress()
+{
+ if (m_progress.m_hWnd == NULL)
+ {
+ CRect rc;
+ m_wndStatusBar.GetItemRect(0, rc);
+ CreateSuspendButton(rc);
+ m_progress.Create(WS_CHILD|WS_VISIBLE, rc, &m_wndStatusBar, 4711);
+ m_progress.ModifyStyle(WS_BORDER, 0); // Doesn't help with XP-style control.
+ }
+}
+
+void CMainFrame::CreatePacmanProgress()
+{
+ if (m_pacman.m_hWnd == NULL)
+ {
+ CRect rc;
+ m_wndStatusBar.GetItemRect(0, rc);
+ CreateSuspendButton(rc);
+ m_pacman.Create(_T(""), WS_CHILD|WS_VISIBLE, rc, &m_wndStatusBar, 4711);
+ }
+}
+
+// rc [in]: Rect of status pane
+// rc [out]: Rest for progress/pacman-control
+void CMainFrame::CreateSuspendButton(CRect& rc)
+{
+ CRect rcButton= rc;
+ rcButton.right= rcButton.left + 80;
+
+ VERIFY(m_suspendButton.Create(LoadString(IDS_SUSPEND), WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX|BS_PUSHLIKE, rcButton, &m_wndStatusBar, IDC_SUSPEND));
+ m_suspendButton.SetFont(GetDirstatView()->GetSmallFont());
+
+ rc.left= rcButton.right;
+}
+
+void CMainFrame::DestroyProgress()
+{
+ if (IsWindow(m_progress.m_hWnd))
+ {
+ m_progress.DestroyWindow();
+ m_progress.m_hWnd= NULL;
+ }
+ else if (IsWindow(m_pacman.m_hWnd))
+ {
+ m_pacman.DestroyWindow();
+ m_pacman.m_hWnd= NULL;
+ }
+ if (IsWindow(m_suspendButton.m_hWnd))
+ {
+ m_suspendButton.DestroyWindow();
+ m_suspendButton.m_hWnd= NULL;
+ }
+}
+
+void CMainFrame::OnBnClickedSuspend()
+{
+ m_pacman.Start(!IsProgressSuspended());
+ UpdateProgress();
+}
+
+int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ VERIFY(m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
+ | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC)
+ );
+ VERIFY(m_wndToolBar.LoadToolBar(IDR_MAINFRAME));
+
+ UINT *indic= indicators;
+ UINT size= countof(indicators);
+
+ // If psapi is not supported, don't show that pane.
+ if (GetApp()->GetCurrentProcessMemoryInfo() == _T(""))
+ {
+ indic= indicatorsWithoutMemoryUsage;
+ size= countof(indicatorsWithoutMemoryUsage);
+ }
+
+ VERIFY(m_wndStatusBar.Create(this));
+ VERIFY(m_wndStatusBar.SetIndicators(indic, size));
+
+ m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
+ EnableDocking(CBRS_ALIGN_ANY);
+ DockControlBar(&m_wndToolBar);
+
+ LoadBarState(CPersistence::GetBarStateSection());
+ ShowControlBar(&m_wndToolBar, CPersistence::GetShowToolbar(), false);
+ ShowControlBar(&m_wndStatusBar, CPersistence::GetShowStatusbar(), false);
+
+ return 0;
+}
+
+void CMainFrame::InitialShowWindow()
+{
+ WINDOWPLACEMENT wp;
+ wp.length= sizeof(wp);
+ GetWindowPlacement(&wp);
+ CPersistence::GetMainWindowPlacement(wp);
+ MakeSaneShowCmd(wp.showCmd);
+ SetWindowPlacement(&wp);
+}
+
+void CMainFrame::MakeSaneShowCmd(UINT& u)
+{
+ switch (u)
+ {
+ default:
+ case SW_HIDE:
+ case SW_MINIMIZE:
+ case SW_SHOWMINNOACTIVE:
+ case SW_SHOWNA:
+ case SW_SHOWMINIMIZED:
+ case SW_SHOWNOACTIVATE:
+ case SW_RESTORE:
+ case SW_FORCEMINIMIZE:
+ case SW_SHOWDEFAULT:
+ case SW_SHOW:
+ case SW_SHOWNORMAL:
+ u= SW_SHOWNORMAL;
+ break;
+ case SW_SHOWMAXIMIZED:
+ break;
+ }
+}
+
+void CMainFrame::OnClose()
+{
+ CWaitCursor wc;
+
+ // It's too late, to do this in OnDestroy(). Because the toolbar, if undocked,
+ // is already destroyed in OnDestroy(). So we must save the toolbar state here
+ // in OnClose().
+ SaveBarState(CPersistence::GetBarStateSection());
+ CPersistence::SetShowToolbar((m_wndToolBar.GetStyle() & WS_VISIBLE) != 0);
+ CPersistence::SetShowStatusbar((m_wndStatusBar.GetStyle() & WS_VISIBLE) != 0);
+
+#ifdef _DEBUG
+ // avoid memory leaks an show hourglass while deleting the tree
+ GetDocument()->OnNewDocument();
+#endif
+
+ GetDocument()->ForgetItemTree();
+ CFrameWnd::OnClose();
+}
+
+void CMainFrame::OnDestroy()
+{
+ WINDOWPLACEMENT wp;
+ wp.length= sizeof(wp);
+ GetWindowPlacement(&wp);
+ CPersistence::SetMainWindowPlacement(wp);
+
+ CPersistence::SetShowFileTypes(GetTypeView()->IsShowTypes());
+ CPersistence::SetShowTreemap(GetGraphView()->IsShowTreemap());
+
+ CFrameWnd::OnDestroy();
+}
+
+BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
+{
+ VERIFY(m_wndSplitter.CreateStatic(this, 2, 1));
+ VERIFY(m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CGraphView), CSize(100, 100), pContext));
+ VERIFY(m_wndSubSplitter.CreateStatic(&m_wndSplitter, 1, 2, WS_CHILD | WS_VISIBLE | WS_BORDER, m_wndSplitter.IdFromRowCol(0, 0)));
+ VERIFY(m_wndSubSplitter.CreateView(0, 0, RUNTIME_CLASS(CDirstatView), CSize(700, 500), pContext));
+ VERIFY(m_wndSubSplitter.CreateView(0, 1, RUNTIME_CLASS(CTypeView), CSize(100, 500), pContext));
+
+ MinimizeGraphView();
+ MinimizeTypeView();
+
+ GetTypeView()->ShowTypes(CPersistence::GetShowFileTypes());
+ GetGraphView()->ShowTreemap(CPersistence::GetShowTreemap());
+
+ return TRUE;
+}
+
+BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if( !CFrameWnd::PreCreateWindow(cs) )
+ return FALSE;
+
+ return TRUE;
+}
+
+
+// CMainFrame Diagnose
+
+#ifdef _DEBUG
+void CMainFrame::AssertValid() const
+{
+ CFrameWnd::AssertValid();
+}
+
+void CMainFrame::Dump(CDumpContext& dc) const
+{
+ CFrameWnd::Dump(dc);
+}
+
+#endif //_DEBUG
+
+void CMainFrame::MinimizeTypeView()
+{
+ m_wndSubSplitter.SetSplitterPos(1.0);
+}
+
+void CMainFrame::RestoreTypeView()
+{
+ if (GetTypeView()->IsShowTypes())
+ {
+ m_wndSubSplitter.RestoreSplitterPos(0.72);
+ GetTypeView()->RedrawWindow();
+ }
+}
+
+void CMainFrame::MinimizeGraphView()
+{
+ m_wndSplitter.SetSplitterPos(1.0);
+}
+
+void CMainFrame::RestoreGraphView()
+{
+ if (GetGraphView()->IsShowTreemap())
+ {
+ m_wndSplitter.RestoreSplitterPos(0.4);
+ GetGraphView()->DrawEmptyView();
+ GetGraphView()->RedrawWindow();
+ }
+}
+
+CDirstatView* CMainFrame::GetDirstatView()
+{
+ CWnd* pWnd = m_wndSubSplitter.GetPane(0, 0);
+ CDirstatView* pView = DYNAMIC_DOWNCAST(CDirstatView, pWnd);
+ return pView;
+}
+
+CGraphView *CMainFrame::GetGraphView()
+{
+ CWnd *pWnd= m_wndSplitter.GetPane(1, 0);
+ CGraphView *pView= DYNAMIC_DOWNCAST(CGraphView, pWnd);
+ return pView;
+}
+
+CTypeView *CMainFrame::GetTypeView()
+{
+ CWnd *pWnd= m_wndSubSplitter.GetPane(0, 1);
+ CTypeView *pView= DYNAMIC_DOWNCAST(CTypeView, pWnd);
+ return pView;
+}
+
+LRESULT CMainFrame::OnEnterSizeMove(WPARAM, LPARAM)
+{
+ GetGraphView()->SuspendRecalculation(true);
+ return 0;
+}
+
+LRESULT CMainFrame::OnExitSizeMove(WPARAM, LPARAM)
+{
+ GetGraphView()->SuspendRecalculation(false);
+ return 0;
+}
+
+void CMainFrame::CopyToClipboard(LPCTSTR psz)
+{
+ try
+ {
+ COpenClipboard clipboard(this);
+
+ HGLOBAL h= GlobalAlloc(GMEM_MOVEABLE, (lstrlen(psz) + 1 ) * sizeof(TCHAR));
+ if (h == NULL)
+ MdThrowStringException(_T("GlobalAlloc failed."));
+
+ LPVOID lp= GlobalLock(h);
+ ASSERT(lp != NULL);
+
+ lstrcpy((LPTSTR)lp, psz);
+
+ GlobalUnlock(h);
+
+ UINT uFormat= CF_TEXT;
+#ifdef UNICODE
+ uFormat= CF_UNICODETEXT;
+#endif
+ if (NULL == SetClipboardData(uFormat, h))
+ MdThrowStringException(IDS_CANNOTSETCLIPBAORDDATA);
+ }
+ catch (CException *pe)
+ {
+ pe->ReportError();
+ pe->Delete();
+ }
+}
+
+void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
+{
+ CFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
+
+ if (!bSysMenu)
+ {
+ switch (nIndex)
+ {
+ case TLM_CLEANUP:
+ UpdateCleanupMenu(pPopupMenu);
+ break;
+ }
+ }
+}
+
+void CMainFrame::UpdateCleanupMenu(CMenu *menu)
+{
+ CString s= LoadString(IDS_EMPTYRECYCLEBIN);
+ VERIFY(menu->ModifyMenu(ID_CLEANUP_EMPTYRECYCLEBIN, MF_BYCOMMAND|MF_STRING, ID_CLEANUP_EMPTYRECYCLEBIN, s));
+ menu->EnableMenuItem(ID_CLEANUP_EMPTYRECYCLEBIN, MF_BYCOMMAND | MF_DISABLED|MF_GRAYED);
+
+ CRecycleBinApi rb;
+ if (rb.IsSupported())
+ {
+
+ SHQUERYRBINFO qbi;
+ ZeroMemory(&qbi, sizeof(qbi));
+ qbi.cbSize= sizeof(qbi);
+
+ HRESULT hr= rb.SHQueryRecycleBin(NULL, &qbi);
+ if (FAILED(hr))
+ return;
+
+ CString info;
+ if (qbi.i64NumItems == 1)
+ info.FormatMessage(IDS__ONEITEMss, FormatBytes(qbi.i64Size), GetOptions()->IsHumanFormat() ? "" : " Bytes");
+ else
+ info.FormatMessage(IDS__sITEMSss, FormatCount(qbi.i64NumItems), FormatBytes(qbi.i64Size), GetOptions()->IsHumanFormat() ? "" : " Bytes");
+
+ s+= info;
+ VERIFY(menu->ModifyMenu(ID_CLEANUP_EMPTYRECYCLEBIN, MF_BYCOMMAND|MF_STRING, ID_CLEANUP_EMPTYRECYCLEBIN, s));
+
+ if (qbi.i64NumItems > 0)
+ menu->EnableMenuItem(ID_CLEANUP_EMPTYRECYCLEBIN, MF_BYCOMMAND | MF_ENABLED);
+ }
+
+ UINT toRemove= menu->GetMenuItemCount() - MAINMENU_USERDEFINEDCLEANUP_POSITION;
+ for (UINT i=0; i < toRemove; i++)
+ menu->RemoveMenu(MAINMENU_USERDEFINEDCLEANUP_POSITION, MF_BYPOSITION);
+
+ AppendUserDefinedCleanups(menu);
+}
+
+void CMainFrame::AppendUserDefinedCleanups(CMenu *menu)
+{
+ CArray<int, int> indices;
+ GetOptions()->GetEnabledUserDefinedCleanups(indices);
+ if (indices.GetSize() > 0)
+ {
+ for (int i=0; i < indices.GetSize(); i++)
+ {
+ CString string;
+ string.FormatMessage(IDS_UDCsCTRLd, GetOptions()->GetUserDefinedCleanup(indices[i])->title, indices[i]);
+
+ UINT flags= MF_GRAYED;
+ if (GetDocument()->UserDefinedCleanupWorksForItem(GetOptions()->GetUserDefinedCleanup(indices[i]), GetDocument()->GetSelection()))
+ flags= MF_ENABLED;
+ menu->AppendMenu(flags|MF_STRING, ID_USERDEFINEDCLEANUP0 + indices[i], string);
+ }
+ }
+ else
+ {
+ // This is just to show new users, that they can configure user defined cleanups.
+ menu->AppendMenu(MF_GRAYED, 0, LoadString(IDS_USERDEFINEDCLEANUP0));
+ }
+}
+
+void CMainFrame::OnUpdateMemoryUsage(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(true);
+ pCmdUI->SetText(GetApp()->GetCurrentProcessMemoryInfo());
+}
+
+
+
+void CMainFrame::OnSize(UINT nType, int cx, int cy)
+{
+ CFrameWnd::OnSize(nType, cx, cy);
+
+ if (!IsWindow(m_wndStatusBar.m_hWnd))
+ return;
+
+ CRect rc;
+ m_wndStatusBar.GetItemRect(0, rc);
+
+ if (m_suspendButton.m_hWnd != NULL)
+ {
+ CRect suspend;
+ m_suspendButton.GetClientRect(suspend);
+ rc.left= suspend.right;
+ }
+
+ if (m_progress.m_hWnd != NULL)
+ m_progress.MoveWindow(rc);
+ else if (m_pacman.m_hWnd != NULL)
+ m_pacman.MoveWindow(rc);
+}
+
+void CMainFrame::OnUpdateViewShowtreemap(CCmdUI *pCmdUI)
+{
+ pCmdUI->SetCheck(GetGraphView()->IsShowTreemap());
+}
+
+void CMainFrame::OnViewShowtreemap()
+{
+ GetGraphView()->ShowTreemap(!GetGraphView()->IsShowTreemap());
+ if (GetGraphView()->IsShowTreemap())
+ RestoreGraphView();
+ else
+ MinimizeGraphView();
+}
+
+void CMainFrame::OnUpdateViewShowfiletypes(CCmdUI *pCmdUI)
+{
+ pCmdUI->SetCheck(GetTypeView()->IsShowTypes());
+}
+
+void CMainFrame::OnViewShowfiletypes()
+{
+ GetTypeView()->ShowTypes(!GetTypeView()->IsShowTypes());
+ if (GetTypeView()->IsShowTypes())
+ RestoreTypeView();
+ else
+ MinimizeTypeView();
+}
+
+void CMainFrame::OnConfigure()
+{
+ CMyPropertySheet sheet;
+
+ CPageGeneral general;
+ CPageTreelist treelist;
+ CPageTreemap treemap;
+ CPageCleanups cleanups;
+
+ sheet.AddPage(&general);
+ sheet.AddPage(&treelist);
+ sheet.AddPage(&treemap);
+ sheet.AddPage(&cleanups);
+
+ sheet.DoModal();
+
+ GetOptions()->SaveToRegistry();
+}
+
+
+void CMainFrame::OnUpdateSendmailtoowner(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(
+ GetDocument()->GetSelection() != NULL
+ && GetDocument()->GetSelection()->IsDone()
+ && CModalSendMail::IsSendMailAvailable()
+ );
+}
+
+void CMainFrame::OnSendmailtoowner()
+{
+ CString subject= LoadString(IDS_REPORT_DISKUSAGE);
+ CString body= GetDirstatView()->GenerateReport();
+
+ CModalSendMail sm;
+ sm.SendMail(_T(""), subject, body);
+
+/*
+ This works only for small bodies:
+
+ CString url;
+ url.Format("mailto:?subject=%s&body=%s", subject, body);
+ url= MyUrlCanonicalize(url);
+
+ AfxMessageBox(url);
+ try
+ {
+ MyShellExecute(NULL, NULL, url, NULL, NULL, SW_SHOWNORMAL);
+ }
+ catch (CException *pe)
+ {
+ pe->ReportError();
+ pe->Delete();
+ }
+*/
+}
+
+void CMainFrame::OnTreemapHelpabouttreemaps()
+{
+ GetApp()->DoContextHelp(IDH_Treemap);
+}
diff --git a/windirstat/mainframe.h b/windirstat/mainframe.h
new file mode 100644
index 0000000..79e2947
--- /dev/null
+++ b/windirstat/mainframe.h
@@ -0,0 +1,162 @@
+// mainframe.h - Declaration of CMySplitterWnd and CMainFrame
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "pacman.h"
+
+class CMySplitterWnd;
+class CMainFrame;
+
+class CDirstatView;
+class CGraphView;
+class CTypeView;
+
+//
+// CMySplitterWnd. A CSplitterWnd with 2 columns or rows, which
+// knows about the current split ratio and retains it even when resized.
+//
+class CMySplitterWnd: public CSplitterWnd
+{
+public:
+ CMySplitterWnd(LPCTSTR name);
+ virtual void StopTracking(BOOL bAccept);
+ double GetSplitterPos();
+ void SetSplitterPos(double pos);
+ void RestoreSplitterPos(double posIfVirgin);
+
+protected:
+ CString m_persistenceName; // Name of object for CPersistence
+ double m_splitterPos; // Current split ratio
+ bool m_wasTrackedByUser; // True as soon as user has modified the splitter position
+ double m_userSplitterPos; // Split ratio as set by the user
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+public:
+ afx_msg void OnDestroy();
+};
+
+
+class CPacmanControl: public CStatic
+{
+public:
+ CPacmanControl();
+ void Drive(LONGLONG readJobs);
+ void Start(bool start);
+
+protected:
+ CPacman m_pacman;
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnPaint();
+public:
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+};
+
+//
+// CMainFrame. The main application window.
+//
+class CMainFrame : public CFrameWnd
+{
+protected:
+ static CMainFrame *_theFrame;
+ CMainFrame(); // Created by MFC only
+ DECLARE_DYNCREATE(CMainFrame)
+
+public:
+ static CMainFrame *GetTheFrame();
+ virtual ~CMainFrame();
+ void InitialShowWindow();
+
+ void RestoreGraphView();
+ void RestoreTypeView();
+ void MinimizeGraphView();
+ void MinimizeTypeView();
+ void CopyToClipboard(LPCTSTR psz);
+
+ CDirstatView *GetDirstatView();
+ CGraphView *GetGraphView();
+ CTypeView *GetTypeView();
+
+ void ShowProgress(LONGLONG range);
+ void HideProgress();
+ void SetProgressPos(LONGLONG pos);
+ void SetProgressPos100();
+ bool IsProgressSuspended();
+ void DrivePacman();
+
+ void UpdateProgress();
+ void AppendUserDefinedCleanups(CMenu *menu);
+
+protected:
+ virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ void MakeSaneShowCmd(UINT& u);
+
+ void CreateStatusProgress();
+ void CreatePacmanProgress();
+ void CreateSuspendButton(CRect& rc);
+ void DestroyProgress();
+
+ void UpdateCleanupMenu(CMenu *menu);
+
+ bool m_progressVisible; // True while progress must be shown (either pacman or progressbar)
+ LONGLONG m_progressRange; // Progress range. A range of 0 means that we have no range available. In this case we should display pacman.
+ LONGLONG m_progressPos; // Progress position (<= progressRange, or an item count in case of m_progressRang == 0)
+
+ CMySplitterWnd m_wndSubSplitter; // Contains the two upper views
+ CMySplitterWnd m_wndSplitter; // Contains (a) m_wndSubSplitter and (b) the graphview.
+
+ CStatusBar m_wndStatusBar; // Status bar
+ CToolBar m_wndToolBar; // Tool bar
+ CProgressCtrl m_progress; // Progress control. Is Create()ed and Destroy()ed again every time.
+ CPacmanControl m_pacman; // Static control for Pacman.
+ CButton m_suspendButton;// Progress-Suspend-Button
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg LRESULT OnEnterSizeMove(WPARAM, LPARAM);
+ afx_msg LRESULT OnExitSizeMove(WPARAM, LPARAM);
+ afx_msg void OnClose();
+ afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);
+ afx_msg void OnUpdateMemoryUsage(CCmdUI *pCmdUI);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnUpdateViewShowtreemap(CCmdUI *pCmdUI);
+ afx_msg void OnViewShowtreemap();
+ afx_msg void OnUpdateViewShowfiletypes(CCmdUI *pCmdUI);
+ afx_msg void OnViewShowfiletypes();
+ afx_msg void OnConfigure();
+ afx_msg void OnDestroy();
+ afx_msg void OnUpdateSendmailtoowner(CCmdUI *pCmdUI);
+ afx_msg void OnSendmailtoowner();
+ afx_msg void OnBnClickedSuspend();
+
+public:
+ #ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+ #endif
+ afx_msg void OnTreemapHelpabouttreemaps();
+};
+
+
+
diff --git a/windirstat/mountpoints.cpp b/windirstat/mountpoints.cpp
new file mode 100644
index 0000000..05744d2
--- /dev/null
+++ b/windirstat/mountpoints.cpp
@@ -0,0 +1,235 @@
+// mountpoints.cpp - Implementation of CMountPoints
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "osspecific.h"
+
+#include "mountpoints.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+CMountPoints::~CMountPoints()
+{
+ Clear();
+}
+
+void CMountPoints::Clear()
+{
+ m_drive.RemoveAll();
+
+ POSITION pos= m_volume.GetStartPosition();
+ while (pos != NULL)
+ {
+ CString volume;
+ PointVolumeArray *pva= NULL;
+ m_volume.GetNextAssoc(pos, volume, pva);
+ ASSERT_VALID(pva);
+ delete pva;
+ }
+ m_volume.RemoveAll();
+}
+
+void CMountPoints::Initialize()
+{
+ Clear();
+
+ if (!m_va.IsSupported())
+ return;
+
+ GetDriveVolumes();
+ GetAllMountPoints();
+}
+
+void CMountPoints::GetDriveVolumes()
+{
+ m_drive.SetSize(32);
+
+ DWORD drives= GetLogicalDrives();
+ int i;
+ DWORD mask= 0x00000001;
+ for (i=0; i < 32; i++, mask <<= 1)
+ {
+ CString volume;
+
+ if ((drives & mask) != 0)
+ {
+ CString s;
+ s.Format(_T("%c:\\"), i + _T('A'));
+
+ BOOL b= m_va.GetVolumeNameForVolumeMountPoint(s, volume.GetBuffer(_MAX_PATH), _MAX_PATH);
+ volume.ReleaseBuffer();
+
+ if (!b)
+ {
+ TRACE(_T("GetVolumeNameForVolumeMountPoint(%s) failed.\n"), s);
+ volume.Empty();
+ }
+ }
+
+ m_drive[i]= volume;
+ }
+}
+
+void CMountPoints::GetAllMountPoints()
+{
+ TCHAR volume[_MAX_PATH];
+ HANDLE hvol= m_va.FindFirstVolume(volume, countof(volume));
+ if (hvol == INVALID_HANDLE_VALUE)
+ {
+ TRACE(_T("No volumes found.\r\n"));
+ return;
+ }
+
+ for (BOOL bContinue=true; bContinue; bContinue= m_va.FindNextVolume(hvol, volume, countof(volume)))
+ {
+ PointVolumeArray *pva= new PointVolumeArray;
+ ASSERT_VALID(pva);
+
+ DWORD sysflags;
+ CString fsname;
+ BOOL b= GetVolumeInformation(volume, NULL, 0, NULL, NULL, &sysflags, fsname.GetBuffer(_MAX_PATH), _MAX_PATH);
+ fsname.ReleaseBuffer();
+
+ if (!b)
+ {
+ TRACE(_T("This file system (%s) is not ready.\r\n"), volume);
+ m_volume.SetAt(volume, pva);
+ continue;
+ }
+
+ if ((sysflags & FILE_SUPPORTS_REPARSE_POINTS) == 0)
+ {
+ // No support for reparse points, and therefore for volume
+ // mount points, which are implemented using reparse points.
+ TRACE(_T("This file system (%s) does not support volume mount points.\r\n"), volume);
+ m_volume.SetAt(volume, pva);
+ continue;
+ }
+
+ TCHAR point[_MAX_PATH];
+ HANDLE h= m_va.FindFirstVolumeMountPoint(volume, point, countof(point));
+ if (h == INVALID_HANDLE_VALUE)
+ {
+ TRACE(_T("No volume mount points found on %s.\r\n"), volume);
+ m_volume.SetAt(volume, pva);
+ continue;
+ }
+
+ for (BOOL bCont=true; bCont; bCont= m_va.FindNextVolumeMountPoint(h, point, countof(point)))
+ {
+ CString uniquePath= volume;
+ uniquePath+= point;
+ CString mountedVolume;
+
+ BOOL b= m_va.GetVolumeNameForVolumeMountPoint(uniquePath, mountedVolume.GetBuffer(_MAX_PATH), _MAX_PATH);
+ mountedVolume.ReleaseBuffer();
+
+ if (!b)
+ {
+ TRACE(_T("GetVolumeNameForVolumeMountPoint(%s) failed.\r\n"), uniquePath);
+ continue;
+ }
+
+ SPointVolume pv;
+ pv.point= point;
+ pv.volume= mountedVolume;
+
+ pv.point.MakeLower();
+
+ pva->Add(pv);
+ }
+ m_va.FindVolumeMountPointClose(h);
+
+ m_volume.SetAt(volume, pva);
+ }
+
+ (void)m_va.FindVolumeClose(hvol);
+
+#ifdef _DEBUG
+ POSITION pos= m_volume.GetStartPosition();
+ while (pos != NULL)
+ {
+ CString volume;
+ PointVolumeArray *pva= NULL;
+ m_volume.GetNextAssoc(pos, volume, pva);
+ pva->AssertValid();
+ }
+#endif
+
+}
+
+
+bool CMountPoints::IsMountPoint(CString path)
+{
+ if (path.GetLength() < 3 || path[1] != _T(':') || path[2] != _T('\\'))
+ {
+ // Don't know how to make out mount points on UNC paths ###
+ return false;
+ }
+
+ ASSERT(path.GetLength() >= 3);
+ ASSERT(path[1] == _T(':'));
+ ASSERT(path[2] == _T('\\'));
+
+ if (!m_va.IsSupported())
+ return false;
+
+ if (path.Right(1) != _T('\\'))
+ path+= _T("\\");
+
+ path.MakeLower();
+
+ CString volume= m_drive[path[0] - _T('a')];
+ path= path.Mid(3);
+
+ return IsVolumeMountPoint(volume, path);
+}
+
+bool CMountPoints::IsVolumeMountPoint(CString volume, CString path)
+{
+ for (;;)
+ {
+ PointVolumeArray *pva;
+ if (!m_volume.Lookup(volume, pva))
+ {
+ TRACE(_T("CMountPoints: Volume(%s) unknown!\r\n"), volume);
+ return false;
+ }
+
+ CString point;
+ for (int i=0; i < pva->GetSize(); i++)
+ {
+ point= (*pva)[i].point;
+ if (path.Left(point.GetLength()) == point)
+ break;
+ }
+ if (i >= pva->GetSize())
+ return false;
+
+ if (path.GetLength() == point.GetLength())
+ return true;
+
+ volume= (*pva)[i].volume;
+ path= path.Mid(point.GetLength());
+ }
+}
diff --git a/windirstat/mountpoints.h b/windirstat/mountpoints.h
new file mode 100644
index 0000000..3f9b038
--- /dev/null
+++ b/windirstat/mountpoints.h
@@ -0,0 +1,56 @@
+// mountpoints.h
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+
+class CMountPoints
+{
+ struct SPointVolume
+ {
+ CString point; // Path like "mount\backup\"
+ CString volume; // Volume identifier
+ };
+
+ typedef CArray<SPointVolume, SPointVolume&> PointVolumeArray;
+
+public:
+ ~CMountPoints();
+ void Initialize();
+ bool IsMountPoint(CString path);
+
+private:
+ void Clear();
+ void GetDriveVolumes();
+ void GetAllMountPoints();
+
+ bool IsVolumeMountPoint(CString volume, CString path);
+
+ CVolumeApi m_va;
+
+ // m_drive contains the volume identifiers of the Drives A:, B: etc.
+ // mdrive[0] = Volume identifier of A:\.
+ CArray<CString, LPCTSTR> m_drive;
+
+ // m_volume maps all volume identifiers to PointVolumeArrays
+ CMap<CString, LPCTSTR, PointVolumeArray *, PointVolumeArray *> m_volume;
+};
+
diff --git a/windirstat/myimagelist.cpp b/windirstat/myimagelist.cpp
new file mode 100644
index 0000000..5b13e0d
--- /dev/null
+++ b/windirstat/myimagelist.cpp
@@ -0,0 +1,233 @@
+// myimagelist.cpp - Implementation of CMyImageList
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "myimagelist.h"
+
+
+CMyImageList::CMyImageList()
+{
+ m_filesFolderImage= 0;
+ m_freeSpaceImage= 0;
+ m_unknownImage= 0;
+}
+
+CMyImageList::~CMyImageList()
+{
+}
+
+void CMyImageList::Initialize()
+{
+ if (m_hImageList == NULL)
+ {
+ SHFILEINFO sfi;
+ HIMAGELIST hil= (HIMAGELIST)SHGetFileInfo(_T(""), 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
+
+ Attach(ImageList_Duplicate(hil));
+
+ for (int i=0; i < GetImageCount(); i++)
+ m_indexMap.SetAt(i, i);
+
+ AddCustomImages();
+ }
+}
+
+int CMyImageList::CacheIcon(LPCTSTR path, UINT flags, CString *psTypeName)
+{
+ ASSERT(m_hImageList != NULL); // should have been Initialize()ed.
+
+ flags|= SHGFI_SYSICONINDEX | SHGFI_SMALLICON;
+ if (psTypeName != NULL)
+ flags|= SHGFI_TYPENAME;
+
+ SHFILEINFO sfi;
+ HIMAGELIST hil= (HIMAGELIST)SHGetFileInfo(path, 0, &sfi, sizeof(sfi), flags);
+ if (hil == NULL)
+ {
+ TRACE(_T("SHGetFileInfo() failed\n"));
+ return GetEmptyImage();
+ }
+
+ if (psTypeName != NULL)
+ *psTypeName= sfi.szTypeName;
+
+ int i;
+ if (!m_indexMap.Lookup(sfi.iIcon, i))
+ {
+ CImageList *sil= CImageList::FromHandle(hil);
+
+ /*
+ This doesn't work:
+ IMAGEINFO ii;
+ VERIFY(sil->GetImageInfo(sfi.iIcon, &ii));
+
+ i= Add(CBitmap::FromHandle(ii.hbmImage), CBitmap::FromHandle(ii.hbmMask));
+
+ So we use this method:
+ */
+ i= Add(sil->ExtractIcon(sfi.iIcon));
+ m_indexMap.SetAt(sfi.iIcon, i);
+ }
+
+ return i;
+}
+
+int CMyImageList::GetMyComputerImage()
+{
+ LPITEMIDLIST pidl= NULL;
+ HRESULT hr= SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidl);
+ if (FAILED(hr))
+ {
+ TRACE(_T("SHGetSpecialFolderLocation(CSIDL_DRIVES) failed!\n"));
+ return 0;
+ }
+
+ int i= CacheIcon((LPCTSTR)pidl, SHGFI_PIDL);
+
+ CoTaskMemFree(pidl);
+
+ return i;
+}
+
+int CMyImageList::GetMountPointImage()
+{
+ return CacheIcon(GetADriveSpec(), 0); // The flag SHGFI_USEFILEATTRIBUTES doesn't work on W95.
+}
+
+int CMyImageList::GetFolderImage()
+{
+ return CacheIcon(_T(""), 0);
+}
+
+int CMyImageList::GetFileImage(LPCTSTR path)
+{
+ return CacheIcon(path, 0);
+}
+
+int CMyImageList::GetExtImageAndDescription(LPCTSTR ext, CString& description)
+{
+ return CacheIcon(ext, SHGFI_USEFILEATTRIBUTES, &description);
+}
+
+
+int CMyImageList::GetFilesFolderImage()
+{
+ ASSERT(m_hImageList != NULL); // should have been Initialize()ed.
+ return m_filesFolderImage;
+}
+
+int CMyImageList::GetFreeSpaceImage()
+{
+ ASSERT(m_hImageList != NULL); // should have been Initialize()ed.
+ return m_freeSpaceImage;
+}
+
+int CMyImageList::GetUnknownImage()
+{
+ ASSERT(m_hImageList != NULL); // should have been Initialize()ed.
+ return m_unknownImage;
+}
+
+int CMyImageList::GetEmptyImage()
+{
+ ASSERT(m_hImageList != NULL);
+ return m_emptyImage;
+}
+
+
+// Returns an arbitrary present drive
+CString CMyImageList::GetADriveSpec()
+{
+ CString s;
+ UINT u= GetWindowsDirectory(s.GetBuffer(_MAX_PATH), _MAX_PATH);
+ s.ReleaseBuffer();
+ if (u == 0 || s.GetLength() < 3 || s[1] != _T(':') || s[2] != _T('\\'))
+ return _T("C:\\");
+ return s.Left(3);
+}
+
+void CMyImageList::AddCustomImages()
+{
+ const CUSTOM_IMAGE_COUNT = 4;
+ const COLORREF bgcolor= RGB(255,0,255);
+
+ int folderImage= GetFolderImage();
+ int driveImage= GetMountPointImage();
+
+ IMAGEINFO ii;
+ ZeroMemory(&ii, sizeof(ii));
+ VERIFY(GetImageInfo(folderImage, &ii));
+ CRect rc= ii.rcImage;
+
+ CClientDC dcClient(CWnd::GetDesktopWindow());
+
+ CDC dcmem;
+ dcmem.CreateCompatibleDC(&dcClient);
+ CBitmap target;
+ target.CreateCompatibleBitmap(&dcClient, rc.Width() * CUSTOM_IMAGE_COUNT, rc.Height());
+ {
+ CSelectObject sotarget(&dcmem, &target);
+ dcmem.FillSolidRect(0, 0, rc.Width() * CUSTOM_IMAGE_COUNT, rc.Height(), bgcolor);
+ CPoint pt(0, 0);
+ COLORREF safe= SetBkColor(bgcolor);
+ VERIFY(Draw(&dcmem, folderImage, pt, ILD_NORMAL));
+ pt.x+= rc.Width();
+ VERIFY(Draw(&dcmem, driveImage, pt, ILD_NORMAL));
+ pt.x+= rc.Width();
+ VERIFY(Draw(&dcmem, driveImage, pt, ILD_NORMAL));
+ SetBkColor(safe);
+
+ // Now we re-color the imagees
+ for (int i=0; i < rc.Width(); i++)
+ for (int j=0; j < rc.Height(); j++)
+ {
+ // We "blueify" the folder image ("<Files>")
+ COLORREF c= dcmem.GetPixel(i, j);
+ if (c != bgcolor)
+ {
+ int brightness= (GetRValue(c) + GetGValue(c) + GetBValue(c)) / 3;
+ dcmem.SetPixel(i, j, RGB(0, brightness, brightness));
+ }
+
+ // ... "greenify" the drive image ("<Free Space>")
+ c= dcmem.GetPixel(rc.Width() + i, j);
+ if (c != bgcolor)
+ {
+ int brightness= (GetRValue(c) + GetGValue(c) + GetBValue(c)) / 3;
+ dcmem.SetPixel(rc.Width() + i, j, RGB(120, brightness, 120));
+ }
+
+ // ...and "yellowify" the drive image ("<Unknown>")
+ c= dcmem.GetPixel(2 * rc.Width() + i, j);
+ if (c != bgcolor)
+ {
+ int brightness= (GetRValue(c) + GetGValue(c) + GetBValue(c)) / 3;
+ dcmem.SetPixel(2 * rc.Width() + i, j, RGB(brightness, brightness, 0));
+ }
+ }
+ }
+ int k= Add(&target, bgcolor);
+ m_filesFolderImage= k++;
+ m_freeSpaceImage= k++;
+ m_unknownImage= k++;
+ m_emptyImage= k++;
+}
diff --git a/windirstat/myimagelist.h b/windirstat/myimagelist.h
new file mode 100644
index 0000000..4567290
--- /dev/null
+++ b/windirstat/myimagelist.h
@@ -0,0 +1,61 @@
+// myimagelist.h - Declaration of CMyImageList
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+//
+// CMyImageList. Both CDirstatView and CTypeView use this central
+// image list. It caches the system image list images as needed,
+// and adds 4 special images at initialization.
+// This is because I don't want to deal with two images lists.
+//
+class CMyImageList: public CImageList
+{
+public:
+ CMyImageList();
+ virtual ~CMyImageList();
+
+ void Initialize();
+
+ int GetMyComputerImage();
+ int GetMountPointImage();
+ int GetFolderImage();
+ int GetFileImage(LPCTSTR path);
+ int GetExtImageAndDescription(LPCTSTR ext, CString& description);
+
+ int GetFilesFolderImage();
+ int GetFreeSpaceImage();
+ int GetUnknownImage();
+ int GetEmptyImage();
+
+protected:
+ int CacheIcon(LPCTSTR path, UINT flags, CString *psTypeName = NULL);
+ CString GetADriveSpec();
+ void AddCustomImages();
+
+ CMap<int, int, int, int> m_indexMap; // system image list index -> our index
+
+ int m_filesFolderImage; // <Files>
+ int m_freeSpaceImage; // <Free Space>
+ int m_unknownImage; // <Unknown>
+ int m_emptyImage; // For items whose image cannot be found
+};
+
diff --git a/windirstat/options.cpp b/windirstat/options.cpp
new file mode 100644
index 0000000..2ea8673
--- /dev/null
+++ b/windirstat/options.cpp
@@ -0,0 +1,931 @@
+// options.cpp - Implementation of CPersistence, COptions and CRegistryUser
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "dirstatdoc.h"
+#include "options.h"
+
+namespace
+{
+ COptions _theOptions;
+
+ const LPCTSTR sectionPersistence = _T("persistence");
+ const LPCTSTR entryShowFreeSpace = _T("showFreeSpace");
+ const LPCTSTR entryShowUnknown = _T("showUnknown");
+ const LPCTSTR entryShowFileTypes = _T("showFileTypes");
+ const LPCTSTR entryShowTreemap = _T("showTreemap");
+ const LPCTSTR entryShowToolbar = _T("showToolbar");
+ const LPCTSTR entryShowStatusbar = _T("showStatusbar");
+ const LPCTSTR entryMainWindowPlacement = _T("mainWindowPlacement");
+ const LPCTSTR entrySplitterPosS = _T("%s-splitterPos");
+ const LPCTSTR entryColumnOrderS = _T("%s-columnOrder");
+ const LPCTSTR entryColumnWidthsS = _T("%s-columnWidths");
+ const LPCTSTR entryDialogRectangleS = _T("%s-rectangle");
+// const LPCTSTR entrySortingColumnSN = _T("%s-sortColumn%d");
+// const LPCTSTR entrySortingAscendingSN = _T("%s-sortAscending%d");
+ const LPCTSTR entryConfigPage = _T("configPage");
+ const LPCTSTR entryConfigPositionX = _T("configPositionX");
+ const LPCTSTR entryConfigPositionY = _T("configPositionY");
+ const LPCTSTR entrySelectDrivesRadio = _T("selectDrivesRadio");
+ const LPCTSTR entrySelectDrivesFolder = _T("selectDrivesFolder");
+ const LPCTSTR entrySelectDrivesDrives = _T("selectDrivesDrives");
+ const LPCTSTR entryShowDeleteWarning = _T("showDeleteWarning");
+ const LPCTSTR sectionBarState = _T("persistence\\barstate");
+
+ const LPCTSTR entryLanguage = _T("language");
+
+ const LPCTSTR sectionOptions = _T("options");
+ const LPCTSTR entryTreelistGrid = _T("treelistGrid");
+ const LPCTSTR entryTreelistColorCount = _T("treelistColorCount");
+ const LPCTSTR entryTreelistColorN = _T("treelistColor%d");
+ const LPCTSTR entryHumanFormat = _T("humanFormat");
+ const LPCTSTR entryPacmanAnimation = _T("pacmanAnimation");
+ const LPCTSTR entryCushionShading = _T("cushionShading");
+ const LPCTSTR entryTreemapGrid = _T("treemapGrid");
+ const LPCTSTR entryTreemapGridColor = _T("treemapGridColor");
+ const LPCTSTR entryTreemapHighlightColor= _T("treemapHighlightColor");
+ const LPCTSTR entryHeightFactor = _T("heightFactor");
+ const LPCTSTR entryScaleFactor = _T("scaleFactor");
+ const LPCTSTR entryAmbientLight = _T("ambientLight");
+ const LPCTSTR entryFollowMountPoints = _T("followMountPoints");
+
+ const LPCTSTR sectionUserDefinedCleanupD = _T("options\\userDefinedCleanup%02d");
+ const LPCTSTR entryEnabled = _T("enabled");
+ const LPCTSTR entryTitle = _T("title");
+ const LPCTSTR entryWorksForDrives = _T("worksForDrives");
+ const LPCTSTR entryWorksForDirectories = _T("worksForDirectories");
+ const LPCTSTR entryWorksForFilesFolder = _T("worksForFilesFolder");
+ const LPCTSTR entryWorksForFiles = _T("worksForFiles");
+ const LPCTSTR entryCommandLine = _T("commandLine");
+ const LPCTSTR entryRecurseIntoSubdirectories= _T("recurseIntoSubdirectories");
+ const LPCTSTR entryAskForConfirmation = _T("askForConfirmation");
+ const LPCTSTR entryShowConsoleWindow = _T("showConsoleWindow");
+ const LPCTSTR entryWaitForCompletion = _T("waitForCompletion");
+ const LPCTSTR entryRefreshPolicy = _T("refreshPolicy");
+
+ COLORREF treelistColorDefault[TREELISTCOLORCOUNT] = {
+ RGB(0, 128, 192),
+ RGB(255, 128, 128),
+ RGB(128, 255, 128),
+ RGB(180, 180, 0),
+ RGB(0, 0, 255),
+ RGB(255, 0, 0),
+ RGB(0, 255, 0),
+ RGB(255, 255, 0)
+ };
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+bool CPersistence::GetShowFreeSpace()
+{
+ return GetProfileBool(sectionPersistence, entryShowFreeSpace, false);
+}
+
+void CPersistence::SetShowFreeSpace(bool show)
+{
+ SetProfileBool(sectionPersistence, entryShowFreeSpace, show);
+}
+
+bool CPersistence::GetShowUnknown()
+{
+ return GetProfileBool(sectionPersistence, entryShowUnknown, false);
+}
+
+void CPersistence::SetShowUnknown(bool show)
+{
+ SetProfileBool(sectionPersistence, entryShowUnknown, show);
+}
+
+bool CPersistence::GetShowFileTypes()
+{
+ return GetProfileBool(sectionPersistence, entryShowFileTypes, true);
+}
+
+void CPersistence::SetShowFileTypes(bool show)
+{
+ SetProfileBool(sectionPersistence, entryShowFileTypes, show);
+}
+
+bool CPersistence::GetShowTreemap()
+{
+ return GetProfileBool(sectionPersistence, entryShowTreemap, true);
+}
+
+void CPersistence::SetShowTreemap(bool show)
+{
+ SetProfileBool(sectionPersistence, entryShowTreemap, show);
+}
+
+bool CPersistence::GetShowToolbar()
+{
+ return GetProfileBool(sectionPersistence, entryShowToolbar, true);
+}
+
+void CPersistence::SetShowToolbar(bool show)
+{
+ SetProfileBool(sectionPersistence, entryShowToolbar, show);
+}
+
+bool CPersistence::GetShowStatusbar()
+{
+ return GetProfileBool(sectionPersistence, entryShowStatusbar, true);
+}
+
+void CPersistence::SetShowStatusbar(bool show)
+{
+ SetProfileBool(sectionPersistence, entryShowStatusbar, show);
+}
+
+void CPersistence::GetMainWindowPlacement(/* [in/out] */ WINDOWPLACEMENT& wp)
+{
+ ASSERT(wp.length == sizeof(wp));
+ CString s= GetProfileString(sectionPersistence, entryMainWindowPlacement, _T(""));
+ DecodeWindowPlacement(s, wp);
+ SanifyRect((CRect &)wp.rcNormalPosition);
+}
+
+void CPersistence::SetMainWindowPlacement(const WINDOWPLACEMENT& wp)
+{
+ CString s= EncodeWindowPlacement(wp);
+ SetProfileString(sectionPersistence, entryMainWindowPlacement, s);
+}
+
+void CPersistence::SetSplitterPos(LPCTSTR name, bool valid, double userpos)
+{
+ int pos;
+ if (valid)
+ pos= (int)(userpos * 100);
+ else
+ pos= -1;
+
+ SetProfileInt(sectionPersistence, MakeSplitterPosEntry(name), pos);
+}
+
+void CPersistence::GetSplitterPos(LPCTSTR name, bool& valid, double& userpos)
+{
+ int pos= GetProfileInt(sectionPersistence, MakeSplitterPosEntry(name), -1);
+ if (pos < 0 || pos > 100)
+ {
+ valid= false;
+ userpos= 0.5;
+ }
+ else
+ {
+ valid= true;
+ userpos= (double)pos / 100;
+ }
+}
+
+void CPersistence::SetColumnOrder(LPCTSTR name, const CArray<int, int>& arr)
+{
+ SetArray(MakeColumnOrderEntry(name), arr);
+}
+
+void CPersistence::GetColumnOrder(LPCTSTR name, /* in/out */ CArray<int, int>& arr)
+{
+ GetArray(MakeColumnOrderEntry(name), arr);
+}
+
+void CPersistence::SetColumnWidths(LPCTSTR name, const CArray<int, int>& arr)
+{
+ SetArray(MakeColumnWidthsEntry(name), arr);
+}
+
+void CPersistence::GetColumnWidths(LPCTSTR name, /* in/out */ CArray<int, int>& arr)
+{
+ GetArray(MakeColumnWidthsEntry(name), arr);
+}
+
+void CPersistence::SetDialogRectangle(LPCTSTR name, const CRect& rc)
+{
+ SetRect(MakeDialogRectangleEntry(name), rc);
+}
+
+void CPersistence::GetDialogRectangle(LPCTSTR name, CRect& rc)
+{
+ GetRect(MakeDialogRectangleEntry(name), rc);
+ SanifyRect(rc);
+}
+/*
+void CPersistence::SetSorting(LPCTSTR name, int column1, bool ascending1, int column2, bool ascending2)
+{
+ SetProfileInt(sectionPersistence, MakeSortingColumnEntry(name, 1), column1);
+ SetProfileBool(sectionPersistence, MakeSortingAscendingEntry(name, 1), ascending1);
+ SetProfileInt(sectionPersistence, MakeSortingColumnEntry(name, 2), column2);
+ SetProfileBool(sectionPersistence, MakeSortingAscendingEntry(name, 2), ascending2);
+}
+
+void CPersistence::GetSorting(LPCTSTR name, int columnCount, int& column1, bool& ascending1, int& column2, bool& ascending2)
+{
+ column1= GetProfileInt(sectionPersistence, MakeSortingColumnEntry(name, 1), column1);
+ CheckRange(column1, 0, columnCount - 1);
+ ascending1= GetProfileBool(sectionPersistence, MakeSortingAscendingEntry(name, 1), ascending1);
+
+ column2= GetProfileInt(sectionPersistence, MakeSortingColumnEntry(name, 2), column2);
+ CheckRange(column2, 0, columnCount - 1);
+ ascending2= GetProfileBool(sectionPersistence, MakeSortingAscendingEntry(name, 2), ascending2);
+}
+*/
+
+int CPersistence::GetConfigPage(int max)
+{
+ int n= GetProfileInt(sectionPersistence, entryConfigPage, 0);
+ CheckRange(n, 0, max);
+ return n;
+}
+
+void CPersistence::SetConfigPage(int page)
+{
+ SetProfileInt(sectionPersistence, entryConfigPage, page);
+}
+
+void CPersistence::GetConfigPosition(/* in/out */ CPoint& pt)
+{
+ pt.x= GetProfileInt(sectionPersistence, entryConfigPositionX, pt.x);
+ pt.y= GetProfileInt(sectionPersistence, entryConfigPositionY, pt.y);
+
+ CRect rc(pt, CSize(100, 100));
+ SanifyRect(rc);
+ pt= rc.TopLeft();
+}
+
+void CPersistence::SetConfigPosition(CPoint pt)
+{
+ SetProfileInt(sectionPersistence, entryConfigPositionX, pt.x);
+ SetProfileInt(sectionPersistence, entryConfigPositionY, pt.y);
+}
+
+CString CPersistence::GetBarStateSection()
+{
+ return sectionBarState;
+}
+
+int CPersistence::GetSelectDrivesRadio()
+{
+ int radio= GetProfileInt(sectionPersistence, entrySelectDrivesRadio, 0);
+ CheckRange(radio, 0, 2);
+ return radio;
+}
+
+void CPersistence::SetSelectDrivesRadio(int radio)
+{
+ SetProfileInt(sectionPersistence, entrySelectDrivesRadio, radio);
+}
+
+CString CPersistence::GetSelectDrivesFolder()
+{
+ return GetProfileString(sectionPersistence, entrySelectDrivesFolder, _T(""));
+}
+
+void CPersistence::SetSelectDrivesFolder(LPCTSTR folder)
+{
+ SetProfileString(sectionPersistence, entrySelectDrivesFolder, folder);
+}
+
+void CPersistence::GetSelectDrivesDrives(CStringArray& drives)
+{
+ drives.RemoveAll();
+ CString s= GetProfileString(sectionPersistence, entrySelectDrivesDrives, _T(""));
+ int i=0;
+ while (i < s.GetLength())
+ {
+ CString drive;
+ while (i < s.GetLength() && s[i] != _T('|'))
+ {
+ drive+= s[i];
+ i++;
+ }
+ if (i < s.GetLength())
+ i++;
+ drives.Add(drive);
+ }
+}
+
+void CPersistence::SetSelectDrivesDrives(const CStringArray& drives)
+{
+ CString s;
+ for (int i=0; i < drives.GetSize(); i++)
+ {
+ if (i > 0)
+ s+= _T("|");
+ s+= drives[i];
+ }
+ SetProfileString(sectionPersistence, entrySelectDrivesDrives, s);
+}
+
+bool CPersistence::GetShowDeleteWarning()
+{
+ return GetProfileBool(sectionPersistence, entryShowDeleteWarning, true);
+}
+
+void CPersistence::SetShowDeleteWarning(bool show)
+{
+ SetProfileBool(sectionPersistence, entryShowDeleteWarning, show);
+}
+
+void CPersistence::SetArray(LPCTSTR entry, const CArray<int, int>& arr)
+{
+ CString value;
+ for (int i=0; i < arr.GetSize(); i++)
+ {
+ CString s;
+ s.Format(_T("%d"), arr[i]);
+ if (i > 0)
+ value+= _T(",");
+ value+= s;
+ }
+ SetProfileString(sectionPersistence, entry, value);
+}
+
+void CPersistence::GetArray(LPCTSTR entry, /* in/out */ CArray<int, int>& rarr)
+{
+ CString s= GetProfileString(sectionPersistence, entry, _T(""));
+ CArray<int, int> arr;
+ int i=0;
+ while (i < s.GetLength())
+ {
+ int n= 0;
+ while (i < s.GetLength() && isdigit(s[i]))
+ {
+ n*= 10;
+ n+= s[i] - _T('0');
+ i++;
+ }
+ arr.Add(n);
+ if (i >= s.GetLength() || s[i] != _T(','))
+ break;
+ i++;
+ }
+ if (i >= s.GetLength() && arr.GetSize() == rarr.GetSize())
+ {
+ for (i=0; i < rarr.GetSize(); i++)
+ rarr[i]= arr[i];
+ }
+}
+
+void CPersistence::SetRect(LPCTSTR entry, const CRect& rc)
+{
+ CString s;
+ s.Format(_T("%d,%d,%d,%d"), rc.left, rc.top, rc.right, rc.bottom);
+ SetProfileString(sectionPersistence, entry, s);
+}
+
+void CPersistence::GetRect(LPCTSTR entry, CRect& rc)
+{
+ CString s= GetProfileString(sectionPersistence, entry, _T(""));
+ CRect tmp;
+ int r= _stscanf(s, _T("%d,%d,%d,%d"), &tmp.left, &tmp.top, &tmp.right, &tmp.bottom);
+ if (r == 4)
+ rc= tmp;
+}
+
+void CPersistence::SanifyRect(CRect& rc)
+{
+ const int visible = 30;
+
+ rc.NormalizeRect();
+
+ CRect rcDesktop;
+ CWnd::GetDesktopWindow()->GetWindowRect(rcDesktop);
+
+ if (rc.Width() > rcDesktop.Width())
+ rc.right= rc.left + rcDesktop.Width();
+ if (rc.Height() > rcDesktop.Height())
+ rc.bottom= rc.top + rcDesktop.Height();
+
+ if (rc.left < 0)
+ rc.OffsetRect(-rc.left, 0);
+ if (rc.left > rcDesktop.right - visible)
+ rc.OffsetRect(-visible, 0);
+
+ if (rc.top < 0)
+ rc.OffsetRect(-rc.top, 0);
+ if (rc.top > rcDesktop.bottom - visible)
+ rc.OffsetRect(0, -visible);
+}
+
+CString CPersistence::MakeSplitterPosEntry(LPCTSTR name)
+{
+ CString entry;
+ entry.Format(entrySplitterPosS, name);
+ return entry;
+}
+
+CString CPersistence::MakeColumnOrderEntry(LPCTSTR name)
+{
+ CString entry;
+ entry.Format(entryColumnOrderS, name);
+ return entry;
+}
+
+CString CPersistence::MakeDialogRectangleEntry(LPCTSTR name)
+{
+ CString entry;
+ entry.Format(entryDialogRectangleS, name);
+ return entry;
+}
+
+CString CPersistence::MakeColumnWidthsEntry(LPCTSTR name)
+{
+ CString entry;
+ entry.Format(entryColumnWidthsS, name);
+ return entry;
+}
+
+/*
+CString CPersistence::MakeSortingColumnEntry(LPCTSTR name, int n)
+{
+ CString entry;
+ entry.Format(entrySortingColumnSN, name, n);
+ return entry;
+}
+
+CString CPersistence::MakeSortingAscendingEntry(LPCTSTR name, int n)
+{
+ CString entry;
+ entry.Format(entrySortingAscendingSN, name, n);
+ return entry;
+}
+*/
+
+CString CPersistence::EncodeWindowPlacement(const WINDOWPLACEMENT& wp)
+{
+ CString s;
+ s.Format(
+ _T("%u,%u,")
+ _T("%ld,%ld,%ld,%ld,")
+ _T("%ld,%ld,%ld,%ld"),
+ wp.flags, wp.showCmd,
+ wp.ptMinPosition.x, wp.ptMinPosition.y, wp.ptMaxPosition.x, wp.ptMaxPosition.y,
+ wp.rcNormalPosition.left, wp.rcNormalPosition.right, wp.rcNormalPosition.top, wp.rcNormalPosition.bottom
+ );
+ return s;
+}
+
+void CPersistence::DecodeWindowPlacement(const CString& s, WINDOWPLACEMENT& rwp)
+{
+ WINDOWPLACEMENT wp;
+ wp.length= sizeof(wp);
+
+ int r= _stscanf(s,
+ _T("%u,%u,")
+ _T("%ld,%ld,%ld,%ld,")
+ _T("%ld,%ld,%ld,%ld"),
+ &wp.flags, &wp.showCmd,
+ &wp.ptMinPosition.x, &wp.ptMinPosition.y, &wp.ptMaxPosition.x, &wp.ptMaxPosition.y,
+ &wp.rcNormalPosition.left, &wp.rcNormalPosition.right, &wp.rcNormalPosition.top, &wp.rcNormalPosition.bottom
+ );
+
+ if (r == 10)
+ rwp= wp;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+LANGID CLanguageOptions::GetLanguage()
+{
+ LANGID defaultLangid= LANGIDFROMLCID(GetUserDefaultLCID());
+ LANGID id= (LANGID)GetProfileInt(sectionOptions, entryLanguage, defaultLangid);
+ return id;
+}
+
+void CLanguageOptions::SetLanguage(LANGID langid)
+{
+ SetProfileInt(sectionOptions, entryLanguage, langid);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+COptions *GetOptions()
+{
+ return &_theOptions;
+}
+
+
+COptions::COptions()
+{
+ m_treelistGrid= true;
+}
+
+bool COptions::IsTreelistGrid()
+{
+ return m_treelistGrid;
+}
+
+void COptions::SetTreelistGrid(bool show)
+{
+ if (m_treelistGrid != show)
+ {
+ m_treelistGrid= show;
+ GetDocument()->UpdateAllViews(NULL, HINT_TREELISTSTYLECHANGED);
+ }
+}
+
+void COptions::GetTreelistColors(COLORREF color[TREELISTCOLORCOUNT])
+{
+ for (int i=0; i < TREELISTCOLORCOUNT; i++)
+ color[i]= m_treelistColor[i];
+}
+
+void COptions::SetTreelistColors(const COLORREF color[TREELISTCOLORCOUNT])
+{
+ for (int i=0; i < TREELISTCOLORCOUNT; i++)
+ m_treelistColor[i]= color[i];
+ GetDocument()->UpdateAllViews(NULL, HINT_TREELISTSTYLECHANGED);
+}
+
+COLORREF COptions::GetTreelistColor(int i)
+{
+ ASSERT(i >= 0);
+ ASSERT(i < m_treelistColorCount);
+ return m_treelistColor[i];
+}
+
+int COptions::GetTreelistColorCount()
+{
+ return m_treelistColorCount;
+}
+
+void COptions::SetTreelistColorCount(int count)
+{
+ if (m_treelistColorCount != count)
+ {
+ m_treelistColorCount= count;
+ GetDocument()->UpdateAllViews(NULL, HINT_TREELISTSTYLECHANGED);
+ }
+}
+
+bool COptions::IsHumanFormat()
+{
+ return m_humanFormat;
+}
+
+void COptions::SetHumanFormat(bool human)
+{
+ if (m_humanFormat != human)
+ {
+ m_humanFormat= human;
+ GetDocument()->UpdateAllViews(NULL, HINT_NULL);
+ GetApp()->UpdateRamUsage();
+ }
+}
+
+bool COptions::IsPacmanAnimation()
+{
+ return m_pacmanAnimation;
+}
+
+void COptions::SetPacmanAnimation(bool animate)
+{
+ if (m_pacmanAnimation != animate)
+ {
+ m_pacmanAnimation= animate;
+ }
+}
+
+bool COptions::IsCushionShading()
+{
+ return m_cushionShading;
+}
+
+void COptions::SetCushionShading(bool shade)
+{
+ if (m_cushionShading != shade)
+ {
+ m_cushionShading= shade;
+ GetDocument()->UpdateAllViews(NULL, HINT_CUSHIONSHADINGCHANGED);
+ }
+}
+
+bool COptions::IsTreemapGrid()
+{
+ return m_treemapGrid;
+}
+
+void COptions::SetTreemapGrid(bool show)
+{
+ if (m_treemapGrid != show)
+ {
+ m_treemapGrid= show;
+ GetDocument()->UpdateAllViews(NULL, HINT_TREEMAPSTYLECHANGED);
+ }
+}
+
+COLORREF COptions::GetTreemapGridColor()
+{
+ return m_treemapGridColor;
+}
+
+void COptions::SetTreemapGridColor(COLORREF color)
+{
+ if (m_treemapGridColor != color)
+ {
+ m_treemapGridColor= color;
+ GetDocument()->UpdateAllViews(NULL, HINT_TREEMAPSTYLECHANGED);
+ }
+}
+
+COLORREF COptions::GetTreemapHighlightColor()
+{
+ return m_treemapHighlightColor;
+}
+
+void COptions::SetTreemapHighlightColor(COLORREF color)
+{
+ if (m_treemapHighlightColor != color)
+ {
+ m_treemapHighlightColor= color;
+ GetDocument()->UpdateAllViews(NULL, HINT_SELECTIONCHANGED);
+ }
+}
+
+int COptions::GetHeightFactor() // "H"
+{
+ return m_heightFactor;
+}
+
+void COptions::SetHeightFactor(int h)
+{
+ if (m_heightFactor != h)
+ {
+ m_heightFactor= h;
+ GetDocument()->UpdateAllViews(NULL, HINT_TREEMAPSTYLECHANGED);
+ }
+}
+
+int COptions::GetHeightFactorDefault()
+{
+ return 40;
+}
+
+void COptions::GetHeightFactorRange(int& min, int& max)
+{
+ min= 0;
+ max= 200;
+}
+
+
+int COptions::GetScaleFactor() // "F"
+{
+ return m_scaleFactor;
+}
+
+void COptions::SetScaleFactor(int f)
+{
+ if (m_scaleFactor != f)
+ {
+ m_scaleFactor= f;
+ GetDocument()->UpdateAllViews(NULL, HINT_TREEMAPSTYLECHANGED);
+ }
+}
+
+int COptions::GetScaleFactorDefault()
+{
+ return 90;
+}
+
+void COptions::GetScaleFactorRange(int& min, int& max)
+{
+ min= 20;
+ max= 100;
+}
+
+int COptions::GetAmbientLight()
+{
+ return m_ambientLight;
+}
+
+void COptions::SetAmbientLight(int a)
+{
+ if (m_ambientLight != a)
+ {
+ m_ambientLight= a;
+ GetDocument()->UpdateAllViews(NULL, HINT_TREEMAPSTYLECHANGED);
+ }
+}
+
+int COptions::GetAmbientLightDefault()
+{
+ return 15;
+}
+
+void COptions::GetAmbientLightRange(int& min, int& max)
+{
+ min= 0;
+ max= 100;
+}
+
+void COptions::GetUserDefinedCleanups(USERDEFINEDCLEANUP udc[USERDEFINEDCLEANUPCOUNT])
+{
+ for (int i=0; i < USERDEFINEDCLEANUPCOUNT; i++)
+ udc[i]= m_userDefinedCleanup[i];
+}
+
+void COptions::SetUserDefinedCleanups(const USERDEFINEDCLEANUP udc[USERDEFINEDCLEANUPCOUNT])
+{
+ for (int i=0; i < USERDEFINEDCLEANUPCOUNT; i++)
+ m_userDefinedCleanup[i]= udc[i];
+}
+
+void COptions::GetEnabledUserDefinedCleanups(CArray<int, int>& indices)
+{
+ indices.RemoveAll();
+ for (int i=0; i < USERDEFINEDCLEANUPCOUNT; i++)
+ if (m_userDefinedCleanup[i].enabled)
+ indices.Add(i);
+}
+
+bool COptions::IsUserDefinedCleanupEnabled(int i)
+{
+ ASSERT(i >= 0);
+ ASSERT(i < USERDEFINEDCLEANUPCOUNT);
+ return m_userDefinedCleanup[i].enabled;
+}
+
+const USERDEFINEDCLEANUP *COptions::GetUserDefinedCleanup(int i)
+{
+ ASSERT(i >= 0);
+ ASSERT(i < USERDEFINEDCLEANUPCOUNT);
+ ASSERT(m_userDefinedCleanup[i].enabled);
+
+ return &m_userDefinedCleanup[i];
+}
+
+bool COptions::IsFollowMountPoints()
+{
+ return m_followMountPoints;
+}
+
+void COptions::SetFollowMountPoints(bool follow)
+{
+ if (m_followMountPoints != follow)
+ {
+ m_followMountPoints= follow;
+ GetDocument()->RefreshMountPointItems();
+ }
+}
+
+void COptions::SaveToRegistry()
+{
+ SetProfileBool(sectionOptions, entryTreelistGrid, m_treelistGrid);
+ SetProfileInt(sectionOptions, entryTreelistColorCount, m_treelistColorCount);
+ for (int i=0; i < TREELISTCOLORCOUNT; i++)
+ {
+ CString entry;
+ entry.Format(entryTreelistColorN, i);
+ SetProfileInt(sectionOptions, entry, m_treelistColor[i]);
+ }
+ SetProfileBool(sectionOptions, entryHumanFormat, m_humanFormat);
+ SetProfileBool(sectionOptions, entryPacmanAnimation, m_pacmanAnimation);
+ SetProfileBool(sectionOptions, entryCushionShading, m_cushionShading);
+ SetProfileBool(sectionOptions, entryTreemapGrid, m_treemapGrid);
+ SetProfileInt(sectionOptions, entryTreemapGridColor, m_treemapGridColor);
+ SetProfileInt(sectionOptions, entryTreemapHighlightColor, m_treemapHighlightColor);
+ SetProfileInt(sectionOptions, entryHeightFactor, m_heightFactor);
+ SetProfileInt(sectionOptions, entryScaleFactor, m_scaleFactor);
+ SetProfileInt(sectionOptions, entryAmbientLight, m_ambientLight);
+ SetProfileBool(sectionOptions, entryFollowMountPoints, m_followMountPoints);
+ for (i=0; i < USERDEFINEDCLEANUPCOUNT; i++)
+ SaveUserDefinedCleanup(i);
+}
+
+void COptions::LoadFromRegistry()
+{
+ int min;
+ int max;
+ m_treelistGrid= GetProfileBool(sectionOptions, entryTreelistGrid, false);
+ m_treelistColorCount= GetProfileInt(sectionOptions, entryTreelistColorCount, 4);
+ CheckRange(m_treelistColorCount, 1, TREELISTCOLORCOUNT);
+ for (int i=0; i < TREELISTCOLORCOUNT; i++)
+ {
+ CString entry;
+ entry.Format(entryTreelistColorN, i);
+ m_treelistColor[i]= GetProfileInt(sectionOptions, entry, treelistColorDefault[i]);
+ }
+ m_humanFormat= GetProfileBool(sectionOptions, entryHumanFormat, true);
+ m_pacmanAnimation= GetProfileBool(sectionOptions, entryPacmanAnimation, true);
+ m_cushionShading= GetProfileBool(sectionOptions, entryCushionShading, true);
+ m_treemapGrid= GetProfileBool(sectionOptions, entryTreemapGrid, false);
+ m_treemapGridColor= GetProfileInt(sectionOptions, entryTreemapGridColor, RGB(0, 0, 0));
+ m_treemapHighlightColor= GetProfileInt(sectionOptions, entryTreemapHighlightColor, RGB(0,255,255));
+ m_heightFactor= GetProfileInt(sectionOptions, entryHeightFactor, GetHeightFactorDefault());
+ GetHeightFactorRange(min, max);
+ CheckRange(m_heightFactor, min, max);
+ m_scaleFactor= GetProfileInt(sectionOptions, entryScaleFactor, GetScaleFactorDefault());
+ GetScaleFactorRange(min, max);
+ CheckRange(m_scaleFactor, min, max);
+ m_ambientLight= GetProfileInt(sectionOptions, entryAmbientLight, GetAmbientLightDefault());
+ GetAmbientLightRange(min, max);
+ CheckRange(m_ambientLight, min, max);
+ m_followMountPoints= GetProfileBool(sectionOptions, entryFollowMountPoints, false);
+ for (i=0; i < USERDEFINEDCLEANUPCOUNT; i++)
+ ReadUserDefinedCleanup(i);
+}
+
+void COptions::ReadUserDefinedCleanup(int i)
+{
+ CString section;
+ section.Format(sectionUserDefinedCleanupD, i);
+
+ CString defaultTitle;
+ defaultTitle.FormatMessage(IDS_USERDEFINEDCLEANUPd, i);
+
+ m_userDefinedCleanup[i].enabled= GetProfileBool(section, entryEnabled, false);
+ m_userDefinedCleanup[i].title= GetProfileString(section, entryTitle, defaultTitle);
+ m_userDefinedCleanup[i].worksForDrives= GetProfileBool(section, entryWorksForDrives, false);
+ m_userDefinedCleanup[i].worksForDirectories= GetProfileBool(section, entryWorksForDirectories, false);
+ m_userDefinedCleanup[i].worksForFilesFolder= GetProfileBool(section, entryWorksForFilesFolder, false);
+ m_userDefinedCleanup[i].worksForFiles= GetProfileBool(section, entryWorksForFiles, false);
+ m_userDefinedCleanup[i].commandLine= GetProfileString(section, entryCommandLine, _T(""));
+ m_userDefinedCleanup[i].recurseIntoSubdirectories= GetProfileBool(section, entryRecurseIntoSubdirectories, false);
+ m_userDefinedCleanup[i].askForConfirmation= GetProfileBool(section, entryAskForConfirmation, true);
+ m_userDefinedCleanup[i].showConsoleWindow= GetProfileBool(section, entryShowConsoleWindow, true);
+ m_userDefinedCleanup[i].waitForCompletion= GetProfileBool(section, entryWaitForCompletion, true);
+ int r= GetProfileInt(section, entryRefreshPolicy, RP_NO_REFRESH);
+ CheckRange(r, 0, REFRESHPOLICYCOUNT);
+ m_userDefinedCleanup[i].refreshPolicy= (REFRESHPOLICY)r;
+}
+
+void COptions::SaveUserDefinedCleanup(int i)
+{
+ CString section;
+ section.Format(sectionUserDefinedCleanupD, i);
+
+ SetProfileBool(section, entryEnabled, m_userDefinedCleanup[i].enabled);
+ SetProfileString(section, entryTitle, m_userDefinedCleanup[i].title);
+ SetProfileBool(section, entryWorksForDrives, m_userDefinedCleanup[i].worksForDrives);
+ SetProfileBool(section, entryWorksForDirectories, m_userDefinedCleanup[i].worksForDirectories);
+ SetProfileBool(section, entryWorksForFilesFolder, m_userDefinedCleanup[i].worksForFilesFolder);
+ SetProfileBool(section, entryWorksForFiles, m_userDefinedCleanup[i].worksForFiles);
+ SetProfileString(section, entryCommandLine, m_userDefinedCleanup[i].commandLine);
+ SetProfileBool(section, entryRecurseIntoSubdirectories, m_userDefinedCleanup[i].recurseIntoSubdirectories);
+ SetProfileBool(section, entryAskForConfirmation, m_userDefinedCleanup[i].askForConfirmation);
+ SetProfileBool(section, entryShowConsoleWindow, m_userDefinedCleanup[i].showConsoleWindow);
+ SetProfileBool(section, entryWaitForCompletion, m_userDefinedCleanup[i].waitForCompletion);
+ SetProfileInt(section, entryRefreshPolicy, m_userDefinedCleanup[i].refreshPolicy);
+}
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CRegistryUser::SetProfileString(LPCTSTR section, LPCTSTR entry, LPCTSTR value)
+{
+ AfxGetApp()->WriteProfileString(section, entry, value);
+}
+
+CString CRegistryUser::GetProfileString(LPCTSTR section, LPCTSTR entry, LPCTSTR defaultValue)
+{
+ return AfxGetApp()->GetProfileString(section, entry, defaultValue);
+}
+
+void CRegistryUser::SetProfileInt(LPCTSTR section, LPCTSTR entry, int value)
+{
+ AfxGetApp()->WriteProfileInt(section, entry, value);
+}
+
+int CRegistryUser::GetProfileInt(LPCTSTR section, LPCTSTR entry, int defaultValue)
+{
+ return AfxGetApp()->GetProfileInt(section, entry, defaultValue);
+}
+
+void CRegistryUser::SetProfileBool(LPCTSTR section, LPCTSTR entry, bool value)
+{
+ SetProfileInt(section, entry, (int)value);
+}
+
+bool CRegistryUser::GetProfileBool(LPCTSTR section, LPCTSTR entry, bool defaultValue)
+{
+ return GetProfileInt(section, entry, defaultValue) != 0;
+}
+
+void CRegistryUser::CheckRange(int& value, int min, int max)
+{
+ if (value < min)
+ value= min;
+ if (value > max)
+ value= max;
+}
+
diff --git a/windirstat/options.h b/windirstat/options.h
new file mode 100644
index 0000000..2a38373
--- /dev/null
+++ b/windirstat/options.h
@@ -0,0 +1,263 @@
+// options.h - Declaration of CRegistryUser, COptions and CPersistence
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+class COptions;
+
+enum REFRESHPOLICY
+{
+ RP_NO_REFRESH,
+ RP_REFRESH_THIS_ENTRY,
+ RP_REFRESH_THIS_ENTRYS_PARENT,
+ // RP_ASSUME_ENTRY_HAS_BEEN_DELETED, // feature not implemented.
+ REFRESHPOLICYCOUNT
+};
+
+struct USERDEFINEDCLEANUP
+{
+ bool enabled;
+ CString title;
+ bool worksForDrives;
+ bool worksForDirectories;
+ bool worksForFilesFolder;
+ bool worksForFiles;
+ CString commandLine;
+ bool recurseIntoSubdirectories;
+ bool askForConfirmation;
+ bool showConsoleWindow;
+ bool waitForCompletion;
+ REFRESHPOLICY refreshPolicy;
+};
+
+#define USERDEFINEDCLEANUPCOUNT 10
+
+#define TREELISTCOLORCOUNT 8
+
+
+//
+// CRegistryUser. (Base class for COptions and CPersistence.)
+// Can read from and write to the registry.
+//
+class CRegistryUser
+{
+public:
+ static void SetProfileString(LPCTSTR section, LPCTSTR entry, LPCTSTR value);
+ static CString GetProfileString(LPCTSTR section, LPCTSTR entry, LPCTSTR defaultValue);
+
+ static void SetProfileInt(LPCTSTR section, LPCTSTR entry, int value);
+ static int GetProfileInt(LPCTSTR section, LPCTSTR entry, int defaultValue);
+
+ static void SetProfileBool(LPCTSTR section, LPCTSTR entry, bool value);
+ static bool GetProfileBool(LPCTSTR section, LPCTSTR entry, bool defaultValue);
+
+ static void CheckRange(int& value, int min, int max);
+};
+
+
+//
+// CPersistence. Reads from and writes to the registry all the persistent settings
+// like window position, column order etc.
+//
+class CPersistence: private CRegistryUser
+{
+public:
+ static bool GetShowFreeSpace();
+ static void SetShowFreeSpace(bool show);
+
+ static bool GetShowUnknown();
+ static void SetShowUnknown(bool show);
+
+ static bool GetShowFileTypes();
+ static void SetShowFileTypes(bool show);
+
+ static bool GetShowTreemap();
+ static void SetShowTreemap(bool show);
+
+ static bool GetShowToolbar();
+ static void SetShowToolbar(bool show);
+
+ static bool GetShowStatusbar();
+ static void SetShowStatusbar(bool show);
+
+ static void GetMainWindowPlacement(/* [in/out] */ WINDOWPLACEMENT& wp);
+ static void SetMainWindowPlacement(const WINDOWPLACEMENT& wp);
+
+ static void SetSplitterPos(LPCTSTR name, bool valid, double userpos);
+ static void GetSplitterPos(LPCTSTR name, bool& valid, double& userpos);
+
+ static void SetColumnOrder(LPCTSTR name, const CArray<int, int>& arr);
+ static void GetColumnOrder(LPCTSTR name, /* in/out */ CArray<int, int>& arr);
+
+ static void SetColumnWidths(LPCTSTR name, const CArray<int, int>& arr);
+ static void GetColumnWidths(LPCTSTR name, /* in/out */ CArray<int, int>& arr);
+
+ static void SetDialogRectangle(LPCTSTR name, const CRect& rc);
+ static void GetDialogRectangle(LPCTSTR name, CRect& rc);
+
+// static void SetSorting(LPCTSTR name, int column1, bool ascending1, int column2, bool ascending2);
+// static void GetSorting(LPCTSTR name, int columnCount, int& column1, bool& ascending1, int& column2, bool& ascending2);
+
+ static int GetConfigPage(int max);
+ static void SetConfigPage(int page);
+
+ static void GetConfigPosition(/* in/out */ CPoint& pt);
+ static void SetConfigPosition(CPoint pt);
+
+ static CString GetBarStateSection();
+
+ static int GetSelectDrivesRadio();
+ static void SetSelectDrivesRadio(int radio);
+
+ static CString GetSelectDrivesFolder();
+ static void SetSelectDrivesFolder(LPCTSTR folder);
+
+ static void GetSelectDrivesDrives(CStringArray& drives);
+ static void SetSelectDrivesDrives(const CStringArray& drives);
+
+ static bool GetShowDeleteWarning();
+ static void SetShowDeleteWarning(bool show);
+
+private:
+ static void SetArray(LPCTSTR entry, const CArray<int, int>& arr);
+ static void GetArray(LPCTSTR entry, /* in/out */ CArray<int, int>& arr);
+ static void SetRect(LPCTSTR entry, const CRect& rc);
+ static void GetRect(LPCTSTR entry, CRect& rc);
+ static void SanifyRect(CRect& rc);
+
+ static CString EncodeWindowPlacement(const WINDOWPLACEMENT& wp);
+ static void DecodeWindowPlacement(const CString& s, WINDOWPLACEMENT& wp);
+ static CString MakeSplitterPosEntry(LPCTSTR name);
+ static CString MakeColumnOrderEntry(LPCTSTR name);
+ static CString MakeColumnWidthsEntry(LPCTSTR name);
+ //static CString MakeSortingColumnEntry(LPCTSTR name, int n);
+ //static CString MakeSortingAscendingEntry(LPCTSTR name, int n);
+ static CString MakeDialogRectangleEntry(LPCTSTR name);
+
+
+};
+
+//
+// CLanguageOptions. Is separated from COptions because it
+// must be loaded earlier.
+//
+
+class CLanguageOptions: private CRegistryUser
+{
+public:
+ static LANGID GetLanguage();
+ static void SetLanguage(LANGID langid);
+};
+
+
+
+
+//
+// COptions. Represents all the data which can be viewed
+// and modified in the "Configure WinDirStat" dialog.
+//
+
+// COptions is a singleton.
+COptions *GetOptions();
+
+class COptions: private CRegistryUser
+{
+public:
+ COptions();
+
+ void LoadFromRegistry();
+ void SaveToRegistry();
+
+ bool IsTreelistGrid();
+ void SetTreelistGrid(bool show);
+
+ void GetTreelistColors(COLORREF color[TREELISTCOLORCOUNT]);
+ void SetTreelistColors(const COLORREF color[TREELISTCOLORCOUNT]);
+ COLORREF GetTreelistColor(int i);
+
+ int GetTreelistColorCount();
+ void SetTreelistColorCount(int count);
+
+ bool IsHumanFormat();
+ void SetHumanFormat(bool human);
+
+ bool IsPacmanAnimation();
+ void SetPacmanAnimation(bool animate);
+
+ bool IsCushionShading();
+ void SetCushionShading(bool shade);
+
+ bool IsTreemapGrid();
+ void SetTreemapGrid(bool show);
+
+ COLORREF GetTreemapGridColor();
+ void SetTreemapGridColor(COLORREF color);
+
+ COLORREF GetTreemapHighlightColor();
+ void SetTreemapHighlightColor(COLORREF color);
+
+ int GetHeightFactor(); // Percent
+ void SetHeightFactor(int h); // Percent
+ int GetHeightFactorDefault();
+ void GetHeightFactorRange(int& min, int& max);
+
+ int GetScaleFactor(); // Percent
+ void SetScaleFactor(int f); // Percent
+ int GetScaleFactorDefault();
+ void GetScaleFactorRange(int& min, int& max);
+
+ int GetAmbientLight(); // Percent
+ void SetAmbientLight(int a); // Percent
+ int GetAmbientLightDefault();
+ void GetAmbientLightRange(int& min, int& max);
+
+ bool IsFollowMountPoints();
+ void SetFollowMountPoints(bool follow);
+
+ void GetUserDefinedCleanups(USERDEFINEDCLEANUP udc[USERDEFINEDCLEANUPCOUNT]);
+ void SetUserDefinedCleanups(const USERDEFINEDCLEANUP udc[USERDEFINEDCLEANUPCOUNT]);
+
+ void GetEnabledUserDefinedCleanups(CArray<int, int>& indices);
+ bool IsUserDefinedCleanupEnabled(int i);
+ const USERDEFINEDCLEANUP *GetUserDefinedCleanup(int i);
+
+
+private:
+ void ReadUserDefinedCleanup(int i);
+ void SaveUserDefinedCleanup(int i);
+
+ bool m_treelistGrid;
+ COLORREF m_treelistColor[TREELISTCOLORCOUNT];
+ int m_treelistColorCount;
+ bool m_humanFormat;
+ bool m_pacmanAnimation;
+ bool m_cushionShading;
+ bool m_treemapGrid;
+ COLORREF m_treemapGridColor;
+ COLORREF m_treemapHighlightColor;
+ int m_heightFactor; // H (percent)
+ int m_scaleFactor; // F (percent)
+ int m_ambientLight; // Ia (percent)
+ bool m_followMountPoints;
+ USERDEFINEDCLEANUP m_userDefinedCleanup[USERDEFINEDCLEANUPCOUNT];
+};
+
+
diff --git a/windirstat/osspecific.cpp b/windirstat/osspecific.cpp
new file mode 100644
index 0000000..e31a8d3
--- /dev/null
+++ b/windirstat/osspecific.cpp
@@ -0,0 +1,212 @@
+// osspecific.cpp - Implementation of the platform-specific classes
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "osspecific.h"
+
+#ifdef UNICODE
+#define TSPEC "W"
+#else
+#define TSPEC "A"
+#endif
+
+#define GETPROC(name) m_##name = ( m_dll != 0 ? (Type##name)GetProcAddress(m_dll, #name) : NULL )
+#define TGETPROC(name) m_##name = ( m_dll != 0 ? (Type##name)GetProcAddress(m_dll, #name TSPEC) : NULL )
+
+#define CHECK(name) if (m_##name == 0) return false
+
+/////////////////////////////////////////////////////////////////////////////
+
+CVolumeApi::CVolumeApi()
+{
+ m_dll= LoadLibrary(_T("kernel32.dll"));
+
+ TGETPROC(GetVolumeNameForVolumeMountPoint);
+ TGETPROC(FindFirstVolume);
+ TGETPROC(FindNextVolume);
+ GETPROC(FindVolumeClose);
+ TGETPROC(FindFirstVolumeMountPoint);
+ TGETPROC(FindNextVolumeMountPoint);
+ GETPROC(FindVolumeMountPointClose);
+}
+
+CVolumeApi::~CVolumeApi()
+{
+ if (m_dll != NULL)
+ FreeLibrary(m_dll);
+ // "It is not safe to call FreeLibrary from DllMain."
+ // Therefore, don't use global variables of type CVolumeApi in a DLL.
+}
+
+bool CVolumeApi::IsSupported()
+{
+ CHECK(GetVolumeNameForVolumeMountPoint);
+ CHECK(FindFirstVolume);
+ CHECK(FindNextVolume);
+ CHECK(FindVolumeClose);
+ CHECK(FindFirstVolumeMountPoint);
+ CHECK(FindNextVolumeMountPoint);
+ CHECK(FindVolumeMountPointClose);
+
+ return true;
+}
+
+
+BOOL CVolumeApi::GetVolumeNameForVolumeMountPoint(LPCTSTR lpszVolumeMountPoint, LPTSTR lpszVolumeName, DWORD cchBufferLength)
+{
+ ASSERT(IsSupported());
+ return (*m_GetVolumeNameForVolumeMountPoint)(lpszVolumeMountPoint, lpszVolumeName, cchBufferLength);
+}
+
+HANDLE CVolumeApi::FindFirstVolume(LPTSTR lpszVolumeName, DWORD cchBufferLength)
+{
+ ASSERT(IsSupported());
+ return (*m_FindFirstVolume)(lpszVolumeName, cchBufferLength);
+}
+
+BOOL CVolumeApi::FindNextVolume(HANDLE hFindVolume, LPTSTR lpszVolumeName, DWORD cchBufferLength)
+{
+ ASSERT(IsSupported());
+ return (*m_FindNextVolume)(hFindVolume, lpszVolumeName, cchBufferLength);
+}
+
+BOOL CVolumeApi::FindVolumeClose(HANDLE hFindVolume)
+{
+ ASSERT(IsSupported());
+ return (*m_FindVolumeClose)(hFindVolume);
+}
+
+
+HANDLE CVolumeApi::FindFirstVolumeMountPoint(LPCTSTR lpszRootPathName, LPTSTR lpszVolumeMountPoint, DWORD cchBufferLength)
+{
+ ASSERT(IsSupported());
+ return (*m_FindFirstVolumeMountPoint)(lpszRootPathName, lpszVolumeMountPoint, cchBufferLength);
+}
+
+BOOL CVolumeApi::FindNextVolumeMountPoint(HANDLE hFindVolumeMountPoint, LPTSTR lpszVolumeMountPoint, DWORD cchBufferLength)
+{
+ ASSERT(IsSupported());
+ return (*m_FindNextVolumeMountPoint)(hFindVolumeMountPoint, lpszVolumeMountPoint, cchBufferLength);
+}
+
+BOOL CVolumeApi::FindVolumeMountPointClose(HANDLE hFindVolumeMountPoint)
+{
+ ASSERT(IsSupported());
+ return (*m_FindVolumeMountPointClose)(hFindVolumeMountPoint);
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+CRecycleBinApi::CRecycleBinApi()
+{
+ m_dll= LoadLibrary(_T("shell32.dll"));
+
+ TGETPROC(SHEmptyRecycleBin);
+ TGETPROC(SHQueryRecycleBin);
+}
+
+CRecycleBinApi::~CRecycleBinApi()
+{
+ if (m_dll != NULL)
+ FreeLibrary(m_dll);
+}
+
+bool CRecycleBinApi::IsSupported()
+{
+ CHECK(SHEmptyRecycleBin);
+ CHECK(SHQueryRecycleBin);
+
+ return true;
+}
+
+HRESULT CRecycleBinApi::SHEmptyRecycleBin(HWND hwnd, LPCTSTR pszRootPath, DWORD dwFlags)
+{
+ ASSERT(IsSupported());
+ return (*m_SHEmptyRecycleBin)(hwnd, pszRootPath, dwFlags);
+}
+
+HRESULT CRecycleBinApi::SHQueryRecycleBin(LPCTSTR pszRootPath, LPSHQUERYRBINFO pSHQueryRBInfo)
+{
+ ASSERT(IsSupported());
+ return (*m_SHQueryRecycleBin)(pszRootPath, pSHQueryRBInfo);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+CPsapi::CPsapi()
+{
+ m_dll= LoadLibrary(_T("psapi.dll"));
+
+ GETPROC(GetProcessMemoryInfo);
+}
+
+CPsapi::~CPsapi()
+{
+ if (m_dll != NULL)
+ FreeLibrary(m_dll);
+}
+
+bool CPsapi::IsSupported()
+{
+ CHECK(GetProcessMemoryInfo);
+ return true;
+}
+
+BOOL CPsapi::GetProcessMemoryInfo(HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb)
+{
+ ASSERT(IsSupported());
+ return (*m_GetProcessMemoryInfo)(Process, ppsmemCounters, cb);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+CMapi32Api::CMapi32Api()
+{
+ m_dll= LoadLibrary(_T("mapi32.dll"));
+ GETPROC(MAPISendMail);
+}
+
+CMapi32Api::~CMapi32Api()
+{
+ if (m_dll != NULL)
+ FreeLibrary(m_dll);
+}
+
+bool CMapi32Api::IsDllPresent()
+{
+ return SearchPath(NULL, _T("mapi32.dll"), NULL, 0, NULL, NULL) != 0;
+}
+
+bool CMapi32Api::IsSupported()
+{
+ CHECK(MAPISendMail);
+ return true;
+}
+
+ULONG CMapi32Api::MAPISendMail(LHANDLE lhSession, ULONG ulUIParam, lpMapiMessage lpMessage, FLAGS flFlags, ULONG ulReserved)
+{
+ ASSERT(IsSupported());
+ return (*m_MAPISendMail)(lhSession, ulUIParam, lpMessage, flFlags, ulReserved);
+}
+
diff --git a/windirstat/osspecific.h b/windirstat/osspecific.h
new file mode 100644
index 0000000..20d7cfc
--- /dev/null
+++ b/windirstat/osspecific.h
@@ -0,0 +1,137 @@
+// osspecific.h - Declaration of CVolumeApi, CRecycleBinApi, CPsapi, CMapi32Api
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+
+// I try not to blow up such classes; they shall _only_ hide away the dynamic linking.
+
+#pragma once
+
+
+//
+// CVolumeApi. Supported with Windows 2000 or higher.
+//
+class CVolumeApi
+{
+public:
+ CVolumeApi();
+ ~CVolumeApi();
+
+ bool IsSupported();
+
+ BOOL GetVolumeNameForVolumeMountPoint(LPCTSTR lpszVolumeMountPoint, LPTSTR lpszVolumeName, DWORD cchBufferLength);
+
+ HANDLE FindFirstVolume(LPTSTR lpszVolumeName, DWORD cchBufferLength);
+ BOOL FindNextVolume(HANDLE hFindVolume, LPTSTR lpszVolumeName, DWORD cchBufferLength);
+ BOOL FindVolumeClose(HANDLE hFindVolume);
+
+ HANDLE FindFirstVolumeMountPoint(LPCTSTR lpszRootPathName, LPTSTR lpszVolumeMountPoint, DWORD cchBufferLength);
+ BOOL FindNextVolumeMountPoint(HANDLE hFindVolumeMountPoint, LPTSTR lpszVolumeMountPoint, DWORD cchBufferLength);
+ BOOL FindVolumeMountPointClose(HANDLE hFindVolumeMountPoint);
+
+
+private:
+ typedef BOOL (WINAPI *TypeGetVolumeNameForVolumeMountPoint)(LPCTSTR lpszVolumeMountPoint, LPTSTR lpszVolumeName, DWORD cchBufferLength);
+ typedef HANDLE (WINAPI *TypeFindFirstVolume)(LPTSTR lpszVolumeName, DWORD cchBufferLength);
+ typedef BOOL (WINAPI *TypeFindNextVolume)(HANDLE hFindVolume, LPTSTR lpszVolumeName, DWORD cchBufferLength);
+ typedef BOOL (WINAPI *TypeFindVolumeClose)(HANDLE hFindVolume);
+ typedef HANDLE (WINAPI *TypeFindFirstVolumeMountPoint)(LPCTSTR lpszRootPathName, LPTSTR lpszVolumeMountPoint, DWORD cchBufferLength);
+ typedef BOOL (WINAPI *TypeFindNextVolumeMountPoint)(HANDLE hFindVolumeMountPoint, LPTSTR lpszVolumeMountPoint, DWORD cchBufferLength);
+ typedef BOOL (WINAPI *TypeFindVolumeMountPointClose)(HANDLE hFindVolumeMountPoint);
+
+ HMODULE m_dll;
+ TypeGetVolumeNameForVolumeMountPoint m_GetVolumeNameForVolumeMountPoint;
+ TypeFindFirstVolume m_FindFirstVolume;
+ TypeFindNextVolume m_FindNextVolume;
+ TypeFindVolumeClose m_FindVolumeClose;
+ TypeFindFirstVolumeMountPoint m_FindFirstVolumeMountPoint;
+ TypeFindNextVolumeMountPoint m_FindNextVolumeMountPoint;
+ TypeFindVolumeMountPointClose m_FindVolumeMountPointClose;
+};
+
+
+//
+// CRecycleBinApi. Not always supported on NT and W95/98.
+//
+class CRecycleBinApi
+{
+public:
+ CRecycleBinApi();
+ ~CRecycleBinApi();
+
+ bool IsSupported();
+
+ HRESULT SHEmptyRecycleBin(HWND hwnd, LPCTSTR pszRootPath, DWORD dwFlags);
+ HRESULT SHQueryRecycleBin(LPCTSTR pszRootPath, LPSHQUERYRBINFO pSHQueryRBInfo);
+
+private:
+ typedef HRESULT (STDAPICALLTYPE *TypeSHEmptyRecycleBin)(HWND hwnd, LPCTSTR pszRootPath, DWORD dwFlags);
+ typedef HRESULT (STDAPICALLTYPE *TypeSHQueryRecycleBin)(LPCTSTR pszRootPath, LPSHQUERYRBINFO pSHQueryRBInfo);
+
+ HMODULE m_dll;
+
+ TypeSHEmptyRecycleBin m_SHEmptyRecycleBin;
+ TypeSHQueryRecycleBin m_SHQueryRecycleBin;
+};
+
+
+//
+// CPsapi. Not Supported on W95/W98/me.
+//
+class CPsapi
+{
+public:
+ CPsapi();
+ ~CPsapi();
+
+ bool IsSupported();
+
+ BOOL GetProcessMemoryInfo(HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb);
+
+private:
+ typedef BOOL (WINAPI *TypeGetProcessMemoryInfo)(HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb);
+
+ HMODULE m_dll;
+ TypeGetProcessMemoryInfo m_GetProcessMemoryInfo;
+};
+
+
+//
+// CMapi32Api. CDocument::OnFileSendMail() loads mapi32.dll dynamically.
+// So we do, too.
+//
+class CMapi32Api
+{
+public:
+ CMapi32Api();
+ ~CMapi32Api();
+
+ static bool IsDllPresent();
+ bool IsSupported();
+
+ ULONG MAPISendMail(LHANDLE lhSession, ULONG ulUIParam, lpMapiMessage lpMessage, FLAGS flFlags, ULONG ulReserved);
+
+private:
+ typedef ULONG (FAR PASCAL *TypeMAPISendMail)(LHANDLE lhSession, ULONG ulUIParam, lpMapiMessage lpMessage, FLAGS flFlags, ULONG ulReserved);
+
+ HMODULE m_dll;
+ TypeMAPISendMail m_MAPISendMail;
+};
+
diff --git a/windirstat/ownerdrawnlistcontrol.cpp b/windirstat/ownerdrawnlistcontrol.cpp
new file mode 100644
index 0000000..f149318
--- /dev/null
+++ b/windirstat/ownerdrawnlistcontrol.cpp
@@ -0,0 +1,460 @@
+// OwnerDrawnListControl.cpp - Implementation of COwnerDrawnListItem and COwnerDrawnListControl
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include ".\ownerdrawnlistcontrol.h"
+
+namespace
+{
+ const int TEXT_X_MARGIN = 6; // horizontaler Abstand der Texte vom Rand des Item-Rechtecks
+
+ const UINT LABEL_INFLATE_CX = 3;// um soviel wird das Label vergrößert, um das Selektions- und Fokus-
+ const UINT LABEL_INFLATE_CY = 1;// rechteck zu erhalten
+
+ const UINT GENERAL_INDENT = 5;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+COwnerDrawnListItem::COwnerDrawnListItem()
+{
+}
+
+COwnerDrawnListItem::~COwnerDrawnListItem()
+{
+}
+
+void COwnerDrawnListItem::DrawLabel(COwnerDrawnListControl *list, CImageList *il, CDC *pdc, CRect& rc, UINT state, int *width, bool indent) const
+{
+ CRect rcRest= rc;
+ if (indent)
+ rcRest.left+= GENERAL_INDENT;
+
+ ASSERT(GetImage() < il->GetImageCount());
+
+ IMAGEINFO ii;
+ il->GetImageInfo(GetImage(), &ii);
+ CRect rcImage(ii.rcImage);
+
+ if (width == NULL)
+ {
+ CPoint pt(rcRest.left, rcRest.top + rcRest.Height() / 2 - rcImage.Height() / 2);
+ il->Draw(pdc, GetImage(), pt, ILD_NORMAL);
+ }
+
+ rcRest.left+= rcImage.Width();
+
+ CSelectObject sofont(pdc, list->GetFont());
+
+ rcRest.DeflateRect(list->GetTextXMargin(), 0);
+
+ CRect rcLabel= rcRest;
+ pdc->DrawText(GetText(0), rcLabel, DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS | DT_CALCRECT);
+ rcLabel.top= rcRest.top + (rcRest.bottom - rcLabel.bottom);
+ rcLabel.InflateRect(LABEL_INFLATE_CX, LABEL_INFLATE_CY);
+
+ CSetBkMode bk(pdc, TRANSPARENT);
+ COLORREF textColor= RGB(0,0,0);
+ if (width == NULL && (state & ODS_SELECTED) != 0 && (GetFocus() == list->m_hWnd || (list->GetStyle() & LVS_SHOWSELALWAYS) != 0))
+ {
+ pdc->FillSolidRect(rcLabel, RGB(0,0,180));
+ textColor= GetSysColor(COLOR_WINDOW);
+ }
+ CSetTextColor stc(pdc, textColor);
+ if (width == NULL)
+ pdc->DrawText(GetText(0), rcRest, DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS);
+ else
+ pdc->DrawText(GetText(0), rcRest, DT_SINGLELINE | DT_VCENTER | DT_CALCRECT);
+
+ rcLabel.InflateRect(1, 1);
+
+ if (state & ODS_FOCUS && width == NULL)
+ pdc->DrawFocusRect(rcLabel);
+
+ if (width == NULL)
+ DrawAdditionalState(pdc, rcLabel);
+
+ rcLabel.left= rc.left;
+ rc= rcLabel;
+
+ if (width != NULL)
+ *width= rcLabel.Width() + 5; // Don't know, why +5
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_DYNAMIC(COwnerDrawnListControl, CSortingListControl)
+
+COwnerDrawnListControl::COwnerDrawnListControl(LPCTSTR name, int rowHeight)
+ : CSortingListControl(name)
+{
+ ASSERT(rowHeight > 0);
+ m_rowHeight= rowHeight;
+ m_showGrid= false;
+}
+
+COwnerDrawnListControl::~COwnerDrawnListControl()
+{
+}
+
+// This method MUST be called before the Control is shown.
+void COwnerDrawnListControl::OnColumnsInserted()
+{
+ // The pacmen shall not draw over our header control.
+ ModifyStyle(0, WS_CLIPCHILDREN);
+
+ // Where does the 1st Item begin vertically?
+ if (GetItemCount() > 0)
+ {
+ CRect rc;
+ GetItemRect(0, rc, LVIR_BOUNDS);
+ m_yFirstItem= rc.top;
+ }
+ else
+ {
+ InsertItem(0, _T("_tmp"), 0);
+ CRect rc;
+ GetItemRect(0, rc, LVIR_BOUNDS);
+ DeleteItem(0);
+ m_yFirstItem= rc.top;
+ }
+
+ LoadPersistentAttributes();
+}
+
+int COwnerDrawnListControl::GetRowHeight()
+{
+ return m_rowHeight;
+}
+
+void COwnerDrawnListControl::ShowGrid(bool show)
+{
+ m_showGrid= show;
+ if (IsWindow(m_hWnd))
+ InvalidateRect(NULL);
+}
+
+int COwnerDrawnListControl::GetTextXMargin()
+{
+ return TEXT_X_MARGIN;
+}
+
+int COwnerDrawnListControl::GetGeneralLeftIndent()
+{
+ return GENERAL_INDENT;
+}
+
+COwnerDrawnListItem *COwnerDrawnListControl::GetItem(int i)
+{
+ COwnerDrawnListItem *item= (COwnerDrawnListItem *)GetItemData(i);
+ return item;
+}
+
+int COwnerDrawnListControl::FindListItem(const COwnerDrawnListItem *item)
+{
+ LVFINDINFO fi;
+ ZeroMemory(&fi, sizeof(fi));
+ fi.flags= LVFI_PARAM;
+ fi.lParam= (LPARAM)item;
+
+ int i= FindItem(&fi);
+
+ return i;
+}
+
+void COwnerDrawnListControl::DrawItem(LPDRAWITEMSTRUCT pdis)
+{
+ COwnerDrawnListItem *item= (COwnerDrawnListItem *)(pdis->itemData);
+ CDC *pdc= CDC::FromHandle(pdis->hDC);
+ CRect rcItem(pdis->rcItem);
+ if (m_showGrid)
+ {
+ rcItem.bottom--;
+ rcItem.right--;
+ }
+
+ CDC dcmem;
+
+ dcmem.CreateCompatibleDC(pdc);
+ CBitmap bm;
+ bm.CreateCompatibleBitmap(pdc, rcItem.Width(), rcItem.Height());
+ CSelectObject sobm(&dcmem, &bm);
+
+ dcmem.FillSolidRect(rcItem - rcItem.TopLeft(), GetSysColor(COLOR_WINDOW));
+
+ for (int i=0; i < GetHeaderCtrl()->GetItemCount(); i++)
+ {
+ CRect rc= GetWholeSubitemRect(pdis->itemID, i);
+
+ CRect rcDraw= rc - rcItem.TopLeft();
+
+ if (!item->DrawSubitem(i, &dcmem, rcDraw, pdis->itemState, NULL))
+ {
+ CRect rcText= rcDraw;
+ rcText.DeflateRect(TEXT_X_MARGIN, 0);
+ CSetBkMode bk(&dcmem, TRANSPARENT);
+ CSelectObject sofont(&dcmem, GetFont());
+ CString s= item->GetText(i);
+ UINT align= IsColumnRightAligned(i) ? DT_RIGHT : DT_LEFT;
+ dcmem.DrawText(s, rcText, DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS | align);
+ // Test: dcmem.FillSolidRect(rcDraw, 0);
+ }
+
+ pdc->BitBlt(rcItem.left + rcDraw.left, rcItem.top + rcDraw.top, rcDraw.Width(), rcDraw.Height(), &dcmem, rcDraw.left, rcDraw.top, SRCCOPY);
+ }
+}
+
+bool COwnerDrawnListControl::IsColumnRightAligned(int col)
+{
+ HDITEM hditem;
+ ZeroMemory(&hditem, sizeof(hditem));
+ hditem.mask= HDI_FORMAT;
+
+ GetHeaderCtrl()->GetItem(col, &hditem);
+
+ return (hditem.fmt & HDF_RIGHT) != 0;
+}
+
+CRect COwnerDrawnListControl::GetWholeSubitemRect(int item, int subitem)
+{
+ CRect rc;
+ if (subitem == 0)
+ {
+ // Special case column 0:
+ // If we did GetSubItemRect(item 0, LVIR_LABEL, rc)
+ // and we have an image list, then we would get the rectangle
+ // excluding the image.
+ HDITEM hditem;
+ hditem.mask= HDI_WIDTH;
+ GetHeaderCtrl()->GetItem(0, &hditem);
+
+ VERIFY(GetItemRect(item, rc, LVIR_LABEL));
+ rc.left= rc.right - hditem.cxy;
+ }
+ else
+ {
+ VERIFY(GetSubItemRect(item, subitem, LVIR_LABEL, rc));
+ }
+
+ if (m_showGrid)
+ {
+ rc.right--;
+ rc.bottom--;
+ }
+ return rc;
+}
+
+int COwnerDrawnListControl::GetSubItemWidth(COwnerDrawnListItem *item, int subitem)
+{
+ int width;
+
+ CClientDC dc(this);
+ CRect rc(0, 0, 1000, 1000);
+
+ if (item->DrawSubitem(subitem, &dc, rc, 0, &width))
+ return width;
+
+ CString s= item->GetText(subitem);
+ if (s.IsEmpty())
+ {
+ // DrawText(..DT_CALCRECT) scheint mit Leerstrings nicht klarzukommen
+ return 0;
+ }
+
+ CSelectObject sofont(&dc, GetFont());
+ UINT align= IsColumnRightAligned(subitem) ? DT_RIGHT : DT_LEFT;
+ dc.DrawText(s, rc, DT_SINGLELINE | DT_VCENTER | align | DT_CALCRECT);
+
+ rc.InflateRect(TEXT_X_MARGIN, 0);
+ return rc.Width();
+}
+
+
+BEGIN_MESSAGE_MAP(COwnerDrawnListControl, CSortingListControl)
+ ON_WM_ERASEBKGND()
+ ON_NOTIFY(HDN_DIVIDERDBLCLICKA, 0, OnHdnDividerdblclick)
+ ON_NOTIFY(HDN_DIVIDERDBLCLICKW, 0, OnHdnDividerdblclick)
+ ON_WM_VSCROLL()
+ ON_NOTIFY(HDN_ITEMCHANGINGA, 0, OnHdnItemchanging)
+ ON_NOTIFY(HDN_ITEMCHANGINGW, 0, OnHdnItemchanging)
+ ON_WM_SHOWWINDOW()
+END_MESSAGE_MAP()
+
+BOOL COwnerDrawnListControl::OnEraseBkgnd(CDC* pDC)
+{
+ ASSERT(GetHeaderCtrl()->GetItemCount() > 0);
+
+ // We should recalculate m_yFirstItem here (could have changed e.g. when
+ // the XP-Theme changed).
+ if (GetItemCount() > 0)
+ {
+ CRect rc;
+ GetItemRect(0, rc, LVIR_BOUNDS);
+ m_yFirstItem= rc.top;
+ }
+ // else: if we did the same thing as in OnColumnsCreated(), we get
+ // repaint problems.
+
+ const COLORREF gridColor= RGB(212,208,200);
+
+ CRect rcClient;
+ GetClientRect(rcClient);
+
+ CRect rcHeader;
+ GetHeaderCtrl()->GetWindowRect(rcHeader);
+ ScreenToClient(rcHeader);
+
+ CRect rcBetween= rcClient; // between header and first item
+ rcBetween.top= rcHeader.bottom;
+ rcBetween.bottom= m_yFirstItem;
+ pDC->FillSolidRect(rcBetween, gridColor);
+
+ CArray<int, int> columnOrder;
+ columnOrder.SetSize(GetHeaderCtrl()->GetItemCount());
+ GetColumnOrderArray(columnOrder.GetData(), columnOrder.GetSize());
+
+ CArray<int, int> vertical;
+ vertical.SetSize(GetHeaderCtrl()->GetItemCount());
+
+ int x= - GetScrollPos(SB_HORZ);
+ HDITEM hdi;
+ ZeroMemory(&hdi, sizeof(hdi));
+ hdi.mask= HDI_WIDTH;
+ for (int i=0; i < GetHeaderCtrl()->GetItemCount(); i++)
+ {
+ GetHeaderCtrl()->GetItem(columnOrder[i], &hdi);
+ x+= hdi.cxy;
+ vertical[i]= x;
+ }
+
+ if (m_showGrid)
+ {
+ CPen pen(PS_SOLID, 1, gridColor);
+ CSelectObject sopen(pDC, &pen);
+
+ for (int y=m_yFirstItem + GetRowHeight() - 1; y < rcClient.bottom; y+= GetRowHeight())
+ {
+ pDC->MoveTo(rcClient.left, y);
+ pDC->LineTo(rcClient.right, y);
+ }
+
+ for (int i=0; i < vertical.GetSize(); i++)
+ {
+ pDC->MoveTo(vertical[i] - 1, rcClient.top);
+ pDC->LineTo(vertical[i] - 1, rcClient.bottom);
+ }
+ }
+
+ const int gridWidth= m_showGrid ? 1 : 0;
+ const COLORREF bgcolor= GetSysColor(COLOR_WINDOW);
+
+ const int lineCount= GetCountPerPage() + 1;
+ const int firstItem= GetTopIndex();
+ const int lastItem= min(firstItem + lineCount, GetItemCount()) - 1;
+
+ ASSERT(GetItemCount() == 0 || firstItem < GetItemCount());
+ ASSERT(GetItemCount() == 0 || lastItem < GetItemCount());
+ ASSERT(GetItemCount() == 0 || lastItem >= firstItem);
+
+ const int itemCount= lastItem - firstItem + 1;
+
+ CRect fill;
+ fill.left= vertical[vertical.GetSize() - 1];
+ fill.right= rcClient.right;
+ fill.top= m_yFirstItem;
+ fill.bottom= fill.top + GetRowHeight() - gridWidth;
+ for (i=0; i < itemCount; i++)
+ {
+ pDC->FillSolidRect(fill, bgcolor);
+ fill.OffsetRect(0, GetRowHeight());
+ }
+
+ int top= fill.top;
+ while (top < rcClient.bottom)
+ {
+ fill.top= top;
+ fill.bottom= top + GetRowHeight() - gridWidth;
+
+ int left= 0;
+ for (int i=0; i < vertical.GetSize(); i++)
+ {
+ fill.left= left;
+ fill.right= vertical[i] - gridWidth;
+
+ pDC->FillSolidRect(fill, bgcolor);
+
+ left= vertical[i];
+ }
+ fill.left= left;
+ fill.right= rcClient.right;
+ pDC->FillSolidRect(fill, bgcolor);
+
+ top+= GetRowHeight();
+ }
+ return true;
+}
+
+void COwnerDrawnListControl::OnHdnDividerdblclick(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ CWaitCursor wc;
+ LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
+
+ int subitem= phdr->iItem;
+
+ AdjustColumnWidth(subitem);
+
+ *pResult = 0;
+}
+
+void COwnerDrawnListControl::AdjustColumnWidth(int col)
+{
+ CWaitCursor wc;
+
+ int width= 10;
+ for (int i=0; i < GetItemCount(); i++)
+ {
+ int w= GetSubItemWidth(GetItem(i), col);
+ if (w > width)
+ width= w;
+ }
+ SetColumnWidth(col, width + 5);
+}
+
+void COwnerDrawnListControl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
+
+ // Owner drawn list controls with LVS_EX_GRIDLINES don't repaint correctly
+ // when scrolled (under Windows XP). So we fource a complete repaint here.
+ InvalidateRect(NULL);
+}
+
+void COwnerDrawnListControl::OnHdnItemchanging(NMHDR * /*pNMHDR*/, LRESULT *pResult)
+{
+ // Unused: LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
+ Default();
+ InvalidateRect(NULL);
+
+ *pResult = 0;
+}
+
diff --git a/windirstat/ownerdrawnlistcontrol.h b/windirstat/ownerdrawnlistcontrol.h
new file mode 100644
index 0000000..09b3387
--- /dev/null
+++ b/windirstat/ownerdrawnlistcontrol.h
@@ -0,0 +1,88 @@
+// ownerdrawnlistcontrol.h - Declaration of COwnerDrawnListControl and COwnerDrawnListItem
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "sortinglistcontrol.h"
+
+class COwnerDrawnListItem;
+class COwnerDrawnListControl;
+
+
+//
+// COwnerDrawnListItem. An item in a COwnerDrawnListControl.
+// Some columns (subitems) may be owner drawn (DrawSubitem() returns true),
+// COwnerDrawnListControl draws the texts (GetText()) of all others.
+// DrawLabel() draws a standard label (width image, text, seletion and focus rect)
+//
+class COwnerDrawnListItem: public CSortingListItem
+{
+public:
+ COwnerDrawnListItem();
+ virtual ~COwnerDrawnListItem();
+
+ virtual CString GetText(int subitem) const =0;
+ virtual bool DrawSubitem(int subitem, CDC *pdc, CRect rc, UINT state, int *width) const =0;
+ virtual void DrawAdditionalState(CDC * /*pdc*/, const CRect& /*rcLabel*/) const {}
+
+protected:
+ void DrawLabel(COwnerDrawnListControl *list, CImageList *il, CDC *pdc, CRect& rc, UINT state, int *width, bool indent = true) const;
+};
+
+
+//
+// COwnerDrawnListControl. Must be report view. Deals with COwnerDrawnListItems.
+// Can have a grid or not (own implementation, don't set LVS_EX_GRIDLINES). Flicker-free.
+//
+class COwnerDrawnListControl: public CSortingListControl
+{
+ DECLARE_DYNAMIC(COwnerDrawnListControl)
+public:
+ COwnerDrawnListControl(LPCTSTR name, int rowHeight);
+ virtual ~COwnerDrawnListControl();
+ void OnColumnsInserted();
+
+ int GetRowHeight();
+ void ShowGrid(bool show);
+
+ COwnerDrawnListItem *GetItem(int i);
+ int FindListItem(const COwnerDrawnListItem *item);
+ int GetTextXMargin();
+ int GetGeneralLeftIndent();
+ void AdjustColumnWidth(int col);
+ CRect GetWholeSubitemRect(int item, int subitem);
+
+protected:
+ virtual void DrawItem(LPDRAWITEMSTRUCT pdis);
+ int GetSubItemWidth(COwnerDrawnListItem *item, int subitem);
+ bool IsColumnRightAligned(int col);
+
+ int m_rowHeight; // Height of an item
+ bool m_showGrid; // Whether to draw a grid
+ int m_yFirstItem; // Top of a first list item
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg void OnHdnDividerdblclick(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnHdnItemchanging(NMHDR *pNMHDR, LRESULT *pResult);
+};
+
diff --git a/windirstat/pacman.cpp b/windirstat/pacman.cpp
new file mode 100644
index 0000000..5b757b2
--- /dev/null
+++ b/windirstat/pacman.cpp
@@ -0,0 +1,194 @@
+// pacman.cpp - Implementation of CPacman
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "pacman.h"
+
+namespace
+{
+ DWORD UPDATEINTERVAL = 40; // ms
+ double MOUTHSPEED = 0.0025; // aperture alteration / ms
+}
+
+CPacman::CPacman()
+{
+ m_bgcolor= GetSysColor(COLOR_WINDOW);
+ m_readJobs= 0;
+ m_speed= 0.0005;
+ m_moving= false;
+ m_lastUpdate= 0;
+ Reset();
+}
+
+void CPacman::Reset()
+{
+ m_toTheRight= true;
+ m_position= 0;
+ m_mouthOpening= true;
+ m_aperture= 0;
+}
+
+void CPacman::SetBackgroundColor(COLORREF color)
+{
+ m_bgcolor= color;
+}
+
+void CPacman::SetSpeed(double speed)
+{
+ m_speed= speed;
+}
+
+void CPacman::Start(bool start)
+{
+ m_moving= start;
+ m_lastUpdate= GetTickCount();
+}
+
+bool CPacman::Drive(LONGLONG readJobs)
+{
+ m_readJobs= (double)readJobs;
+
+ if (!m_moving)
+ return false;
+
+ DWORD now= GetTickCount();
+ DWORD delta= now - m_lastUpdate;
+
+ if (delta < UPDATEINTERVAL)
+ return false;
+
+ m_lastUpdate= now;
+
+ UpdatePosition(m_position, m_toTheRight, m_speed * delta);
+ UpdatePosition(m_aperture, m_mouthOpening, MOUTHSPEED * delta);
+
+ return true;
+}
+
+void CPacman::Draw(CDC *pdc, const CRect& rect)
+{
+ pdc->FillSolidRect(rect, m_bgcolor);
+
+ CRect rc= rect;
+ rc.DeflateRect(5, 1);
+
+ if (rc.Height() % 2 == 0)
+ rc.bottom--;
+
+ int diameter= rc.Height();
+
+ int left= rc.left + (int)(m_position * (rc.Width() - diameter));
+ rc.left= left;
+ rc.right= left + diameter;
+
+ CPen pen(PS_SOLID, 1, RGB(0,0,0));
+ CSelectObject sopen(pdc, &pen);
+
+ CBrush brush(CalculateColor());
+ CSelectObject sobrush(pdc, &brush);
+
+ CPoint ptStart;
+ CPoint ptEnd;
+ int hmiddle= rc.top + diameter / 2;
+
+ int mouthcy= (int)(m_aperture * m_aperture * diameter);
+ if (m_toTheRight)
+ {
+ ptStart.x= ptEnd.x= rc.right;
+ ptStart.y = hmiddle - mouthcy;
+ ptEnd.y = hmiddle + mouthcy;
+ }
+ else
+ {
+ ptStart.x= ptEnd.x= rc.left;
+ ptStart.y = hmiddle + mouthcy;
+ ptEnd.y = hmiddle - mouthcy;
+ }
+
+ pdc->Pie(rc, ptStart, ptEnd);
+}
+
+
+void CPacman::UpdatePosition(double& position, bool& up, double diff)
+{
+ ASSERT(diff >= 0.0);
+ ASSERT(position >= 0.0);
+ ASSERT(position <= 1.0);
+
+ while (diff > 0.0)
+ {
+ if (up)
+ {
+ if (position + diff > 1.0)
+ {
+ diff= position + diff - 1.0;
+ position= 1.0;
+ up= false;
+ }
+ else
+ {
+ position+= diff;
+ diff= 0;
+ }
+ }
+ else
+ {
+ if (position - diff < 0.0)
+ {
+ diff= - (position - diff);
+ position= 0.0;
+ up= true;
+ }
+ else
+ {
+ position-= diff;
+ diff= 0;
+ }
+ }
+ }
+}
+
+COLORREF CPacman::CalculateColor()
+{
+ static const double pi2 = (3.1415926535897932384626433832795 / 2);
+
+ ASSERT(m_readJobs >= 0);
+ double a= atan(m_readJobs / 18) / pi2;
+ ASSERT(a >= 0.0);
+ ASSERT(a <= 1.0);
+
+/*
+ // a == 1 --> yellow
+ // a == 0 --> green
+
+ int red= (int)(a * 255);
+
+ return RGB(red, 255, 0);
+*/
+ // a == 1 --> yellow
+ // a == 0 --> bgcolor
+
+ int red = (int)(a * 255 + (1 - a) * GetRValue(m_bgcolor));
+ int green = (int)(a * 255 + (1 - a) * GetGValue(m_bgcolor));
+ int blue = (int)( (1 - a) * GetBValue(m_bgcolor));
+
+ return RGB(red, green, blue);
+}
diff --git a/windirstat/pacman.h b/windirstat/pacman.h
new file mode 100644
index 0000000..e365ffb
--- /dev/null
+++ b/windirstat/pacman.h
@@ -0,0 +1,51 @@
+// pacman.h - Declaration of CPacman
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+//
+// CPacman. Pacman animation.
+//
+class CPacman
+{
+public:
+ CPacman();
+ void SetBackgroundColor(COLORREF color);
+ void SetSpeed(double speed);
+ void Reset();
+ void Start(bool start);
+ bool Drive(LONGLONG readJobs); // return: true -> should be redrawn.
+ void Draw(CDC *pdc, const CRect& rc);
+
+private:
+ void UpdatePosition(double& position, bool& up, double diff);
+ COLORREF CalculateColor();
+
+ COLORREF m_bgcolor; // Background color
+ double m_speed; // Speed in full width / ms
+ bool m_moving; // Whether pacman is moving
+ double m_readJobs; // # of read jobs determines our color
+ bool m_toTheRight; // moving right
+ double m_position; // 0...1
+ bool m_mouthOpening; // Mouth is opening
+ double m_aperture; // 0...1
+ DWORD m_lastUpdate; // TickCount
+};
diff --git a/windirstat/res/Toolbar.bmp b/windirstat/res/Toolbar.bmp
new file mode 100644
index 0000000..b05920f
--- /dev/null
+++ b/windirstat/res/Toolbar.bmp
Binary files differ
diff --git a/windirstat/res/bitmap1.bmp b/windirstat/res/bitmap1.bmp
new file mode 100644
index 0000000..4f8b0bd
--- /dev/null
+++ b/windirstat/res/bitmap1.bmp
Binary files differ
diff --git a/windirstat/res/icon1.ico b/windirstat/res/icon1.ico
new file mode 100644
index 0000000..e645c24
--- /dev/null
+++ b/windirstat/res/icon1.ico
Binary files differ
diff --git a/windirstat/res/license.txt b/windirstat/res/license.txt
new file mode 100644
index 0000000..651a1f0
--- /dev/null
+++ b/windirstat/res/license.txt
@@ -0,0 +1,345 @@
+
+This program is distributed under the terms of the GPL v2.
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
diff --git a/windirstat/res/windirstat.manifest b/windirstat/res/windirstat.manifest
new file mode 100644
index 0000000..153d531
--- /dev/null
+++ b/windirstat/res/windirstat.manifest
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="X86"
+ name="Microsoft.Windows.windirstat"
+ type="win32"
+/>
+<description>WinDirStat - Windows Directory Statistics</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+</assembly>
diff --git a/windirstat/resource.h b/windirstat/resource.h
new file mode 100644
index 0000000..900bc44
--- /dev/null
+++ b/windirstat/resource.h
@@ -0,0 +1,243 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by windirstat.rc
+//
+#define IDD_ABOUTBOX 100
+#define ID_VIEW_ARRANGE 127
+#define IDR_MAINFRAME 128
+#define IDR_windirstatTYPE 129
+#define IDR_11 130
+#define IDB_NODES 131
+#define IDD_SELECTDRIVES 133
+#define IDR_POPUPLIST 134
+#define IDB_IMAGELIST 135
+#define IDR_POPUPGRAPH 136
+#define IDR_LICENSE 137
+#define IDD_DELETE_WARNING 138
+#define IDD_INVISIBLE 140
+#define IDD_MODALSHELLAPI 140
+#define IDD_MODALAPISHUTTLE 140
+#define IDD_PAGE_CLEANUPS 141
+#define IDD_PAGE_TREELIST 142
+#define IDD_PAGE_TREEMAP 143
+#define IDD_PAGE_GENERAL 144
+#define IDD_REPORTBUG 145
+#define IDS_RESOURCEVERSION 199
+#define IDS_ABOUT_ABOUTTEXTss 200
+#define IDS_ABOUT_THANKSTOTEXT 201
+#define IDS_ABOUT_ABOUT 202
+#define IDS_ABOUT_THANKSTO 203
+#define IDS_ABOUT_LICENSEAGREEMENT 204
+#define IDS_MYCOMPUTER 205
+#define IDS_UDC_CONFIRMATIONss 206
+#define IDS_RUDC_CONFIRMATIONss 207
+#define IDS_THEDIRECTORYsDOESNOTEXIST 208
+#define IDS_THEFILEsDOESNOTEXIST 209
+#define IDS_COULDNOTCREATEPROCESSssss 210
+#define IDS_TREECOL_NAME 211
+#define IDS_TREECOL_SUBTREEPERCENTAGE 212
+#define IDS_TREECOL_PERCENTAGE 213
+#define IDS_TREECOL_SIZE 214
+#define IDS_TREECOL_ITEMS 215
+#define IDS_TREECOL_FILES 216
+#define IDS_TREECOL_SUBDIRS 217
+#define IDS_TREECOL_LASTCHANGE 218
+#define IDS_PLEASECHECKYOURDISKUSAGE 219
+#define IDS_DISKUSAGEREPORTGENERATEDBYWINDIRSTAT 220
+#define IDS__UNKNOWN_ 221
+#define IDS_FREESPACE_ITEM 222
+#define IDS_UNKNOWN_ITEM 223
+#define IDS_FILES_ITEM 224
+#define IDS_ONEREADJOB 225
+#define IDS_sREADJOBS 226
+#define IDS_CANNOTOPENCLIPBOARD 227
+#define IDS_CANNOTEMTPYCLIPBOARD 228
+#define IDS_CANNOTSETCLIPBAORDDATA 229
+#define IDS_WINDIRSTAT_SETTINGS 230
+#define IDS_SCANNING_ 231
+#define IDS_EMPTYRECYCLEBIN 232
+#define IDS__ONEITEMss 233
+#define IDS__sITEMSss 234
+#define IDS_UDCsCTRLd 235
+#define IDS_USERDEFINEDCLEANUP0 236
+#define IDS_REPORT_DISKUSAGE 237
+#define IDS_USERDEFINEDCLEANUPd 238
+#define IDS_POLICY_NOREFRESH 239
+#define IDS_POLICY_REFRESHTHISENTRY 240
+#define IDS_POLICY_REFRESHPARENT 241
+#define IDS_BUGREPORTHINT 242
+#define IDS_FEEDBACKHINT 243
+#define IDS_FROMsPLATFORMs 244
+#define IDS_SEV_CRITICAL 245
+#define IDS_SEV_GRAVE 246
+#define IDS_SEV_NORMAL 247
+#define IDS_SEV_WISH 248
+#define IDS_SEV_FEEDBACK 249
+#define IDS_DRIVECOL_NAME 250
+#define IDS_DRIVECOL_TOTAL 251
+#define IDS_DRIVECOL_FREE 252
+#define IDS_DRIVECOL_GRAPH 253
+#define IDS_DRIVECOL_PERCENTUSED 254
+#define IDS_SELECTFOLDER 255
+#define IDS_EXTCOL_EXTENSION 256
+#define IDS_EXTCOL_COLOR 257
+#define IDS_EXTCOL_BYTES 258
+#define IDS_EXTCOL_FILES 259
+#define IDS_EXTCOL_DESCRIPTION 260
+#define IDS_RAMUSAGEs 261
+#define IDS_HELPFILEsCOULDNOTBEFOUND 262
+#define IDS_SUSPENDED_ 263
+#define IDS_SUSPEND 264
+#define IDC_ALLDRIVES 1000
+#define IDC_GROUPS 1000
+#define IDC_ALLLOCALDRIVES 1000
+#define IDC_SOMEDRIVES 1001
+#define IDC_EXTENSIONS 1001
+#define IDC_AFOLDER 1002
+#define IDC_MEMBERS 1002
+#define IDC_FOLDERNAME 1003
+#define IDC_BROWSEFOLDER 1004
+#define IDC_DRIVES 1005
+#define IDC_TEXT 1012
+#define IDC_TAB 1013
+#define IDC_CAPTION 1014
+#define IDC_FILENAME 1016
+#define IDC_DONTSHOWAGAIN 1017
+#define IDC_CHECK1 1020
+#define IDC_FOLLOWMOUNTPOINTS 1020
+#define IDC_CHECK2 1021
+#define IDC_PACMANANIMATION 1021
+#define IDC_TREEMAPGRID 1022
+#define IDC_ASKFORCONFIRMATION 1022
+#define IDC_SHOWCONSOLEWINDOW 1023
+#define IDC_WAITFORCOMPLETION 1024
+#define IDC_HEIGHTFACTORSPIN 1026
+#define IDC_HEIGHTFACTOR 1027
+#define IDC_TREELISTGRID 1028
+#define IDC_SCALEFACTOR 1028
+#define IDC_HUMANFORMAT 1029
+#define IDC_SCALEFACTORSPIN 1029
+#define IDC_TREEMAPGRIDCOLOR 1030
+#define IDC_CUSHIONSHADING 1031
+#define IDC_AMBIENTLIGHT 1032
+#define IDC_AMBIENTLIGHTSPIN 1033
+#define IDC_RESETTODEFAULTS 1034
+#define IDC_DEMO 1035
+#define IDC_LIST 1036
+#define IDC_TITLE 1037
+#define IDC_COMMANDLINE 1038
+#define IDC_WORKSFORFILES 1039
+#define IDC_WORKSFORDIRECTORIES 1040
+#define IDC_WORKSFORFILESFOLDER 1041
+#define IDC_WORKSFORDRIVES 1042
+#define IDC_REFRESHPOLICY 1043
+#define IDC_HELPBUTTON 1044
+#define IDC_ENABLED 1045
+#define IDC_RECURSEINTOSUBDIRECTORIES 1046
+#define IDC_HINTSP 1047
+#define IDC_HINTSN 1048
+#define IDC_UP 1049
+#define IDC_DOWN 1050
+#define IDC_FROM 1050
+#define IDC_TO 1051
+#define IDC_CRITICAL 1052
+#define IDC_GRAVE 1053
+#define IDC_NORMAL 1054
+#define IDC_WISH 1055
+#define IDC_INAWORD 1056
+#define IDC_APPLICATION 1057
+#define IDC_FEEDBACK 1058
+#define IDC_PLATFORM 1059
+#define IDC_HINT 1060
+#define IDC_COLORBUTTON0 1100
+#define IDC_COLORBUTTON1 1101
+#define IDC_COLORBUTTON2 1102
+#define IDC_COLORBUTTON3 1103
+#define IDC_COLORBUTTON4 1104
+#define IDC_COLORBUTTON5 1105
+#define IDC_COLORBUTTON6 1106
+#define IDC_COLORBUTTON7 1107
+#define IDC_SLIDER1 1200
+#define IDC_SLIDER 1200
+#define IDC_BUTTON8 1201
+#define IDC_TREEMAPHIGHLIGHTCOLOR 1202
+#define IDC_COMBO1 1203
+#define IDC_COMBO 1203
+#define IDC_STATIC_TO 1204
+#define IDC_STATIC_PLATFORM 1205
+#define IDC_STATIC_SEVERITY 1206
+#define IDC_STATIC_OKHINT 1207
+#define ID_FILE_OPENURL 32771
+#define ID_FILE_OPENRECENT 32772
+#define ID_FILE_REFRESHALL 32773
+#define ID_CLEANUP_OPENINEXPLORER 32774
+#define ID_CLEANUP_COMPRESS 32776
+#define ID_CLEANUP_DELETETRASHFILES 32777
+#define ID_Menu 32781
+#define ID_TREEMAP_ZOOMIN 32783
+#define ID_TREEMAP_ZOOMOUT 32784
+#define ID_TREEMAP_SELECTPARENT 32785
+#define ID_TREEMAP_REBUILDTREEMAP 32786
+#define ID_TREEMAP_HELPABOUTTREEMAPS 32787
+#define ID_REPORT_SENDMAILTOOWNER 32788
+#define ID_SETTINGS_SHOWTREEMAP 32789
+#define ID_SETTINGS_SHOWTOOLBAR 32790
+#define ID_SETTINGS_SHOW 32791
+#define ID_VIEW_SHOWTREEMAP 32792
+#define ID_SETTINGS_CONFIGUREWINDIRSTAT 32793
+#define ID_HELP_REPORTBUG 32796
+#define ID_HELP_SENDFEEDBACKMAIL 32797
+#define ID_FILE_REFRESHSELECTED 32801
+#define ID_FILE_CONTINUEREADINGATMOUNTPOINT 32802
+#define ID_CLEANUP_MAKECLEAN 32803
+#define ID_FILE_OPENRECENT_0 32806
+#define ID_FILE_OPENRECENT_1 32807
+#define ID_CLEANUP_OPENINCONSOLE 32808
+#define ID_CLEANUP_DELETETOTRASHBIN 32809
+#define ID_CLEANUP_DELETE 32810
+#define ID_CONFIGURE 32813
+#define ID_HELP_MANUAL 32814
+#define ID_HELP_WHATSTHIS 32815
+#define ID_REFRESHALL 32816
+#define ID_REFRESHSELECTED 32817
+#define ID_CLEANUP_EMPTYRECYCLEBIN 32818
+#define ID_VIEW_SHOWFREESPACE 32819
+#define ID_VIEW_SHOWUNKNOWN 32820
+#define ID_POPUP 32826
+#define ID_Menu32827 32827
+#define ID_Menu32828 32828
+#define ID_Menu32829 32829
+#define ID_BUTTON32835 32835
+#define ID_BUTTON32837 32837
+#define ID_VIEW_SHOWFILETYPES 32846
+#define ID_SENDMAILTOOWNER 32856
+#define ID_USERDEFINEDCLEANUP0 32900
+#define ID_USERDEFINEDCLEANUP1 32901
+#define ID_USERDEFINEDCLEANUP2 32902
+#define ID_USERDEFINEDCLEANUP3 32903
+#define ID_USERDEFINEDCLEANUP4 32904
+#define ID_USERDEFINEDCLEANUP5 32905
+#define ID_USERDEFINEDCLEANUP6 32906
+#define ID_USERDEFINEDCLEANUP7 32907
+#define ID_USERDEFINEDCLEANUP8 32908
+#define ID_USERDEFINEDCLEANUP9 32909
+#define ID_DUMMY_USERDEFINEDCLEANUP 33005
+#define ID_POPUP_CANCEL 33008
+#define ID_TREEMAP_RESELECTCHILD 33011
+#define ID_Menu33012 33012
+#define ID_Menu33013 33013
+#define ID_CLEANUP_OPEN 33015
+#define ID_CLEANUP_PROPERTIES 33019
+#define ID_BUTTON33021 33021
+#define ID_INDICATOR_MEMORYUSAGE 59142
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 900
+#define _APS_NEXT_COMMAND_VALUE 33022
+#define _APS_NEXT_CONTROL_VALUE 1208
+#define _APS_NEXT_SYMED_VALUE 104
+#endif
+#endif
diff --git a/windirstat/selectobject.h b/windirstat/selectobject.h
new file mode 100644
index 0000000..a017280
--- /dev/null
+++ b/windirstat/selectobject.h
@@ -0,0 +1,116 @@
+// selectobject.h - Declaration and implementation of Device Context helper classes.
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+
+// Example:
+// Instead of writing
+// CGdiObject *old= pdc->SelectObject(&brush); ...; pdc->SelectObject(old);
+// we can simply write
+// CSelectObject sobrush(pdc, &brush);
+// and the destructor will reselect the old object.
+
+#pragma once
+
+
+class CSelectObject
+{
+public:
+ CSelectObject(CDC *pdc, CGdiObject *pObject)
+ { m_pOldObject= pdc->SelectObject(pObject); m_pdc= pdc; }
+ ~CSelectObject()
+ { m_pdc->SelectObject(m_pOldObject); }
+protected:
+ CDC *m_pdc;
+ CGdiObject *m_pOldObject;
+};
+
+class CSelectStockObject
+{
+public:
+ CSelectStockObject(CDC *pdc, int nIndex)
+ { m_pOldObject= pdc->SelectStockObject(nIndex); m_pdc= pdc; }
+ ~CSelectStockObject()
+ { m_pdc->SelectObject(m_pOldObject); }
+protected:
+ CDC *m_pdc;
+ CGdiObject *m_pOldObject;
+};
+
+class CSetBkMode
+{
+public:
+ CSetBkMode(CDC *pdc, int mode)
+ { m_pdc= pdc; m_oldMode= pdc->SetBkMode(mode); }
+ ~CSetBkMode()
+ { m_pdc->SetBkMode(m_oldMode); }
+protected:
+ CDC *m_pdc;
+ int m_oldMode;
+};
+
+class CSetTextColor
+{
+public:
+ CSetTextColor(CDC *pdc, COLORREF color)
+ { m_pdc= pdc; m_oldColor= pdc->SetTextColor(color); }
+ ~CSetTextColor()
+ { m_pdc->SetTextColor(m_oldColor); }
+protected:
+ CDC *m_pdc;
+ COLORREF m_oldColor;
+};
+
+class CSetBkColor
+{
+public:
+ CSetBkColor(CDC *pdc, COLORREF color)
+ { m_pdc= pdc; m_oldColor= pdc->SetBkColor(color); }
+ ~CSetBkColor()
+ { m_pdc->SetBkColor(m_oldColor); }
+protected:
+ CDC *m_pdc;
+ COLORREF m_oldColor;
+};
+
+class CSaveDC
+{
+public:
+ CSaveDC(CDC *pdc) { m_pdc= pdc; m_save= pdc->SaveDC(); }
+ ~CSaveDC() { m_pdc->RestoreDC(m_save); }
+protected:
+ CDC *m_pdc;
+ int m_save;
+};
+
+inline BOOL CreateRectRgn(CRgn& rgn, CRect rc)
+{
+ return rgn.CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
+}
+
+inline COLORREF MakeShadowColor(COLORREF c, int percent)
+{
+ return RGB(
+ GetRValue(c) * percent / 100,
+ GetGValue(c) * percent / 100,
+ GetBValue(c) * percent / 100
+ );
+}
+
diff --git a/windirstat/set.h b/windirstat/set.h
new file mode 100644
index 0000000..4bd1504
--- /dev/null
+++ b/windirstat/set.h
@@ -0,0 +1,56 @@
+// set.h - Declaration and implementatino of CSet<>
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+
+//
+// CSet. A set class. I simply use the CMap class, which is in fact
+// a set of assocs (x->y) and ignore the ys.
+//
+template<class KEY, class ARG_KEY>
+class CSet
+{
+public:
+ CSet(int nBlockSize = 10): m_map(nBlockSize) { }
+ ~CSet() { }
+ void Serialize(CArchive& ar) { m_map.Serialize(ar); }
+
+ int GetCount() const { return m_map.GetCount(); }
+ BOOL IsEmpty() const { return m_map.IsEmpty(); }
+ BOOL Lookup(ARG_KEY key) const { int dummy; return m_map.Lookup(key, dummy); }
+ void SetKey(ARG_KEY key) { m_map.SetAt(key, 0); }
+ BOOL RemoveKey(ARG_KEY key) { return m_map.RemoveKey(key); }
+ void RemoveAll() { m_map.RemoveAll(); }
+ POSITION GetStartPosition() const { return m_map.GetStartPosition(); }
+ void GetNextAssoc(POSITION& rNextPosition, KEY& rKey) const { int dummy; m_map.GetNextAssoc(rNextPosition, rKey, dummy); }
+ UINT GetHashTableSize() const { return m_map.GetHashTableSize(); }
+ void InitHashTable(UINT hashSize, BOOL bAllocNow = TRUE) { m_map.InitHashTable(hashSize, bAllocNow); }
+
+protected:
+ CMap<KEY, ARG_KEY, int, int> m_map;
+
+public:
+#ifdef _DEBUG
+ void Dump(CDumpContext& dc) const { m_map.Dump(dc); }
+ void AssertValid() const { m_map.AssertValid(); }
+#endif
+};
diff --git a/windirstat/sortinglistcontrol.cpp b/windirstat/sortinglistcontrol.cpp
new file mode 100644
index 0000000..c6ecf80
--- /dev/null
+++ b/windirstat/sortinglistcontrol.cpp
@@ -0,0 +1,283 @@
+// sortinglistcontrol.cpp - Implementation of CSortingListItem and CSortingListControl
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include ".\sortinglistcontrol.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+CString CSortingListItem::GetText(int subitem) const
+{
+ // Dummy implementation
+ CString s;
+ s.Format(_T("subitem %d"), subitem);
+ return s;
+}
+
+int CSortingListItem::GetImage() const
+{
+ // Dummy implementation
+ return 0;
+}
+
+int CSortingListItem::Compare(const CSortingListItem *other, int subitem) const
+{
+ // Default implementation compares strings
+ return GetText(subitem).CompareNoCase(other->GetText(subitem));
+}
+
+int CSortingListItem::CompareS(const CSortingListItem *other, const SSorting& sorting) const
+{
+ int r= Compare(other, sorting.column1);
+ if (abs(r) < 2 && !sorting.ascending1)
+ r= -r;
+
+ if (r == 0 && sorting.column2 != sorting.column1)
+ {
+ r= Compare(other, sorting.column2);
+ if (abs(r) < 2 && !sorting.ascending2)
+ r= -r;
+ }
+ return r;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_DYNAMIC(CSortingListControl, CListCtrl)
+
+CSortingListControl::CSortingListControl(LPCTSTR name)
+{
+ m_name= name;
+ m_indicatedColumn= -1;
+}
+
+CSortingListControl::~CSortingListControl()
+{
+}
+
+void CSortingListControl::LoadPersistentAttributes()
+{
+ CArray<int, int> arr;
+ arr.SetSize(GetHeaderCtrl()->GetItemCount());
+
+ GetColumnOrderArray(arr.GetData(), arr.GetSize());
+ CPersistence::GetColumnOrder(m_name, arr);
+ SetColumnOrderArray(arr.GetSize(), arr.GetData());
+
+ for (int i=0; i < arr.GetSize(); i++)
+ arr[i]= GetColumnWidth(i);
+ CPersistence::GetColumnWidths(m_name, arr);
+ for (i=0; i < arr.GetSize(); i++)
+ {
+ // To avoid "insane" settings we set the column width to
+ // maximal twice the default width.
+ int maxWidth= GetColumnWidth(i) * 2;
+ int w= min(arr[i], maxWidth);
+ SetColumnWidth(i, w);
+ }
+
+ // Not so good: CPersistence::GetSorting(m_name, GetHeaderCtrl()->GetItemCount(), m_sorting.column1, m_sorting.ascending1, m_sorting.column2, m_sorting.ascending2);
+ // We refrain from saving the sorting because it is too likely, that
+ // users start up with insane settings and don't get it.
+}
+
+void CSortingListControl::SavePersistentAttributes()
+{
+ CArray<int, int> arr;
+ arr.SetSize(GetHeaderCtrl()->GetItemCount());
+
+ GetColumnOrderArray(arr.GetData(), arr.GetSize());
+ CPersistence::SetColumnOrder(m_name, arr);
+
+ for (int i=0; i < arr.GetSize(); i++)
+ arr[i]= GetColumnWidth(i);
+ CPersistence::SetColumnWidths(m_name, arr);
+
+ // Not so good: CPersistence::SetSorting(m_name, m_sorting.column1, m_sorting.ascending1, m_sorting.column2, m_sorting.ascending2);
+}
+
+void CSortingListControl::AddExtendedStyle(DWORD exStyle)
+{
+ SetExtendedStyle(GetExtendedStyle() | exStyle);
+}
+
+void CSortingListControl::RemoveExtendedStyle(DWORD exStyle)
+{
+ SetExtendedStyle(GetExtendedStyle() & ~exStyle);
+}
+
+
+const SSorting& CSortingListControl::GetSorting()
+{
+ return m_sorting;
+}
+
+void CSortingListControl::SetSorting(const SSorting& sorting)
+{
+ m_sorting= sorting;
+}
+
+void CSortingListControl::SetSorting(int sortColumn1, bool ascending1, int sortColumn2, bool ascending2)
+{
+ m_sorting.column1= sortColumn1;
+ m_sorting.ascending1= ascending1;
+ m_sorting.column2= sortColumn2;
+ m_sorting.ascending2= ascending2;
+}
+
+void CSortingListControl::SetSorting(int sortColumn, bool ascending)
+{
+ m_sorting.column2= m_sorting.column1;
+ m_sorting.ascending2= m_sorting.ascending1;
+ m_sorting.column1= sortColumn;
+ m_sorting.ascending1= ascending;
+}
+
+void CSortingListControl::InsertListItem(int i, CSortingListItem *item)
+{
+ LVITEM lvitem;
+ ZeroMemory(&lvitem, sizeof(lvitem));
+
+ lvitem.mask= LVIF_TEXT | LVIF_PARAM;
+ if (HasImages())
+ lvitem.mask|= LVIF_IMAGE;
+
+ lvitem.iItem= i;
+ lvitem.pszText= LPSTR_TEXTCALLBACK;
+ lvitem.iImage= I_IMAGECALLBACK;
+ lvitem.lParam= (LPARAM)item;
+
+ VERIFY(i == CListCtrl::InsertItem(&lvitem));
+}
+
+CSortingListItem *CSortingListControl::GetSortingListItem(int i)
+{
+ return (CSortingListItem *)GetItemData(i);
+}
+
+void CSortingListControl::SortItems()
+{
+ VERIFY(CListCtrl::SortItems(&_CompareFunc, (DWORD_PTR)&m_sorting));
+
+ HDITEM hditem;
+ ZeroMemory(&hditem, sizeof(hditem));
+
+ if (m_indicatedColumn != -1)
+ {
+ CString text;
+ hditem.mask= HDI_TEXT;
+ hditem.pszText= text.GetBuffer(256);
+ hditem.cchTextMax= 256;
+ GetHeaderCtrl()->GetItem(m_indicatedColumn, &hditem);
+ text.ReleaseBuffer();
+ text= text.Mid(2);
+ hditem.pszText= (LPTSTR)(LPCTSTR)text;
+ GetHeaderCtrl()->SetItem(m_indicatedColumn, &hditem);
+ }
+
+ CString text;
+ hditem.mask= HDI_TEXT;
+ hditem.pszText= text.GetBuffer(256);
+ hditem.cchTextMax= 256;
+ GetHeaderCtrl()->GetItem(m_sorting.column1, &hditem);
+ text.ReleaseBuffer();
+ text= (m_sorting.ascending1 ? _T("< ") : _T("> ")) + text;
+ hditem.pszText= (LPTSTR)(LPCTSTR)text;
+ GetHeaderCtrl()->SetItem(m_sorting.column1, &hditem);
+ m_indicatedColumn= m_sorting.column1;
+}
+
+bool CSortingListControl::GetAscendingDefault(int /*column*/)
+{
+ return true;
+}
+
+bool CSortingListControl::HasImages()
+{
+ return false;
+}
+
+int CALLBACK CSortingListControl::_CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
+{
+ CSortingListItem *item1= (CSortingListItem *)lParam1;
+ CSortingListItem *item2= (CSortingListItem *)lParam2;
+ SSorting *sorting= (SSorting *)lParamSort;
+
+ return item1->CompareS(item2, *sorting);
+}
+
+BEGIN_MESSAGE_MAP(CSortingListControl, CListCtrl)
+ ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnLvnGetdispinfo)
+ ON_NOTIFY(HDN_ITEMCLICKA, 0, OnHdnItemclick)
+ ON_NOTIFY(HDN_ITEMCLICKW, 0, OnHdnItemclick)
+ ON_NOTIFY(HDN_ITEMDBLCLICKA, 0, OnHdnItemdblclick)
+ ON_NOTIFY(HDN_ITEMDBLCLICKW, 0, OnHdnItemdblclick)
+ ON_WM_DESTROY()
+END_MESSAGE_MAP()
+
+void CSortingListControl::OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ NMLVDISPINFO *di= reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
+ *pResult= 0;
+
+ CSortingListItem *item= (CSortingListItem *)(di->item.lParam);
+
+ if ((di->item.mask & LVIF_TEXT) != 0)
+ lstrcpyn(di->item.pszText, item->GetText(di->item.iSubItem), di->item.cchTextMax);
+
+ if ((di->item.mask & LVIF_IMAGE) != 0)
+ di->item.iImage= item->GetImage();
+}
+
+void CSortingListControl::OnHdnItemclick(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
+ *pResult = 0;
+
+ int col= phdr->iItem;
+
+ if (col == m_sorting.column1)
+ {
+ m_sorting.ascending1 = ! m_sorting.ascending1;
+ }
+ else
+ {
+ SetSorting(col, GetAscendingDefault(col));
+ }
+
+ SortItems();
+}
+
+
+void CSortingListControl::OnHdnItemdblclick(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ OnHdnItemclick(pNMHDR, pResult);
+}
+
+void CSortingListControl::OnDestroy()
+{
+ SavePersistentAttributes();
+ CListCtrl::OnDestroy();
+}
diff --git a/windirstat/sortinglistcontrol.h b/windirstat/sortinglistcontrol.h
new file mode 100644
index 0000000..b877831
--- /dev/null
+++ b/windirstat/sortinglistcontrol.h
@@ -0,0 +1,105 @@
+// sortinglistcontrol.h - Declaration of CSortingListItem and CSortingListControl
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+//
+// SSorting. A sorting specification. We sort by column1, and if two items
+// equal in column1, we sort them by column2.
+//
+struct SSorting
+{
+ SSorting() { column1= column2= 0; ascending1= ascending2= true; }
+ int column1;
+ bool ascending1;
+ int column2;
+ bool ascending2;
+};
+
+//
+// CSortingListItem. An item in a CSortingListControl.
+//
+class CSortingListItem
+{
+public:
+ virtual CString GetText(int subitem) const;
+ virtual int GetImage() const;
+ virtual int Compare(const CSortingListItem *other, int subitem) const;
+ int CompareS(const CSortingListItem *other, const SSorting& sorting) const;
+};
+
+
+//
+// CSortingListControl. The base class for all our ListControls.
+// The lParams of the items are pointers to CSortingListItems.
+// The items use LPSTR_TEXTCALLBACK and I_IMAGECALLBACK.
+// And the items can compare to one another.
+// CSortingListControl maintains a SSorting and handles clicks
+// on the header items. It also indicates the sorting to the user
+// by adding a "<" or ">" to the header items.
+//
+class CSortingListControl: public CListCtrl
+{
+ DECLARE_DYNAMIC(CSortingListControl)
+public:
+ // Construction
+ CSortingListControl(LPCTSTR name);
+ virtual ~CSortingListControl();
+
+ // Public methods
+ void LoadPersistentAttributes();
+
+ void AddExtendedStyle(DWORD exStyle);
+ void RemoveExtendedStyle(DWORD exStyle);
+
+ const SSorting& GetSorting();
+ void GetSorting(int& sortColumn1, bool& ascending1, int& sortColumn2, bool& ascending2);
+
+ void SetSorting(const SSorting& sorting);
+ void SetSorting(int sortColumn1, bool ascending1, int sortColumn2, bool ascending2);
+ void SetSorting(int sortColumn, bool ascending);
+
+ void InsertListItem(int i, CSortingListItem *item);
+ CSortingListItem *GetSortingListItem(int i);
+
+ void SortItems();
+
+ // Overridables
+ virtual bool GetAscendingDefault(int column);
+ virtual bool HasImages();
+
+private:
+ void SavePersistentAttributes();
+ static int CALLBACK _CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
+
+ CString m_name; // for persistence
+ SSorting m_sorting;
+
+ int m_indicatedColumn;
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnHdnItemclick(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnHdnItemdblclick(NMHDR *pNMHDR, LRESULT *pResult);
+public:
+ afx_msg void OnDestroy();
+};
+
diff --git a/windirstat/stdafx.cpp b/windirstat/stdafx.cpp
new file mode 100644
index 0000000..7856312
--- /dev/null
+++ b/windirstat/stdafx.cpp
@@ -0,0 +1,26 @@
+// stdafx.cpp : source file that includes just the standard includes
+// windirstat.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+
+
diff --git a/windirstat/stdafx.h b/windirstat/stdafx.h
new file mode 100644
index 0000000..26fea83
--- /dev/null
+++ b/windirstat/stdafx.h
@@ -0,0 +1,88 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
+#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
+#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
+#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.
+#endif
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+// turns off MFC's hiding of some common and often safely ignored warning messages
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h> // MFC Core
+#include <afxext.h> // MFC Extensions
+
+#include <afxdtctl.h> // MFC IE 4
+#include <afxcmn.h> // MFC Common Controls
+#include <afxtempl.h> // MFC Container classes
+
+#include <io.h> // _access()
+#include <math.h> // floor(), fmod(), sqrt() etc.
+#include <psapi.h> // PROCESS_MEMORY_INFO
+#include <mapi.h> // E-Mail
+#include <lmcons.h> // UNLEN
+
+#include <atlbase.h> // USES_CONVERSION, ComPtr<>
+
+#pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' (performance warning)
+
+// Headers placed in the common directory
+// (used by windirstat and by setup)
+#include "../common/mdexceptions.h"
+#include "../common/cotaskmem.h"
+#include "../common/commonhelpers.h"
+
+// General purpose headers
+#include "selectobject.h"
+#include "set.h"
+
+#ifdef _DEBUG
+#define _STRONG_DEBUG // Extensive checking (slow)
+#endif
+
+#define countof(arr) (sizeof(arr)/sizeof((arr)[0]))
+
+template<class T> int signum(T x) { return (x) < 0 ? -1 : (x) == 0 ? 0 : 1; }
+
+
diff --git a/windirstat/typeview.cpp b/windirstat/typeview.cpp
new file mode 100644
index 0000000..4c60b1d
--- /dev/null
+++ b/windirstat/typeview.cpp
@@ -0,0 +1,418 @@
+// typeview.cpp - Implementation of CExtensionListControl and CTypeView
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "item.h"
+#include "dirstatdoc.h"
+#include ".\typeview.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+CExtensionListControl::CListItem::CListItem(CExtensionListControl *list, LPCTSTR extension, SExtensionRecord r)
+{
+ m_list= list;
+ m_extension= extension;
+ m_record= r;
+ m_image= -1;
+}
+
+bool CExtensionListControl::CListItem::DrawSubitem(int subitem, CDC *pdc, CRect rc, UINT state, int *width) const
+{
+ if (subitem == COL_EXTENSION)
+ {
+ DrawLabel(m_list, GetMyImageList(), pdc, rc, state, width);
+ }
+ else if (subitem == COL_COLOR)
+ {
+ DrawColor(pdc, rc, state, width);
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void CExtensionListControl::CListItem::DrawColor(CDC *pdc, CRect rc, UINT /*state*/, int *width) const
+{
+ if (width != NULL)
+ {
+ *width= 40;
+ return;
+ }
+
+ rc.DeflateRect(2, 3);
+
+ double surface[4];
+ for (int i=0; i < 4; i++)
+ surface[i]= 0;
+
+ AddRidge(rc, surface, GetOptions()->GetHeightFactor()/100.0 * GetOptions()->GetScaleFactor()/100.0);
+
+ RenderRectangle(pdc, rc, surface, m_record.color);
+ if (GetOptions()->IsTreemapGrid())
+ {
+ CPen pen(PS_SOLID, 1, GetOptions()->GetTreemapGridColor());
+ CSelectObject sopen(pdc, &pen);
+ CSelectStockObject sobrush(pdc, NULL_BRUSH);
+ pdc->Rectangle(rc);
+ }
+}
+
+CString CExtensionListControl::CListItem::GetText(int subitem) const
+{
+ switch (subitem)
+ {
+ case COL_EXTENSION:
+ return GetExtension();
+
+ case COL_COLOR:
+ return _T("(color)");
+
+ case COL_BYTES:
+ return FormatBytes(m_record.bytes);
+
+ case COL_FILES:
+ return FormatCount(m_record.files);
+
+ case COL_DESCRIPTION:
+ return GetDescription();
+
+ default:
+ ASSERT(0);
+ return _T("");
+ }
+}
+
+CString CExtensionListControl::CListItem::GetExtension() const
+{
+ return m_extension;
+}
+
+int CExtensionListControl::CListItem::GetImage() const
+{
+ if (m_image == -1)
+ {
+ m_image= GetMyImageList()->GetExtImageAndDescription(m_extension, m_description);
+ }
+ return m_image;
+}
+
+CString CExtensionListControl::CListItem::GetDescription() const
+{
+ if (m_description.IsEmpty())
+ {
+ m_image= GetMyImageList()->GetExtImageAndDescription(m_extension, m_description);
+ }
+ return m_description;
+}
+
+int CExtensionListControl::CListItem::Compare(const CSortingListItem *baseOther, int subitem) const
+{
+ int r= 0;
+
+ const CListItem *other= (const CListItem *)baseOther;
+
+ switch (subitem)
+ {
+ case COL_EXTENSION:
+ r= GetExtension().CompareNoCase(other->GetExtension());
+ break;
+
+ case COL_COLOR:
+ case COL_BYTES:
+ r= signum(m_record.bytes - other->m_record.bytes);
+ break;
+
+ case COL_FILES:
+ r= signum(m_record.files - other->m_record.files);
+ break;
+
+ case COL_DESCRIPTION:
+ r= GetDescription().CompareNoCase(other->GetDescription());
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ return r;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+BEGIN_MESSAGE_MAP(CExtensionListControl, COwnerDrawnListControl)
+ ON_WM_MEASUREITEM_REFLECT()
+ ON_WM_DESTROY()
+ ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnLvnDeleteitem)
+END_MESSAGE_MAP()
+
+CExtensionListControl::CExtensionListControl()
+: COwnerDrawnListControl(_T("types"), 19)
+{
+}
+
+bool CExtensionListControl::GetAscendingDefault(int column)
+{
+ switch (column)
+ {
+ case COL_EXTENSION:
+ case COL_DESCRIPTION:
+ return true;
+ case COL_COLOR:
+ case COL_BYTES:
+ case COL_FILES:
+ return false;
+ default:
+ ASSERT(0);
+ return true;
+ }
+}
+
+// As we will not receive WM_CREATE, we must do initialization
+// in this extra method. The counterpart is OnDestroy().
+void CExtensionListControl::Initialize()
+{
+ SetSorting(COL_BYTES, false);
+
+ InsertColumn(COL_EXTENSION, LoadString(IDS_EXTCOL_EXTENSION), LVCFMT_LEFT, 60, COL_EXTENSION);
+ InsertColumn(COL_COLOR, LoadString(IDS_EXTCOL_COLOR), LVCFMT_LEFT, 40, COL_COLOR);
+ InsertColumn(COL_BYTES, LoadString(IDS_EXTCOL_BYTES), LVCFMT_RIGHT, 60, COL_BYTES);
+ InsertColumn(COL_FILES, LoadString(IDS_EXTCOL_FILES), LVCFMT_RIGHT, 50, COL_FILES);
+ InsertColumn(COL_DESCRIPTION, LoadString(IDS_EXTCOL_DESCRIPTION), LVCFMT_LEFT, 170, COL_DESCRIPTION);
+
+ OnColumnsInserted();
+
+ // We don't use the list control's image list, but attaching an image list
+ // to the control ensures a proper line height.
+ SetImageList(GetMyImageList(), LVSIL_SMALL);
+}
+
+void CExtensionListControl::OnDestroy()
+{
+ SetImageList(NULL, LVSIL_SMALL);
+ COwnerDrawnListControl::OnDestroy();
+}
+
+void CExtensionListControl::SetExtensionData(const CExtensionData *ed)
+{
+ DeleteAllItems();
+
+ int i= 0;
+ POSITION pos= ed->GetStartPosition();
+ while (pos != NULL)
+ {
+ CString ext;
+ SExtensionRecord r;
+ ed->GetNextAssoc(pos, ext, r);
+
+ CListItem *item= new CListItem(this, ext, r);
+ InsertListItem(i++, item);
+ }
+
+ SortItems();
+}
+
+void CExtensionListControl::SelectExtension(LPCTSTR ext)
+{
+ for (int i=0; i < GetItemCount(); i++)
+ {
+ if (GetListItem(i)->GetExtension().CompareNoCase(ext) == 0)
+ break;
+ }
+ if (i < GetItemCount())
+ {
+ SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
+ EnsureVisible(i, false);
+ }
+}
+
+CExtensionListControl::CListItem *CExtensionListControl::GetListItem(int i)
+{
+ return (CListItem *)GetItemData(i);
+}
+
+void CExtensionListControl::OnLvnDeleteitem(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMLISTVIEW lv= reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
+ delete (CListItem *)(lv->lParam);
+ *pResult = 0;
+}
+
+void CExtensionListControl::MeasureItem(LPMEASUREITEMSTRUCT mis)
+{
+ mis->itemHeight= GetRowHeight();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+static UINT _nIdExtensionListControl = 4711;
+
+
+IMPLEMENT_DYNCREATE(CTypeView, CView)
+
+BEGIN_MESSAGE_MAP(CTypeView, CView)
+ ON_WM_CREATE()
+ ON_WM_ERASEBKGND()
+ ON_WM_SIZE()
+END_MESSAGE_MAP()
+
+
+CTypeView::CTypeView()
+{
+ m_showTypes= true;
+}
+
+CTypeView::~CTypeView()
+{
+}
+
+bool CTypeView::IsShowTypes()
+{
+ return m_showTypes;
+}
+
+void CTypeView::ShowTypes(bool show)
+{
+ m_showTypes= show;
+ OnUpdate(NULL, 0, NULL);
+}
+
+BOOL CTypeView::PreCreateWindow(CREATESTRUCT& cs)
+{
+ return CView::PreCreateWindow(cs);
+}
+
+int CTypeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CView::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ RECT rect= { 0, 0, 0, 0 };
+ VERIFY(m_extensionListControl.CreateEx(0, LVS_SINGLESEL | LVS_OWNERDRAWFIXED | LVS_SHOWSELALWAYS | WS_CHILD|WS_VISIBLE|LVS_REPORT, rect, this, _nIdExtensionListControl));
+ m_extensionListControl.SetExtendedStyle(m_extensionListControl.GetExtendedStyle() | LVS_EX_HEADERDRAGDROP);
+
+ m_extensionListControl.Initialize();
+ return 0;
+}
+
+void CTypeView::OnInitialUpdate()
+{
+ CView::OnInitialUpdate();
+}
+
+void CTypeView::OnUpdate(CView * /*pSender*/, LPARAM lHint, CObject *)
+{
+ switch (lHint)
+ {
+ case HINT_NEWROOT:
+ case 0:
+ if (IsShowTypes() && GetDocument()->IsRootDone())
+ m_extensionListControl.SetExtensionData(GetDocument()->GetExtensionData());
+ else
+ m_extensionListControl.DeleteAllItems();
+
+ // fall thru
+
+ case HINT_SELECTIONCHANGED:
+ case HINT_SHOWNEWSELECTION:
+ if (IsShowTypes())
+ SetSelection();
+ break;
+
+ case HINT_ZOOMCHANGED:
+ break;
+
+ case HINT_REDRAWWINDOW:
+ m_extensionListControl.RedrawWindow();
+ break;
+
+ case HINT_CUSHIONSHADINGCHANGED:
+ case HINT_TREEMAPSTYLECHANGED:
+ InvalidateRect(NULL);
+ m_extensionListControl.InvalidateRect(NULL);
+ m_extensionListControl.GetHeaderCtrl()->InvalidateRect(NULL);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void CTypeView::SetSelection()
+{
+ CItem *item= GetDocument()->GetSelection();
+ if (item == NULL || item->GetType() != IT_FILE)
+ {
+ m_extensionListControl.EnsureVisible(0, false);
+ }
+ else
+ {
+ m_extensionListControl.SelectExtension(item->GetExtension());
+ }
+}
+
+#ifdef _DEBUG
+void CTypeView::AssertValid() const
+{
+ CView::AssertValid();
+}
+
+void CTypeView::Dump(CDumpContext& dc) const
+{
+ CView::Dump(dc);
+}
+
+CDirstatDoc* CTypeView::GetDocument() const // Nicht-Debugversion ist inline
+{
+ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDirstatDoc)));
+ return (CDirstatDoc*)m_pDocument;
+}
+#endif //_DEBUG
+
+
+void CTypeView::OnDraw(CDC* pDC)
+{
+ CView::OnDraw(pDC);
+}
+
+BOOL CTypeView::OnEraseBkgnd(CDC* pDC)
+{
+ return CView::OnEraseBkgnd(pDC);
+}
+
+
+void CTypeView::OnSize(UINT nType, int cx, int cy)
+{
+ CView::OnSize(nType, cx, cy);
+ if (IsWindow(m_extensionListControl.m_hWnd))
+ {
+ CRect rc(0, 0, cx, cy);
+ m_extensionListControl.MoveWindow(rc);
+ }
+}
diff --git a/windirstat/typeview.h b/windirstat/typeview.h
new file mode 100644
index 0000000..3fbacfc
--- /dev/null
+++ b/windirstat/typeview.h
@@ -0,0 +1,127 @@
+// typeview.h - Declaration of CExtensionListControl and CTypeView
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "dirstatdoc.h" // SExtensionRecord
+
+//
+// CExtensionListControl.
+//
+class CExtensionListControl: public COwnerDrawnListControl
+{
+protected:
+ // Columns
+ enum
+ {
+ COL_EXTENSION,
+ COL_COLOR,
+ COL_DESCRIPTION,
+ COL_BYTES,
+ COL_FILES,
+ };
+
+ // CListItem. The items of the CExtensionListControl.
+ class CListItem: public COwnerDrawnListItem
+ {
+ public:
+ CListItem(CExtensionListControl *list, LPCTSTR extension, SExtensionRecord r);
+
+ virtual bool DrawSubitem(int subitem, CDC *pdc, CRect rc, UINT state, int *width) const;
+ virtual CString GetText(int subitem) const;
+
+ CString GetExtension() const;
+ int GetImage() const;
+ int Compare(const CSortingListItem *other, int subitem) const;
+
+ private:
+ void DrawColor(CDC *pdc, CRect rc, UINT state, int *width) const;
+
+ CString GetDescription() const;
+
+ CExtensionListControl *m_list;
+ CString m_extension;
+ SExtensionRecord m_record;
+ mutable CString m_description;
+ mutable int m_image;
+ };
+
+public:
+ CExtensionListControl();
+ virtual bool GetAscendingDefault(int column);
+ void Initialize();
+ void SetExtensionData(const CExtensionData *ed);
+ void SelectExtension(LPCTSTR ext);
+
+protected:
+ CListItem *GetListItem(int i);
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnDestroy();
+ afx_msg void OnLvnDeleteitem(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void MeasureItem(LPMEASUREITEMSTRUCT mis);
+};
+
+
+//
+// CTypeView. The upper right view, which shows the extensions and their
+// cushion colors.
+//
+class CTypeView: public CView
+{
+protected:
+ CTypeView();
+ DECLARE_DYNCREATE(CTypeView)
+
+public:
+ virtual ~CTypeView();
+ CDirstatDoc* GetDocument() const;
+
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+
+ bool IsShowTypes();
+ void ShowTypes(bool show);
+
+protected:
+ virtual void OnInitialUpdate();
+ virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
+ virtual void OnDraw(CDC* pDC);
+ void SetSelection();
+
+ bool m_showTypes; // Whether this view shall be shown (F8 option)
+ CExtensionListControl m_extensionListControl; // The list control
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+public:
+ #ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+ #endif
+};
+
+#ifndef _DEBUG // Debugversion in typeview.cpp
+inline CDirstatDoc* CTypeView::GetDocument() const
+ { return reinterpret_cast<CDirstatDoc*>(m_pDocument); }
+#endif
+
diff --git a/windirstat/windirstat.cpp b/windirstat/windirstat.cpp
new file mode 100644
index 0000000..c8c0418
--- /dev/null
+++ b/windirstat/windirstat.cpp
@@ -0,0 +1,558 @@
+// windirstat.cpp - Implementation of CDirstatApp and some globals
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#include "stdafx.h"
+#include "windirstat.h"
+#include "mainframe.h"
+#include "selectdrivesdlg.h"
+#include "aboutdlg.h"
+#include "reportbugdlg.h"
+#include "modalsendmail.h"
+#include "dirstatdoc.h"
+#include "graphview.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+CMainFrame *GetMainFrame()
+{
+ // Not: return (CMainFrame *)AfxGetMainWnd();
+ // because CWinApp::m_pMainWnd is set too late.
+ return CMainFrame::GetTheFrame();
+}
+
+CDirstatApp *GetApp()
+{
+ return (CDirstatApp *)AfxGetApp();
+}
+
+CString GetAuthorEmail()
+{
+ return _T("bseifert@users.sourceforge.net");
+}
+
+CString GetWinDirStatHomepage()
+{
+ return _T("windirstat.sourceforge.net");
+}
+
+void AddRidge(const CRect& rc, double *surface, double h)
+{
+ /*
+ Unoptimized:
+
+ if (rc.Width() > 0)
+ {
+ surface[2]+= 4 * h * (rc.right + rc.left) / (rc.right - rc.left);
+ surface[0]-= 4 * h / (rc.right - rc.left);
+ }
+
+ if (rc.Height() > 0)
+ {
+ surface[3]+= 4 * h * (rc.bottom + rc.top) / (rc.bottom - rc.top);
+ surface[1]-= 4 * h / (rc.bottom - rc.top);
+ }
+ */
+
+ // Optimized (gains 15 ms of 1030):
+
+ int width= rc.Width();
+ int height= rc.Height();
+
+ ASSERT(width > 0 && height > 0);
+
+ double h4= 4 * h;
+
+ double wf= h4 / width;
+ surface[2]+= wf * (rc.right + rc.left);
+ surface[0]-= wf;
+
+ double hf= h4 / height;
+ surface[3]+= hf * (rc.bottom + rc.top);
+ surface[1]-= hf;
+}
+
+void RenderRectangle(CDC *pdc, const CRect& rc, const double *surface, COLORREF col)
+{
+ if (GetOptions()->IsCushionShading())
+ {
+ RenderCushion(pdc, rc, surface, col);
+ }
+ else
+ {
+ pdc->FillSolidRect(rc, col);
+ }
+}
+
+void RenderCushion(CDC *pdc, const CRect& rc, const double *surface, COLORREF col)
+{
+ // Cushion parameters
+ const double Ia = GetOptions()->GetAmbientLight() / 100.0;
+
+ // where is the light:
+ static const double lx = -1; // negative = left
+ static const double ly = -1; // negative = top
+ static const double lz = 10;
+
+ // Derived parameters
+ const double Is = 1 - Ia; // brightness
+
+ static const double len= sqrt(lx*lx + ly*ly + lz*lz);
+ static const double Lx = lx / len;
+ static const double Ly = lx / len;
+ static const double Lz = lz / len;
+
+ const double colR= GetRValue(col);
+ const double colG= GetGValue(col);
+ const double colB= GetBValue(col);
+
+ for (int iy = rc.top; iy < rc.bottom; iy++)
+ for (int ix = rc.left; ix < rc.right; ix++)
+ {
+ double nx= -(2 * surface[0] * (ix + 0.5) + surface[2]);
+ double ny= -(2 * surface[1] * (iy + 0.5) + surface[3]);
+ double cosa= (nx*Lx + ny*Ly + Lz) / sqrt(nx*nx + ny*ny + 1.0);
+
+ double brightness= Is * cosa;
+ if (brightness < 0)
+ brightness= 0;
+
+ brightness+= Ia;
+ ASSERT(brightness <= 1.0);
+
+ brightness*= 2.5 / BASE_BRIGHTNESS;
+
+ int red = (int)(colR * brightness);
+ int green = (int)(colG * brightness);
+ int blue = (int)(colB * brightness);
+
+ NormalizeColor(red, green, blue);
+
+ pdc->SetPixel(ix, iy, RGB(red, green, blue));
+ }
+}
+
+CMyImageList *GetMyImageList()
+{
+ return GetApp()->GetMyImageList();
+}
+
+
+// CDirstatApp
+
+BEGIN_MESSAGE_MAP(CDirstatApp, CWinApp)
+ ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
+ ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
+ ON_COMMAND(ID_HELP_MANUAL, OnHelpManual)
+ ON_UPDATE_COMMAND_UI(ID_HELP_REPORTBUG, OnUpdateHelpReportbug)
+ ON_COMMAND(ID_HELP_REPORTBUG, OnHelpReportbug)
+END_MESSAGE_MAP()
+
+
+CDirstatApp _theApp;
+
+CDirstatApp::CDirstatApp()
+{
+ m_workingSet= 0;
+ m_pageFaults= 0;
+
+ #ifdef _DEBUG
+ TestScanResourceDllName();
+ #endif
+}
+
+CMyImageList *CDirstatApp::GetMyImageList()
+{
+ m_myImageList.Initialize();
+ return &m_myImageList;
+}
+
+void CDirstatApp::UpdateRamUsage()
+{
+ CWinThread::OnIdle(0);
+}
+
+CString CDirstatApp::FindResourceDllPathByLangid(LANGID& langid)
+{
+ return FindAuxiliaryFileByLangid(_T("wdsr"), _T(".dll"), langid, true);
+}
+
+CString CDirstatApp::FindHelpfilePathByLangid(LANGID langid)
+{
+ CString s;
+ if (langid == GetBuiltInLanguage())
+ {
+ // The english help file is named windirstat.chm.
+ s= GetAppFolder() + _T("\\windirstat.chm");
+ if (FileExists(s))
+ return s;
+ }
+
+ // Help files for other languages are named wdshxxxx.chm (xxxx = LANGID).
+ s= FindAuxiliaryFileByLangid(_T("wdsh"), _T(".chm"), langid, false);
+ if (!s.IsEmpty())
+ return s;
+
+ // If our primary language is English, try windirstat.chm again.
+ if (PRIMARYLANGID(langid) == PRIMARYLANGID(GetBuiltInLanguage()))
+ {
+ s= GetAppFolder() + _T("\\windirstat.chm");
+ if (FileExists(s))
+ return s;
+ }
+
+ // Not found.
+ return _T("");
+}
+
+void CDirstatApp::GetAvailableResourceDllLangids(CArray<LANGID, LANGID>& arr)
+{
+ arr.RemoveAll();
+
+ CFileFind finder;
+ BOOL b= finder.FindFile(GetAppFolder() + _T("\\wdsr*.dll"));
+ while (b)
+ {
+ b= finder.FindNextFile();
+ if (finder.IsDirectory())
+ continue;
+
+ LANGID langid;
+ if (ScanResourceDllName(finder.GetFileName(), langid) && IsCorrectResourceDll(finder.GetFilePath()))
+ arr.Add(langid);
+ }
+}
+
+bool CDirstatApp::ScanResourceDllName(LPCTSTR name, LANGID& langid)
+{
+ return ScanAuxiliaryFileName(_T("wdsr"), _T(".dll"), name, langid);
+}
+
+bool CDirstatApp::ScanAuxiliaryFileName(LPCTSTR prefix, LPCTSTR suffix, LPCTSTR name, LANGID& langid)
+{
+ ASSERT(lstrlen(prefix) == 4); // "wdsr" or "wdsh"
+ ASSERT(lstrlen(suffix) == 4); // ".dll" or ".chm"
+
+ CString s= name; // "wdsr0a01.dll"
+ s.MakeLower();
+ if (s.Left(4) != prefix)
+ return false;
+ s= s.Mid(4); // "0a01.dll"
+
+ if (s.GetLength() != 8)
+ return false;
+
+ if (s.Mid(4) != suffix)
+ return false;
+
+ s= s.Left(4); // "0a01"
+
+ for (int i=0; i < 4; i++)
+ if (!IsHexDigit(s[i]))
+ return false;
+
+ int id;
+ VERIFY(1 == _stscanf(s, _T("%04x"), &id));
+ langid= (LANGID)id;
+
+ return true;
+}
+
+#ifdef _DEBUG
+ void CDirstatApp::TestScanResourceDllName()
+ {
+ LANGID id;
+ ASSERT(!ScanResourceDllName(_T(""), id));
+ ASSERT(!ScanResourceDllName(_T("wdsr.dll"), id));
+ ASSERT(!ScanResourceDllName(_T("wdsr123.dll"), id));
+ ASSERT(!ScanResourceDllName(_T("wdsr12345.dll"), id));
+ ASSERT(!ScanResourceDllName(_T("wdsr1234.exe"), id));
+ ASSERT(ScanResourceDllName(_T("wdsr0123.dll"), id));
+ ASSERT(id == 0x0123);
+ ASSERT(ScanResourceDllName(_T("WDsRa13F.dll"), id));
+ ASSERT(id == 0xa13f);
+ }
+#endif
+
+CString CDirstatApp::FindAuxiliaryFileByLangid(LPCTSTR prefix, LPCTSTR suffix, LANGID& langid, bool checkResource)
+{
+ CString number;
+ number.Format(_T("%04x"), langid);
+
+ CString exactName;
+ exactName.Format(_T("%s%s%s"), prefix, number, suffix);
+
+ CString exactPath= GetAppFolder() + _T("\\") + exactName;
+ if (FileExists(exactPath) && (!checkResource || IsCorrectResourceDll(exactPath)))
+ return exactPath;
+
+ CString search;
+ search.Format(_T("%s*%s"), prefix, suffix);
+
+ CFileFind finder;
+ BOOL b= finder.FindFile(GetAppFolder() + _T("\\") + search);
+ while (b)
+ {
+ b= finder.FindNextFile();
+ if (finder.IsDirectory())
+ continue;
+
+ LANGID id;
+ if (!ScanAuxiliaryFileName(prefix, suffix, finder.GetFileName(), id))
+ continue;
+
+ if (PRIMARYLANGID(id) == PRIMARYLANGID(langid) && (!checkResource || IsCorrectResourceDll(finder.GetFilePath())))
+ {
+ langid= id;
+ return finder.GetFilePath();
+ }
+ }
+
+ return _T("");
+}
+
+CString CDirstatApp::ConstructHelpFileName()
+{
+ return FindHelpfilePathByLangid(CLanguageOptions::GetLanguage());
+}
+
+bool CDirstatApp::IsCorrectResourceDll(LPCTSTR path)
+{
+ HMODULE module= LoadLibrary(path);
+ if (module == NULL)
+ return false;
+
+ CString reference= LoadString(IDS_RESOURCEVERSION);
+
+ int bufsize= reference.GetLength() * 2;
+ CString s;
+ int r= LoadString(module, IDS_RESOURCEVERSION, s.GetBuffer(bufsize), bufsize);
+ s.ReleaseBuffer();
+
+ FreeLibrary(module);
+
+ if (r == 0 || s != reference)
+ return false;
+
+ return true;
+}
+
+void CDirstatApp::ReReadMountPoints()
+{
+ m_mountPoints.Initialize();
+}
+
+bool CDirstatApp::IsMountPoint(CString path)
+{
+ return m_mountPoints.IsMountPoint(path);
+}
+
+CString CDirstatApp::GetCurrentProcessMemoryInfo()
+{
+ UpdateMemoryInfo();
+
+ if (m_workingSet == 0)
+ return _T("");
+
+ CString n= PadWidthBlanks(FormatBytes(m_workingSet), 11);
+
+ CString s;
+ s.FormatMessage(IDS_RAMUSAGEs, n);
+
+ return s;
+}
+
+bool CDirstatApp::UpdateMemoryInfo()
+{
+ if (!m_psapi.IsSupported())
+ return false;
+
+ PROCESS_MEMORY_COUNTERS pmc;
+ ZeroMemory(&pmc, sizeof(pmc));
+ pmc.cb= sizeof(pmc);
+
+ if (!m_psapi.GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)))
+ return false;
+
+ m_workingSet= pmc.WorkingSetSize;
+
+ bool ret= false;
+ if (pmc.PageFaultCount > m_pageFaults + 500)
+ ret= true;
+
+ m_pageFaults= pmc.PageFaultCount;
+
+ return ret;
+}
+
+LANGID CDirstatApp::GetBuiltInLanguage()
+{
+ return MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
+}
+
+BOOL CDirstatApp::InitInstance()
+{
+ CWinApp::InitInstance();
+
+ InitCommonControls(); // InitCommonControls() is necessary for Windows XP.
+ VERIFY(AfxOleInit()); // For SHBrowseForFolder()
+ AfxEnableControlContainer(); // For our rich edit controls in the about dialog
+ VERIFY(AfxInitRichEdit()); // Rich edit control in out about box
+ VERIFY(AfxInitRichEdit2()); // On NT, this helps.
+ EnableHtmlHelp();
+
+ SetRegistryKey(_T("Seifert"));
+ LoadStdProfileSettings(4);
+
+ m_langid= GetBuiltInLanguage();
+
+ LANGID langid= CLanguageOptions::GetLanguage();
+ if (langid != GetBuiltInLanguage())
+ {
+ CString resourceDllPath= FindResourceDllPathByLangid(langid);
+ if (!resourceDllPath.IsEmpty())
+ {
+ HINSTANCE dll= LoadLibrary(resourceDllPath);
+ if (dll != NULL)
+ {
+ AfxSetResourceHandle(dll);
+ m_langid= langid;
+ }
+ else
+ {
+ TRACE(_T("LoadLibrary(%s) failed: %u\r\n"), resourceDllPath, GetLastError());
+ }
+ }
+ // else: We use our built-in English resources.
+ }
+
+ GetOptions()->LoadFromRegistry();
+
+ free((void*)m_pszHelpFilePath);
+ m_pszHelpFilePath=_tcsdup(ConstructHelpFileName()); // ~CWinApp() will free this memory.
+
+ m_pDocTemplate = new CSingleDocTemplate(
+ IDR_MAINFRAME,
+ RUNTIME_CLASS(CDirstatDoc),
+ RUNTIME_CLASS(CMainFrame),
+ RUNTIME_CLASS(CGraphView));
+ if (!m_pDocTemplate)
+ return FALSE;
+ AddDocTemplate(m_pDocTemplate);
+
+ CCommandLineInfo cmdInfo;
+ ParseCommandLine(cmdInfo);
+
+ m_nCmdShow= SW_HIDE;
+ if (!ProcessShellCommand(cmdInfo))
+ return FALSE;
+
+ GetMainFrame()->InitialShowWindow();
+ m_pMainWnd->UpdateWindow();
+
+ // When called by setup.exe, windirstat remained in the
+ // background, so we do a
+ m_pMainWnd->BringWindowToTop();
+ m_pMainWnd->SetForegroundWindow();
+
+ if (cmdInfo.m_nShellCommand != CCommandLineInfo::FileOpen)
+ {
+ OnFileOpen();
+ }
+
+ return TRUE;
+}
+
+LANGID CDirstatApp::GetLangid()
+{
+ return m_langid;
+}
+
+void CDirstatApp::OnAppAbout()
+{
+ StartAboutDialog();
+}
+
+void CDirstatApp::OnFileOpen()
+{
+ CSelectDrivesDlg dlg;
+ if (IDOK == dlg.DoModal())
+ {
+ CString path= CDirstatDoc::EncodeSelection((RADIO)dlg.m_radio, dlg.m_folderName, dlg.m_drives);
+ m_pDocTemplate->OpenDocumentFile(path, true);
+ }
+}
+
+BOOL CDirstatApp::OnIdle(LONG lCount)
+{
+ bool more= false;
+
+ CDirstatDoc *doc= GetDocument();
+ if (doc != NULL && !doc->Work(600))
+ more= true;
+
+ if (CWinApp::OnIdle(lCount))
+ more= true;
+
+ // The status bar (RAM usage) is updated only when count == 0.
+ // That's why we call an extra OnIdle(0) here.
+ if (CWinThread::OnIdle(0))
+ more= true;
+
+ return more;
+}
+
+void CDirstatApp::OnHelpManual()
+{
+ DoContextHelp(IDH_StartPage);
+}
+
+void CDirstatApp::DoContextHelp(DWORD topic)
+{
+ if (FileExists(m_pszHelpFilePath))
+ {
+ // I want a NULL parent window. So I don't use CWinApp::HtmlHelp().
+ ::HtmlHelp(NULL, m_pszHelpFilePath, HH_HELP_CONTEXT, topic);
+ }
+ else
+ {
+ CString msg;
+ msg.FormatMessage(IDS_HELPFILEsCOULDNOTBEFOUND, _T("windirstat.chm"));
+ AfxMessageBox(msg);
+ }
+}
+
+void CDirstatApp::OnUpdateHelpReportbug(CCmdUI *pCmdUI)
+{
+ pCmdUI->Enable(CModalSendMail::IsSendMailAvailable());
+}
+
+void CDirstatApp::OnHelpReportbug()
+{
+ CReportBugDlg dlg;
+ if (IDOK == dlg.DoModal())
+ {
+ CModalSendMail msm;
+ msm.SendMail(dlg.m_recipient, dlg.m_subject, dlg.m_body);
+ }
+}
diff --git a/windirstat/windirstat.h b/windirstat/windirstat.h
new file mode 100644
index 0000000..a2fd63a
--- /dev/null
+++ b/windirstat/windirstat.h
@@ -0,0 +1,108 @@
+// windirstat.h - Main header for the windirstat application
+//
+// WinDirStat - Directory Statistics
+// Copyright (C) 2003 Bernhard Seifert
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: bseifert@users.sourceforge.net, bseifert@daccord.net
+
+#pragma once
+
+#include "resource.h"
+#include "myimagelist.h"
+#include "osspecific.h"
+#include "globalhelpers.h"
+#include "options.h"
+#include "mountpoints.h"
+#include "helpmap.h"
+
+typedef CMap<CString, LPCTSTR, COLORREF, COLORREF> CExtensionColorMap; // ".bmp" -> color
+
+class CMainFrame;
+class CDirstatApp;
+
+// Frequently used "globals"
+CMainFrame *GetMainFrame();
+CDirstatApp *GetApp();
+CMyImageList *GetMyImageList();
+
+// Other application related globals
+CString GetAuthorEmail();
+CString GetWinDirStatHomepage();
+
+void AddRidge(const CRect& rc, double *surface, double h);
+void RenderRectangle(CDC *pdc, const CRect& rc, const double *surface, COLORREF col);
+void RenderCushion(CDC *pdc, const CRect& rc, const double *surface, COLORREF col);
+
+//
+// CDirstatApp. The MFC application object.
+// Knows about RAM Usage, Mount points, Help files and the CMyImageList.
+//
+class CDirstatApp : public CWinApp
+{
+public:
+ CDirstatApp();
+ virtual BOOL InitInstance();
+
+ LANGID GetBuiltInLanguage() ;
+ LANGID GetLangid();
+
+ void ReReadMountPoints();
+ bool IsMountPoint(CString path);
+
+ CString GetCurrentProcessMemoryInfo();
+
+ CMyImageList *GetMyImageList();
+ void UpdateRamUsage();
+
+ void DoContextHelp(DWORD topic);
+
+ void GetAvailableResourceDllLangids(CArray<LANGID, LANGID>& arr);
+
+protected:
+ CString FindResourceDllPathByLangid(LANGID& langid);
+ CString FindHelpfilePathByLangid(LANGID langid);
+ CString FindAuxiliaryFileByLangid(LPCTSTR prefix, LPCTSTR suffix, LANGID& langid, bool checkResource);
+ bool ScanResourceDllName(LPCTSTR name, LANGID& langid);
+ bool ScanAuxiliaryFileName(LPCTSTR prefix, LPCTSTR suffix, LPCTSTR name, LANGID& langid);
+ #ifdef _DEBUG
+ void TestScanResourceDllName();
+ #endif
+ bool IsCorrectResourceDll(LPCTSTR path);
+
+ CString ConstructHelpFileName();
+
+ bool UpdateMemoryInfo();
+
+ virtual BOOL OnIdle(LONG lCount); // This is, where scanning is done.
+
+ CSingleDocTemplate* m_pDocTemplate; // MFC voodoo.
+
+ LANGID m_langid; // Language we are running
+ CMountPoints m_mountPoints; // Mount point information
+ CMyImageList m_myImageList; // Out central image list
+ CPsapi m_psapi; // Dynamically linked psapi.dll (for RAM usage)
+ LONGLONG m_workingSet; // Current working set (RAM usage)
+ LONGLONG m_pageFaults; // Page faults so far (unused)
+
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnFileOpen();
+ afx_msg void OnHelpManual();
+ afx_msg void OnAppAbout();
+ afx_msg void OnUpdateHelpReportbug(CCmdUI *pCmdUI);
+ afx_msg void OnHelpReportbug();
+};
+
diff --git a/windirstat/windirstat.rc b/windirstat/windirstat.rc
new file mode 100644
index 0000000..b92aba3
--- /dev/null
+++ b/windirstat/windirstat.rc
@@ -0,0 +1,864 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL)\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON "res\\icon1.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDR_MAINFRAME BITMAP "res\\Toolbar.bmp"
+IDB_NODES BITMAP "res\\bitmap1.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Toolbar
+//
+
+IDR_MAINFRAME TOOLBAR 16, 15
+BEGIN
+ BUTTON ID_FILE_OPEN
+ BUTTON ID_REFRESHALL
+ SEPARATOR
+ BUTTON ID_CLEANUP_OPEN
+ BUTTON ID_EDIT_COPY
+ BUTTON ID_CLEANUP_OPENINEXPLORER
+ BUTTON ID_CLEANUP_OPENINCONSOLE
+ BUTTON ID_REFRESHSELECTED
+ SEPARATOR
+ BUTTON ID_CLEANUP_DELETETOTRASHBIN
+ BUTTON ID_CLEANUP_DELETE
+ SEPARATOR
+ BUTTON ID_CLEANUP_PROPERTIES
+ SEPARATOR
+ BUTTON ID_TREEMAP_ZOOMIN
+ BUTTON ID_TREEMAP_ZOOMOUT
+ SEPARATOR
+ BUTTON ID_HELP_MANUAL
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MAINFRAME MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
+ MENUITEM SEPARATOR
+ MENUITEM "Refresh &All", ID_REFRESHALL
+ MENUITEM "Refresh &Selected", ID_REFRESHSELECTED
+ MENUITEM SEPARATOR
+ MENUITEM "&Quit\tAlt+F4", ID_APP_EXIT
+ END
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM "&Copy Path\tCtrl+C", ID_EDIT_COPY
+ END
+ POPUP "&Clean Up"
+ BEGIN
+ MENUITEM "&Open\tEnter", ID_CLEANUP_OPEN
+ MENUITEM SEPARATOR
+ MENUITEM "&Explorer Here\tCtrl+E", ID_CLEANUP_OPENINEXPLORER
+ MENUITEM "&Command Prompt Here\tCtrl+P", ID_CLEANUP_OPENINCONSOLE
+ MENUITEM "&Delete (to Recycle Bin)\tDel",
+ ID_CLEANUP_DELETETOTRASHBIN
+ MENUITEM "Delete (no &way to undelete!)\tShift+Del",
+ ID_CLEANUP_DELETE
+ MENUITEM SEPARATOR
+ MENUITEM "&Properties", ID_CLEANUP_PROPERTIES
+ MENUITEM SEPARATOR
+ MENUITEM "Empty Recycle &Bin", ID_CLEANUP_EMPTYRECYCLEBIN
+ MENUITEM SEPARATOR
+ MENUITEM "User defined cleanup #0", ID_DUMMY_USERDEFINEDCLEANUP
+ , GRAYED
+ END
+ POPUP "&Treemap"
+ BEGIN
+ MENUITEM "&Show Treemap\tF9", ID_VIEW_SHOWTREEMAP
+ MENUITEM SEPARATOR
+ MENUITEM "Zoom &in\t+", ID_TREEMAP_ZOOMIN
+ MENUITEM "Zoom &out\t-", ID_TREEMAP_ZOOMOUT
+ MENUITEM "&Reselect Child\t*", 33011
+ MENUITEM "&Select Parent\t/", ID_TREEMAP_SELECTPARENT
+ MENUITEM SEPARATOR
+ MENUITEM "&Help about Treemaps", ID_TREEMAP_HELPABOUTTREEMAPS
+ END
+ POPUP "&Report"
+ BEGIN
+ MENUITEM "&Send Mail to Owner...", ID_SENDMAILTOOWNER
+ END
+ POPUP "&Options"
+ BEGIN
+ MENUITEM "Show &Free Space\tF6", ID_VIEW_SHOWFREESPACE
+ MENUITEM "Show &Unknown\tF7", ID_VIEW_SHOWUNKNOWN
+ MENUITEM SEPARATOR
+ MENUITEM "Show File &Types\tF8", ID_VIEW_SHOWFILETYPES
+ MENUITEM "Show Tree&map\tF9", ID_VIEW_SHOWTREEMAP
+ MENUITEM "Show Tool&bar", ID_VIEW_TOOLBAR
+ MENUITEM "Show S&tatusbar", ID_VIEW_STATUS_BAR
+ MENUITEM SEPARATOR
+ MENUITEM "&Configure WinDirStat...", ID_CONFIGURE
+ END
+ POPUP "&?"
+ BEGIN
+ MENUITEM "&Help\tF1", ID_HELP_MANUAL
+ MENUITEM "&Report Bug/Feedback...", ID_HELP_REPORTBUG
+ MENUITEM SEPARATOR
+ MENUITEM "&About WinDirStat...", ID_APP_ABOUT
+ END
+END
+
+IDR_POPUPLIST MENU
+BEGIN
+ POPUP "POPUP_LIST"
+ BEGIN
+ MENUITEM "&Open\tEnter", ID_CLEANUP_OPEN
+ MENUITEM SEPARATOR
+ MENUITEM "&Copy Path\tCtrl+C", 57634
+ MENUITEM "&Explorer Here\tCtrl+E", 32774
+ MENUITEM "&Command Prompt Here\tCtrl+P", 32808
+ MENUITEM "&Refresh Selected", 32817
+ MENUITEM SEPARATOR
+ MENUITEM "&Delete (to Recyle Bin)\tDel", 32809
+ MENUITEM "Delete (no &way to undelete!)\tShift+Del", 32810
+ MENUITEM SEPARATOR
+ MENUITEM "&Properties", ID_CLEANUP_PROPERTIES
+ MENUITEM SEPARATOR
+ END
+END
+
+IDR_POPUPGRAPH MENU
+BEGIN
+ POPUP "POPUP_GRAPH"
+ BEGIN
+ MENUITEM "Zoom &in\t+", 32783
+ MENUITEM "Zoom &out\t-", 32784
+ MENUITEM "&Reselect Child\t*", ID_TREEMAP_RESELECTCHILD
+ MENUITEM "&Select Parent\t/", ID_TREEMAP_SELECTPARENT
+ MENUITEM SEPARATOR
+ MENUITEM "&Copy Path\tCtrl+C", 57634
+ MENUITEM "&Explorer Here\tCtrl+E", 32774
+ MENUITEM "C&ommand Prompt Here\tCtrl+P", 32808
+ MENUITEM SEPARATOR
+ MENUITEM "C&ancel\tEsc", ID_POPUP_CANCEL
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_MAINFRAME ACCELERATORS
+BEGIN
+ VK_DELETE, ID_CLEANUP_DELETE, VIRTKEY, SHIFT, NOINVERT
+ VK_DELETE, ID_CLEANUP_DELETETOTRASHBIN, VIRTKEY, NOINVERT
+ "P", ID_CLEANUP_OPENINCONSOLE, VIRTKEY, CONTROL, NOINVERT
+ "E", ID_CLEANUP_OPENINEXPLORER, VIRTKEY, CONTROL, NOINVERT
+ "C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ "N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT
+ "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
+ VK_F1, ID_HELP_MANUAL, VIRTKEY, NOINVERT
+ VK_MULTIPLY, ID_TREEMAP_RESELECTCHILD, VIRTKEY, NOINVERT
+ VK_DIVIDE, ID_TREEMAP_SELECTPARENT, VIRTKEY, NOINVERT
+ VK_ADD, ID_TREEMAP_ZOOMIN, VIRTKEY, NOINVERT
+ VK_SUBTRACT, ID_TREEMAP_ZOOMOUT, VIRTKEY, NOINVERT
+ "0", ID_USERDEFINEDCLEANUP0, VIRTKEY, CONTROL, NOINVERT
+ "1", ID_USERDEFINEDCLEANUP1, VIRTKEY, CONTROL, NOINVERT
+ "2", ID_USERDEFINEDCLEANUP2, VIRTKEY, CONTROL, NOINVERT
+ "3", ID_USERDEFINEDCLEANUP3, VIRTKEY, CONTROL, NOINVERT
+ "4", ID_USERDEFINEDCLEANUP4, VIRTKEY, CONTROL, NOINVERT
+ "5", ID_USERDEFINEDCLEANUP5, VIRTKEY, CONTROL, NOINVERT
+ "6", ID_USERDEFINEDCLEANUP6, VIRTKEY, CONTROL, NOINVERT
+ "7", ID_USERDEFINEDCLEANUP7, VIRTKEY, CONTROL, NOINVERT
+ "8", ID_USERDEFINEDCLEANUP8, VIRTKEY, CONTROL, NOINVERT
+ "9", ID_USERDEFINEDCLEANUP9, VIRTKEY, CONTROL, NOINVERT
+ VK_F8, ID_VIEW_SHOWFILETYPES, VIRTKEY, NOINVERT
+ VK_F6, ID_VIEW_SHOWFREESPACE, VIRTKEY, NOINVERT
+ VK_F9, ID_VIEW_SHOWTREEMAP, VIRTKEY, NOINVERT
+ VK_F7, ID_VIEW_SHOWUNKNOWN, VIRTKEY, NOINVERT
+ VK_RETURN, ID_CLEANUP_OPEN, VIRTKEY, NOINVERT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 273, 199
+STYLE DS_SETFONT | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU |
+ WS_THICKFRAME
+CAPTION "About WinDirStat"
+FONT 9, "Microsoft Sans Serif", 400, 0, 0x0
+BEGIN
+ CONTROL "",IDC_TAB,"SysTabControl32",WS_TABSTOP,7,22,259,155,
+ WS_EX_ACCEPTFILES
+ DEFPUSHBUTTON "OK",IDOK,111,180,50,12,WS_GROUP
+ CTEXT "WinDirStat 0.0.000",IDC_CAPTION,69,7,134,8
+ ICON IDR_MAINFRAME,IDC_STATIC,7,3,20,20
+END
+
+IDD_SELECTDRIVES DIALOGEX 0, 0, 276, 182
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU |
+ WS_THICKFRAME
+CAPTION "WinDirStat - Select Drives"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "&All Local Drives",IDC_ALLLOCALDRIVES,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP,7,7,99,10
+ CONTROL "&Individual Drives",IDC_SOMEDRIVES,"Button",
+ BS_AUTORADIOBUTTON,7,31,91,10
+ CONTROL "",IDC_DRIVES,"SysListView32",LVS_REPORT |
+ LVS_OWNERDRAWFIXED | LVS_ALIGNLEFT | WS_BORDER |
+ WS_TABSTOP,7,43,262,100
+ CONTROL "A &Folder",IDC_AFOLDER,"Button",BS_AUTORADIOBUTTON,7,
+ 150,100,10
+ EDITTEXT IDC_FOLDERNAME,6,161,209,14,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_BROWSEFOLDER,219,161,50,14
+ DEFPUSHBUTTON "OK",IDOK,219,7,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,219,24,50,14
+END
+
+IDD_DELETE_WARNING DIALOGEX 0, 0, 276, 150
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Warning"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "No",IDNO,163,129,50,14
+ PUSHBUTTON "Yes",IDYES,63,129,50,14
+ CONTROL "&Don't show this warning again.",IDC_DONTSHOWAGAIN,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,99,139,10
+ LTEXT "Do you know what you are doing?",IDC_STATIC,7,7,110,8
+ LTEXT "Your are going to remove",IDC_STATIC,7,23,82,8
+ CTEXT "<filename>",IDC_FILENAME,7,38,262,8,SS_PATHELLIPSIS
+ LTEXT "from your computer.",IDC_STATIC,7,53,67,8
+ LTEXT "Deletion of system files or directories can seriously damage your system.",
+ IDC_STATIC,7,76,262,19
+ LTEXT "Continue?",IDC_STATIC,7,99,104,8
+END
+
+IDD_MODALAPISHUTTLE DIALOGEX 0, 0, 186, 90
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "<invisible dialog>"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+END
+
+IDD_PAGE_CLEANUPS DIALOGEX 0, 0, 380, 202
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Cleanups"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LISTBOX IDC_LIST,7,7,113,169,LBS_HASSTRINGS |
+ LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ CONTROL "&Enabled",IDC_ENABLED,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,129,7,53,10
+ EDITTEXT IDC_TITLE,212,7,161,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_COMMANDLINE,129,35,244,14,ES_AUTOHSCROLL
+ LTEXT "%p Full Path",IDC_STATIC,128,54,93,8
+ LTEXT "%n File/Directory Name without Path",IDC_STATIC,225,54,
+ 138,8
+ LTEXT "%sp Subdir Full Path",IDC_HINTSP,128,63,94,8
+ LTEXT "%sn Subdir Name without Path",IDC_HINTSN,225,63,138,8
+ CONTROL "&Drives",IDC_WORKSFORDRIVES,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,138,92,49,10
+ CONTROL "D&irectories",IDC_WORKSFORDIRECTORIES,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,218,92,69,10
+ CONTROL "&Files",IDC_WORKSFORFILES,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,138,107,69,10
+ CONTROL "<Files> &Pseudo Entries",IDC_WORKSFORFILESFOLDER,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,217,107,122,10
+ PUSHBUTTON "&Help",IDC_HELPBUTTON,323,131,50,14
+ CONTROL "&Recurse into Subdirectories",
+ IDC_RECURSEINTOSUBDIRECTORIES,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,128,132,160,10
+ CONTROL "&Ask for Confirmation",IDC_ASKFORCONFIRMATION,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,128,146,160,10
+ CONTROL "&Show Console Window",IDC_SHOWCONSOLEWINDOW,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,128,160,100,10
+ CONTROL "&Wait for Completion",IDC_WAITFORCOMPLETION,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,250,160,100,10
+ COMBOBOX IDC_REFRESHPOLICY,128,183,245,93,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "&Up",IDC_UP,21,181,37,14
+ PUSHBUTTON "&Down",IDC_DOWN,66,181,37,14
+ LTEXT "Refresh &Policy",IDC_STATIC,128,174,108,8
+ LTEXT "&Title",IDC_STATIC,186,7,24,8
+ LTEXT "&Command Line",IDC_STATIC,129,25,83,8
+ GROUPBOX "Works for",IDC_STATIC,129,81,244,40
+END
+
+IDD_PAGE_TREELIST DIALOGEX 0, 0, 380, 199
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Directory List"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "&Show Grid",IDC_TREELISTGRID,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,23,25,97,10
+ PUSHBUTTON "Tree Level &1",IDC_COLORBUTTON0,151,19,175,14,0,
+ WS_EX_RIGHT
+ PUSHBUTTON "Tree Level &2",IDC_COLORBUTTON1,167,40,159,14,0,
+ WS_EX_RIGHT
+ PUSHBUTTON "Tree Level &3",IDC_COLORBUTTON2,181,61,145,14,0,
+ WS_EX_RIGHT
+ PUSHBUTTON "Tree Level &4",IDC_COLORBUTTON3,195,82,131,14,0,
+ WS_EX_RIGHT
+ PUSHBUTTON "Tree Level &5",IDC_COLORBUTTON4,207,103,119,14,0,
+ WS_EX_RIGHT
+ PUSHBUTTON "Tree Level &6",IDC_COLORBUTTON5,218,124,108,14,0,
+ WS_EX_RIGHT
+ PUSHBUTTON "Tree Level &7",IDC_COLORBUTTON6,227,145,99,14,0,
+ WS_EX_RIGHT
+ PUSHBUTTON "Tree Level &8",IDC_COLORBUTTON7,236,166,90,14,0,
+ WS_EX_RIGHT
+ CONTROL "",IDC_SLIDER,"msctls_trackbar32",TBS_VERT | TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,339,29,18,160
+ GROUPBOX "Subtree Percentage &Colors",IDC_STATIC,129,7,244,185
+END
+
+IDD_PAGE_TREEMAP DIALOGEX 0, 0, 380, 202
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Treemap"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "&Use Cushion Shading",IDC_CUSHIONSHADING,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,18,15,122,10
+ LTEXT "&Height",IDC_STATIC,31,32,54,8
+ EDITTEXT IDC_HEIGHTFACTOR,88,30,35,14,ES_AUTOHSCROLL
+ CONTROL "",IDC_HEIGHTFACTORSPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,125,30,
+ 11,14
+ LTEXT "&Scale Factor",IDC_STATIC,31,53,54,8
+ EDITTEXT IDC_SCALEFACTOR,88,51,35,14,ES_AUTOHSCROLL
+ CONTROL "",IDC_SCALEFACTORSPIN,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_AUTOBUDDY | UDS_ARROWKEYS,125,51,11,14
+ LTEXT "&Ambient Light",IDC_STATIC,31,74,53,8
+ EDITTEXT IDC_AMBIENTLIGHT,88,73,35,14,ES_AUTOHSCROLL
+ CONTROL "",IDC_AMBIENTLIGHTSPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,125,73,
+ 11,14
+ PUSHBUTTON "&Reset to defaults",IDC_RESETTODEFAULTS,31,94,105,14
+ CONTROL "Show &Grid",IDC_TREEMAPGRID,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,18,144,48,10
+ PUSHBUTTON "Grid &Color",IDC_TREEMAPGRIDCOLOR,74,143,62,14,0,
+ WS_EX_RIGHT
+ CONTROL "",IDC_DEMO,"Static",SS_BLACKFRAME | WS_BORDER,147,30,
+ 118,78,WS_EX_TRANSPARENT
+ PUSHBUTTON "H&ighlight Rectangle",IDC_TREEMAPHIGHLIGHTCOLOR,18,166,
+ 117,14,0,WS_EX_RIGHT
+END
+
+IDD_PAGE_GENERAL DIALOGEX 0, 0, 380, 202
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "General"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "&Cross File System Boundaries",IDC_FOLLOWMOUNTPOINTS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,32,29,229,10
+ CONTROL "&Show Sizes in GB/MB/KB/Bytes Format",IDC_HUMANFORMAT,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,32,49,229,10
+ CONTROL "&Pacman Animation in Directory Tree",
+ IDC_PACMANANIMATION,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,32,69,216,10
+ LTEXT "&Language",IDC_STATIC,32,97,166,8
+ COMBOBOX IDC_COMBO,32,110,156,140,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ LTEXT "Language changes take not effect until the application is restarted.",
+ IDC_STATIC,200,110,173,35
+END
+
+IDD_REPORTBUG DIALOGEX 0, 0, 360, 233
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU |
+ WS_THICKFRAME
+CAPTION "WinDirStat - Submit Bug Report/Feedback"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "&Critical",IDC_CRITICAL,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP,14,43,43,10
+ CONTROL "&Grave",IDC_GRAVE,"Button",BS_AUTORADIOBUTTON,73,43,43,
+ 10
+ CONTROL "&Normal",IDC_NORMAL,"Button",BS_AUTORADIOBUTTON,132,43,
+ 43,10
+ CONTROL "&Wish",IDC_WISH,"Button",BS_AUTORADIOBUTTON,191,43,43,
+ 10
+ CONTROL "General &Feedback",IDC_FEEDBACK,"Button",
+ BS_AUTORADIOBUTTON,250,43,79,10
+ EDITTEXT IDC_INAWORD,60,61,293,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_TEXT,7,118,346,80,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
+ DEFPUSHBUTTON "OK",IDOK,154,212,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,303,212,50,14
+ LTEXT "From:",IDC_STATIC,7,7,20,8
+ LTEXT "To:",IDC_STATIC_TO,185,7,12,8
+ LTEXT "<from>",IDC_FROM,51,7,122,8
+ LTEXT "<to>",IDC_TO,230,7,123,8
+ GROUPBOX "Severity",IDC_STATIC_SEVERITY,7,33,346,24,0,
+ WS_EX_TRANSPARENT
+ LTEXT "In a &word:",IDC_STATIC,7,65,49,8
+ LTEXT "&Enter the text (in English or German, please) that you wish to submit for the bug report or comment.",
+ IDC_STATIC,7,84,346,12
+ LTEXT "Application:",IDC_STATIC,7,18,38,8
+ LTEXT "<application>",IDC_APPLICATION,51,18,123,8
+ LTEXT "Platform:",IDC_STATIC_PLATFORM,185,18,30,8
+ LTEXT "<platform>",IDC_PLATFORM,230,18,123,8
+ LTEXT "For a bug report, it's best if you describe the symptom, including the exact wording of the error message, and, if possible, the steps to reproduce the behavior.",
+ IDC_HINT,7,99,346,19
+ LTEXT "When you press OK, you will be able to review the message in your e-mail program.",
+ IDC_STATIC_OKHINT,7,201,346,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,0,0,0
+ PRODUCTVERSION 0,0,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "Comments", "See Aboutbox"
+ VALUE "CompanyName", "See Aboutbox"
+ VALUE "FileDescription", "WinDirStat - Directory Statistics"
+ VALUE "FileVersion", "See Aboutbox"
+ VALUE "InternalName", "windirstat.exe"
+ VALUE "LegalCopyright", "See Aboutbox"
+ VALUE "LegalTrademarks", "See Aboutbox"
+ VALUE "OriginalFilename", "windirstat.exe"
+ VALUE "ProductName", "WinDirStat"
+ VALUE "ProductVersion", "See Aboutbox"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_ABOUTBOX, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 266
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 192
+ END
+
+ IDD_SELECTDRIVES, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 269
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 175
+ END
+
+ IDD_DELETE_WARNING, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 269
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 143
+ END
+
+ IDD_MODALAPISHUTTLE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 83
+ END
+
+ IDD_PAGE_CLEANUPS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 373
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 195
+ END
+
+ IDD_PAGE_TREELIST, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 373
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 192
+ END
+
+ IDD_PAGE_TREEMAP, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 373
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 195
+ END
+
+ IDD_PAGE_GENERAL, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 373
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 195
+ END
+
+ IDD_REPORTBUG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 353
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 226
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// RT_MANIFEST
+//
+
+1 RT_MANIFEST "res\\windirstat.manifest"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXT
+//
+
+IDR_LICENSE TEXT "res\\license.txt"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDR_MAINFRAME "WinDirStat\n\nWinDirStat\n\n\n\n"
+END
+
+STRINGTABLE
+BEGIN
+ AFX_IDS_APP_TITLE "WinDirStat"
+ AFX_IDS_IDLEMESSAGE "Ready"
+END
+
+STRINGTABLE
+BEGIN
+ ID_INDICATOR_EXT "EXT"
+ ID_INDICATOR_CAPS "CAP"
+ ID_INDICATOR_NUM "NUM"
+ ID_INDICATOR_SCRL "SCRL"
+ ID_INDICATOR_OVR "OVR"
+ ID_INDICATOR_REC "REC"
+ ID_INDICATOR_MEMORYUSAGE "RAM Usage: 123.456.789"
+END
+
+STRINGTABLE
+BEGIN
+ ID_FILE_OPEN "Opens a Collection of Drives.\nOpen"
+END
+
+STRINGTABLE
+BEGIN
+ ID_APP_ABOUT "Shows Program, Version, and Copyright Information.\nInfo"
+ ID_APP_EXIT "Quits the Application.\nQuit"
+END
+
+STRINGTABLE
+BEGIN
+ ID_EDIT_COPY "Copies the Selected Path into the Clipboard.\nCopy Path"
+END
+
+STRINGTABLE
+BEGIN
+ ID_VIEW_TOOLBAR "Shows/hides the Toolbar\nToolbar"
+ ID_VIEW_STATUS_BAR "Shows/hides the Statusbar.\nStatusbar"
+END
+
+STRINGTABLE
+BEGIN
+ AFX_IDS_SCSIZE "Change the window size"
+ AFX_IDS_SCMOVE "Change the window position"
+ AFX_IDS_SCMINIMIZE "Reduce the window to an icon"
+ AFX_IDS_SCMAXIMIZE "Enlarge the window to full size"
+ AFX_IDS_SCCLOSE "Close the application"
+END
+
+STRINGTABLE
+BEGIN
+ AFX_IDS_SCRESTORE "Restore the window to normal size"
+ AFX_IDS_SCTASKLIST "Activate Task List"
+END
+
+STRINGTABLE
+BEGIN
+ ID_FILE_REFRESHALL "Re-Reads the Whole Tree"
+ ID_CLEANUP_OPENINEXPLORER
+ "Opens an Explorer at the Selected Location.\nExplorer"
+ ID_TREEMAP_ZOOMIN "Enlarges the Treemap.\nZoom in"
+END
+
+STRINGTABLE
+BEGIN
+ ID_FILE_REFRESHSELECTED "Re-Reads the Selected Subtree"
+ ID_CLEANUP_OPENINCONSOLE
+ "Opens a Command Prompt at the Selected Location.\nCommand Prompt"
+ ID_CLEANUP_DELETETOTRASHBIN
+ "Moves the Selected Item to the Recycle Bin.\nDelete (to Recycle Bin)"
+ ID_CLEANUP_DELETE "Deletes the Selected Item (no way to undelete!).\nDelete (no way to undelete!)"
+ ID_CONFIGURE "Opens the Settings Dialog.\nConfigure"
+ ID_HELP_MANUAL "Opens the WinDirStat Online Help\nManual"
+END
+
+STRINGTABLE
+BEGIN
+ ID_TREEMAP_ZOOMOUT "Reduces the Treemap.\nZoom out"
+ ID_TREEMAP_SELECTPARENT "Selects the Current Item's Parent.\nSelect Parent"
+ ID_TREEMAP_HELPABOUTTREEMAPS
+ "Displays Help about Treemaps.\nHelp about Treemaps"
+ ID_VIEW_SHOWTREEMAP "Shows/hides the Treemap.\nTreemap"
+ ID_HELP_REPORTBUG "Composes a Bug/Feedback Mail.\nReport Bug/Feedback"
+END
+
+STRINGTABLE
+BEGIN
+ ID_REFRESHALL "Rescans the whole directory tree.\nRefresh All"
+ ID_REFRESHSELECTED "Rescans the selected subtree.\nRefresh Selected"
+ ID_CLEANUP_EMPTYRECYCLEBIN "Empties the Recycle Bin.\nEmpty Recycle Bin"
+ ID_VIEW_SHOWFREESPACE "Shows/hides the <Free Space> Item.\nShow Free Space"
+ ID_VIEW_SHOWUNKNOWN "Shows/hides the <Unknown> Item.\nShow Unknown"
+END
+
+STRINGTABLE
+BEGIN
+ ID_DUMMY_USERDEFINEDCLEANUP
+ "Calls up User definied Cleanup #0\nUser defined Cleanup"
+END
+
+STRINGTABLE
+BEGIN
+ ID_SENDMAILTOOWNER "Composes an e-mail report on the currently selected item.\nSend Mail"
+END
+
+STRINGTABLE
+BEGIN
+ ID_VIEW_SHOWFILETYPES "Shows/hides the Extension List.\nShow File Types"
+END
+
+STRINGTABLE
+BEGIN
+ ID_TREEMAP_RESELECTCHILD "Re-selects the child.\nReselect Child"
+ ID_CLEANUP_OPEN "Opens the selected item.\r\nOpen Item"
+ ID_CLEANUP_PROPERTIES "Show the properties of the selected item.\r\nShow Properties"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_RESOURCEVERSION "Resource Version 1"
+ IDS_ABOUT_ABOUTTEXTss "\r\nWinDirStat - Directory Statistics\r\n\r\n""Shows where all your disk space has gone\r\nand helps you clean it up.""\r\n\r\nRe-programmed for MS Windows by\r\nBernhard Seifert (mailto:%1!s!),\r\n\r\nbased on Stefan Hundhammer's KDE (Linux) program KDirStat\r\n(http://kdirstat.sourceforge.net).\r\n\r\nWinDirStat's home is http://%2!s!\r\n\r\nCopyright (c) 2003 Bernhard Seifert"
+ IDS_ABOUT_THANKSTOTEXT "\r\nStefan Hundhammer for his superb Linux tool KDirStat.\r\nUsing KDirStat (2.3.7) as a specification saved me a lot of time.\r\nhttp://kdirstat.sourceforge.net/\r\n\r\nThe authors of SequoiaView for showing just how useful treemaps really can be.\r\nhttp://www.win.tue.nl/sequoiaview/\r\n\r\nJarke J. van Wijk, Huub van de Wetering, Mark Bruls and Kees Huizing\r\nfor their papers about cushion treemaps and squarified treemaps.\r\nhttp://www.win.tue.nl/~vanwijk/\r\n\r\nBen Shneiderman for his ingenious idea of treemaps -\r\na truly intuitive way of visualizing tree contents.\r\nhttp://www.cs.umd.edu/hcil/treemap-history/\r\n\r\nMy colleagues for their feedback on the early releases of WinDirStat.\r\nhttp://www.daccord.net/\r\n"
+ IDS_ABOUT_ABOUT "About"
+ IDS_ABOUT_THANKSTO "Thanks To"
+ IDS_ABOUT_LICENSEAGREEMENT "License Agreement"
+ IDS_MYCOMPUTER "My Computer"
+ IDS_UDC_CONFIRMATIONss "You are going to call the user defined cleanup\r\n'%1!s!'\r\n\r\non '%2!s!'.\r\n\r\nContinue?"
+ IDS_RUDC_CONFIRMATIONss "You are going to call the recursive user defined cleanup\r\n'%1!s!'\r\n\r\non '%2!s!'.\r\n\r\nContinue?"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_THEDIRECTORYsDOESNOTEXIST "The directory '%1!s!' doesn't exist."
+ IDS_THEFILEsDOESNOTEXIST "The file '%1!s!' doesn't exist."
+ IDS_COULDNOTCREATEPROCESSssss
+ "Could not create process.\r\n\r\nApplication: '%1!s!',\r\nCommand Line: '%2!s!',\r\nWorking Directory: '%3!s!'\r\nError Message:\r\n%4!s!\r\n(Refreshing will not take place.)"
+ IDS_TREECOL_NAME "Name"
+ IDS_TREECOL_SUBTREEPERCENTAGE "Subtree Percentage"
+ IDS_TREECOL_PERCENTAGE "Percentage"
+ IDS_TREECOL_SIZE "Size"
+ IDS_TREECOL_ITEMS "Items"
+ IDS_TREECOL_FILES "Files"
+ IDS_TREECOL_SUBDIRS "Subdirs"
+ IDS_TREECOL_LASTCHANGE "Last Change"
+ IDS_PLEASECHECKYOURDISKUSAGE
+ "Please check your disk usage and clean up if you can. Thank you.\r\n\r\n"
+ IDS_DISKUSAGEREPORTGENERATEDBYWINDIRSTAT
+ "\r\n\r\nDisk usage report generated by WinDirStat.\r\n"
+ IDS__UNKNOWN_ "<unknown>"
+ IDS_FREESPACE_ITEM "<Free Space>"
+ IDS_UNKNOWN_ITEM "<Unknown>"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_FILES_ITEM "<Files>"
+ IDS_ONEREADJOB "[1 Read Job]"
+ IDS_sREADJOBS "[%1!s! Read Jobs]"
+ IDS_CANNOTOPENCLIPBOARD "Cannot open the clipboard."
+ IDS_CANNOTEMTPYCLIPBOARD "Cannot empty the clipboard."
+ IDS_CANNOTSETCLIPBAORDDATA "Cannot set clipboard data."
+ IDS_WINDIRSTAT_SETTINGS "WinDirStat - Settings"
+ IDS_SCANNING_ "Scanning "
+ IDS_EMPTYRECYCLEBIN "&Empty Recycle Bin"
+ IDS__ONEITEMss " (1 Item, %1!s!%2!s!)"
+ IDS__sITEMSss " (%1!s! Items, %2!s!%3!s!)"
+ IDS_UDCsCTRLd "%1!s!\tCtrl+%2!d!"
+ IDS_USERDEFINEDCLEANUP0 "User defined cleanup #0"
+ IDS_REPORT_DISKUSAGE "Disk Usage"
+ IDS_USERDEFINEDCLEANUPd "User defined cleanup #%1!d!"
+ IDS_POLICY_NOREFRESH "No refresh"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_POLICY_REFRESHTHISENTRY "Refresh this entry"
+ IDS_POLICY_REFRESHPARENT "Refresh this entry's parent"
+ IDS_BUGREPORTHINT "For a bug report, it's best if you describe the symptom, including the complete wording of the error message, and, if possible, the steps to reproduce the behavior."
+ IDS_FEEDBACKHINT "Feedback is always appreciated."
+ IDS_FROMsPLATFORMs "From: %1!s!. Platform: %2!s!.\r\n\r\n"
+ IDS_SEV_CRITICAL "Critical Bug"
+ IDS_SEV_GRAVE "Grave Bug"
+ IDS_SEV_NORMAL "Bug"
+ IDS_SEV_WISH "Wish"
+ IDS_SEV_FEEDBACK "Feedback"
+ IDS_DRIVECOL_NAME "Name"
+ IDS_DRIVECOL_TOTAL "Total"
+ IDS_DRIVECOL_FREE "Free"
+ IDS_DRIVECOL_GRAPH "Used/Total"
+ IDS_DRIVECOL_PERCENTUSED "Used/Total"
+ IDS_SELECTFOLDER "WinDirStat - Select Folder"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_EXTCOL_EXTENSION "Extension"
+ IDS_EXTCOL_COLOR "Color"
+ IDS_EXTCOL_BYTES "Bytes"
+ IDS_EXTCOL_FILES "Files"
+ IDS_EXTCOL_DESCRIPTION "Description"
+ IDS_RAMUSAGEs "RAM Usage: %1!s!"
+ IDS_HELPFILEsCOULDNOTBEFOUND
+ "The help file %1!s! could not be found.\r\nIt is expected to be in the same folder where windirstat.exe is.\r\nYou should have received it along with windirstat.exe.\r\nYou can download one from WinDirStat's home site (see About box)."
+ IDS_SUSPENDED_ "(suspended) "
+ IDS_SUSPEND "Suspend"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#include "afxres.rc" // Standard components
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/windirstat/windirstat.vcproj b/windirstat/windirstat.vcproj
new file mode 100644
index 0000000..ab72787
--- /dev/null
+++ b/windirstat/windirstat.vcproj
@@ -0,0 +1,551 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="windirstat"
+ ProjectGUID="{BD11B94C-6594-4477-9FDF-2E24447D1F14}"
+ RootNamespace="windirstat"
+ Keyword="MFCProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ TreatWChar_tAsBuiltInType="TRUE"
+ RuntimeTypeInfo="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="4"
+ WarnAsError="FALSE"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="htmlhelp.lib"
+ OutputFile="../../debug/$(ProjectName).exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1031"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="0"
+ TreatWChar_tAsBuiltInType="TRUE"
+ RuntimeTypeInfo="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="htmlhelp.lib"
+ OutputFile="../../release/$(ProjectName).exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1031"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Unicode Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ TreatWChar_tAsBuiltInType="TRUE"
+ RuntimeTypeInfo="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="4"
+ WarnAsError="FALSE"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="htmlhelp.lib"
+ OutputFile="../../debug/$(ProjectName)U.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1031"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Unicode Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="0"
+ TreatWChar_tAsBuiltInType="TRUE"
+ RuntimeTypeInfo="FALSE"
+ UsePrecompiledHeader="3"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="htmlhelp.lib"
+ OutputFile="../../release/windirstatU.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1031"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\aboutdlg.cpp">
+ </File>
+ <File
+ RelativePath=".\colorbutton.cpp">
+ </File>
+ <File
+ RelativePath=".\DeleteWarningDlg.cpp">
+ </File>
+ <File
+ RelativePath=".\dirstatdoc.cpp">
+ </File>
+ <File
+ RelativePath=".\dirstatview.cpp">
+ </File>
+ <File
+ RelativePath=".\getosplatformstring.cpp">
+ </File>
+ <File
+ RelativePath=".\globalhelpers.cpp">
+ </File>
+ <File
+ RelativePath=".\graphview.cpp">
+ </File>
+ <File
+ RelativePath=".\item.cpp">
+ </File>
+ <File
+ RelativePath=".\layout.cpp">
+ </File>
+ <File
+ RelativePath=".\mainframe.cpp">
+ </File>
+ <File
+ RelativePath=".\ModalApiShuttle.cpp">
+ </File>
+ <File
+ RelativePath=".\ModalSendMail.cpp">
+ </File>
+ <File
+ RelativePath=".\ModalShellApi.cpp">
+ </File>
+ <File
+ RelativePath=".\mountpoints.cpp">
+ </File>
+ <File
+ RelativePath=".\myimagelist.cpp">
+ </File>
+ <File
+ RelativePath=".\options.cpp">
+ </File>
+ <File
+ RelativePath=".\osspecific.cpp">
+ </File>
+ <File
+ RelativePath=".\ownerdrawnlistcontrol.cpp">
+ </File>
+ <File
+ RelativePath=".\pacman.cpp">
+ </File>
+ <File
+ RelativePath=".\PageCleanups.cpp">
+ </File>
+ <File
+ RelativePath=".\PageGeneral.cpp">
+ </File>
+ <File
+ RelativePath=".\PageTreelist.cpp">
+ </File>
+ <File
+ RelativePath=".\PageTreemap.cpp">
+ </File>
+ <File
+ RelativePath=".\ReportBugDlg.cpp">
+ </File>
+ <File
+ RelativePath=".\SelectDrivesDlg.cpp">
+ </File>
+ <File
+ RelativePath=".\sortinglistcontrol.cpp">
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\TreeListControl.cpp">
+ </File>
+ <File
+ RelativePath=".\typeview.cpp">
+ </File>
+ <File
+ RelativePath=".\windirstat.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\aboutdlg.h">
+ </File>
+ <File
+ RelativePath=".\colorbutton.h">
+ </File>
+ <File
+ RelativePath=".\DeleteWarningDlg.h">
+ </File>
+ <File
+ RelativePath=".\dirstatdoc.h">
+ </File>
+ <File
+ RelativePath=".\dirstatview.h">
+ </File>
+ <File
+ RelativePath=".\getosplatformstring.h">
+ </File>
+ <File
+ RelativePath=".\globalhelpers.h">
+ </File>
+ <File
+ RelativePath=".\graphview.h">
+ </File>
+ <File
+ RelativePath=".\helpmap.h">
+ </File>
+ <File
+ RelativePath=".\item.h">
+ </File>
+ <File
+ RelativePath=".\layout.h">
+ </File>
+ <File
+ RelativePath=".\mainframe.h">
+ </File>
+ <File
+ RelativePath=".\ModalApiShuttle.h">
+ </File>
+ <File
+ RelativePath=".\ModalSendMail.h">
+ </File>
+ <File
+ RelativePath=".\ModalShellApi.h">
+ </File>
+ <File
+ RelativePath=".\mountpoints.h">
+ </File>
+ <File
+ RelativePath=".\myimagelist.h">
+ </File>
+ <File
+ RelativePath=".\options.h">
+ </File>
+ <File
+ RelativePath=".\osspecific.h">
+ </File>
+ <File
+ RelativePath=".\ownerdrawnlistcontrol.h">
+ </File>
+ <File
+ RelativePath=".\pacman.h">
+ </File>
+ <File
+ RelativePath=".\PageCleanups.h">
+ </File>
+ <File
+ RelativePath=".\PageGeneral.h">
+ </File>
+ <File
+ RelativePath=".\PageTreelist.h">
+ </File>
+ <File
+ RelativePath=".\PageTreemap.h">
+ </File>
+ <File
+ RelativePath=".\ReportBugDlg.h">
+ </File>
+ <File
+ RelativePath=".\Resource.h">
+ </File>
+ <File
+ RelativePath=".\SelectDrivesDlg.h">
+ </File>
+ <File
+ RelativePath=".\selectobject.h">
+ </File>
+ <File
+ RelativePath=".\set.h">
+ </File>
+ <File
+ RelativePath=".\sortinglistcontrol.h">
+ </File>
+ <File
+ RelativePath=".\stdafx.h">
+ </File>
+ <File
+ RelativePath=".\TreeListControl.h">
+ </File>
+ <File
+ RelativePath=".\typeview.h">
+ </File>
+ <File
+ RelativePath=".\windirstat.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ <File
+ RelativePath=".\res\bitmap1.bmp">
+ </File>
+ <File
+ RelativePath=".\res\icon1.ico">
+ </File>
+ <File
+ RelativePath=".\res\license.txt">
+ </File>
+ <File
+ RelativePath=".\res\Toolbar.bmp">
+ </File>
+ <File
+ RelativePath=".\res\windirstat.manifest">
+ </File>
+ <File
+ RelativePath=".\windirstat.rc">
+ </File>
+ </Filter>
+ <Filter
+ Name="Common Files"
+ Filter="">
+ <File
+ RelativePath="..\common\commonhelpers.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\common\commonhelpers.h">
+ </File>
+ <File
+ RelativePath="..\common\cotaskmem.h">
+ </File>
+ <File
+ RelativePath="..\common\mdexceptions.h">
+ </File>
+ </Filter>
+ <File
+ RelativePath="..\README.txt">
+ </File>
+ <File
+ RelativePath="..\testplan.txt">
+ </File>
+ </Files>
+ <Globals>
+ <Global
+ Name="RESOURCE_FILE"
+ Value="windirstat.rc"/>
+ </Globals>
+</VisualStudioProject>