Updated with progress. Still far to go....
[reactos.git] / rosapps / winfile / listview.c
index 50f8942..bba8fd6 100644 (file)
 
 #include "main.h"
 #include "listview.h"
-//#include "entries.h"
+#include "dialogs.h"
 #include "utils.h"
-
+#include "run.h"
 #include "trace.h"
 
+
+////////////////////////////////////////////////////////////////////////////////
 // Global Variables:
+//
+
 extern HINSTANCE hInst;
 
+static WNDPROC g_orgListWndProc;
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Local module support methods
+//
 
 static void init_output(HWND hWnd)
 {
@@ -113,21 +123,25 @@ static void InsertListEntries(HWND hWnd, Entry* entry, int idx)
     ShowWindow(hWnd, SW_SHOW);
 }
 
+#define MAX_LIST_COLUMNS 5
+static int default_column_widths[MAX_LIST_COLUMNS] = { 175, 100, 100, 100, 70 };
+static int column_alignment[MAX_LIST_COLUMNS] = { LVCFMT_LEFT, LVCFMT_RIGHT, LVCFMT_RIGHT, LVCFMT_RIGHT, LVCFMT_LEFT };
+
 static void CreateListColumns(HWND hWndListView)
 {
-    char szText[50];
+    TCHAR szText[50];
     int index;
     LV_COLUMN lvC;
  
     // Create columns.
     lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
-    lvC.fmt = LVCFMT_LEFT;
-    lvC.cx = 175;
     lvC.pszText = szText;
 
     // Load the column labels from the resource file.
-    for (index = 0; index < 4; index++) {
+    for (index = 0; index < MAX_LIST_COLUMNS; index++) {
         lvC.iSubItem = index;
+        lvC.cx = default_column_widths[index];
+        lvC.fmt = column_alignment[index];
         LoadString(hInst, IDS_LIST_COLUMN_FIRST + index, szText, sizeof(szText));
         if (ListView_InsertColumn(hWndListView, index, &lvC) == -1) {
             // TODO: handle failure condition...
@@ -143,10 +157,9 @@ static HWND CreateListView(HWND hwndParent, int id)
 
     // Get the dimensions of the parent window's client area, and create the list view control. 
     GetClientRect(hwndParent, &rcClient); 
-    hwndLV = CreateWindowEx(0, WC_LISTVIEW, "List View"
+    hwndLV = CreateWindowEx(0, WC_LISTVIEW, _T("List View")
 //        WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT | LVS_NOCOLUMNHEADER, 
         WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT, 
-//        WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_LIST | LVS_NOCOLUMNHEADER,
         0, 0, rcClient.right, rcClient.bottom, 
         hwndParent, (HMENU)id, hInst, NULL); 
 
@@ -164,18 +177,72 @@ static HWND CreateListView(HWND hwndParent, int id)
     return hwndLV;
 } 
 
+/*
+int GetNumberFormat(
+  LCID Locale,                // locale
+  DWORD dwFlags,              // options
+  LPCTSTR lpValue,            // input number string
+  CONST NUMBERFMT *lpFormat,  // formatting information
+  LPTSTR lpNumberStr,         // output buffer
+  int cchNumber               // size of output buffer
+);
+ */
+/*
+typedef struct _numberfmt { 
+  UINT      NumDigits; 
+  UINT      LeadingZero; 
+  UINT      Grouping; 
+  LPTSTR    lpDecimalSep; 
+  LPTSTR    lpThousandSep; 
+  UINT      NegativeOrder; 
+} NUMBERFMT, *LPNUMBERFMT; 
+ */
+/*
+typedef struct _BY_HANDLE_FILE_INFORMATION {
+  DWORD    dwFileAttributes; 
+  FILETIME ftCreationTime; 
+  FILETIME ftLastAccessTime; 
+  FILETIME ftLastWriteTime; 
+  DWORD    dwVolumeSerialNumber; 
+  DWORD    nFileSizeHigh; 
+  DWORD    nFileSizeLow; 
+  DWORD    nNumberOfLinks; 
+  DWORD    nFileIndexHigh; 
+  DWORD    nFileIndexLow; 
+} BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION;  
+
+GetDriveTypeW
+GetFileType
+GetLocaleInfoW
+GetNumberFormatW
+
+BOOL FileTimeToLocalFileTime(
+  CONST FILETIME *lpFileTime,  // UTC file time to convert
+  LPFILETIME lpLocalFileTime   // converted file time
+);
+
+BOOL FileTimeToSystemTime(
+  CONST FILETIME *lpFileTime,  // file time to convert
+  LPSYSTEMTIME lpSystemTime    // receives system time
+);
+ */ 
+
 // OnGetDispInfo - processes the LVN_GETDISPINFO 
 // notification message. 
  
-void OnGetDispInfo(NMLVDISPINFO* plvdi)
+static void OnGetDispInfo(NMLVDISPINFO* plvdi)
 {
-    static char buffer[200];
+    SYSTEMTIME SystemTime;
+    FILETIME LocalFileTime;
+    static TCHAR buffer[200];
 
 //    LVITEM* pItem = &(plvdi->item);
 //    Entry* entry = (Entry*)pItem->lParam;
     Entry* entry = (Entry*)plvdi->item.lParam;
     ASSERT(entry);
 
+    plvdi->item.pszText = NULL;
+
     switch (plvdi->item.iSubItem) {
     case 0:
         plvdi->item.pszText = entry->data.cFileName; 
@@ -184,37 +251,74 @@ void OnGetDispInfo(NMLVDISPINFO* plvdi)
         break;
     case 1:
         if (entry->bhfi_valid) {
+            NUMBERFMT numFmt;
+            memset(&numFmt, 0, sizeof(numFmt));
+            numFmt.NumDigits = 0;
+            numFmt.LeadingZero = 0;
+            numFmt.Grouping = 3;
+            numFmt.lpDecimalSep = _T(".");
+            numFmt.lpThousandSep = _T(",");
+            numFmt.NegativeOrder = 0;
+
             //entry->bhfi.nFileSizeLow;
             //entry->bhfi.nFileSizeHigh;
-
             //entry->bhfi.ftCreationTime
-
-            wsprintf(buffer, "%u", entry->bhfi.nFileSizeLow);
-            plvdi->item.pszText = buffer;
+            wsprintf(buffer, _T("%u"), entry->bhfi.nFileSizeLow);
+            if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, buffer, &numFmt, 
+                    buffer + sizeof(buffer)/2, sizeof(buffer)/2)) {
+                plvdi->item.pszText = buffer + sizeof(buffer)/2;
+            } else {
+                plvdi->item.pszText = buffer;
+            }
         } else {
-            plvdi->item.pszText = "unknown";
+            plvdi->item.pszText = _T("unknown");
         }
         break;
     case 2:
-        plvdi->item.pszText = "TODO:";
+        plvdi->item.pszText = _T("error");
+        if (FileTimeToLocalFileTime(&entry->bhfi.ftLastWriteTime, &LocalFileTime)) {
+            if (FileTimeToSystemTime(&LocalFileTime, &SystemTime)) {
+                if (GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &SystemTime, NULL, buffer, sizeof(buffer))) {
+                    plvdi->item.pszText = buffer;
+                }
+            }
+        }
         break;
     case 3:
-            //entry->bhfi.dwFileAttributes
-//        plvdi->item.pszText = "rhsa";
-        strcpy(buffer, " ");
-        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) strcat(buffer, "a"); else strcat(buffer, " ");
-        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) strcat(buffer, "c"); else strcat(buffer, " ");
-        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) strcat(buffer, "d"); else strcat(buffer, " ");
-        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) strcat(buffer, "e"); else strcat(buffer, " ");
-        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) strcat(buffer, "h"); else strcat(buffer, " ");
-        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) strcat(buffer, "n"); else strcat(buffer, " ");
-        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) strcat(buffer, "o"); else strcat(buffer, " ");
-        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) strcat(buffer, "r"); else strcat(buffer, " ");
-        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) strcat(buffer, "p"); else strcat(buffer, " ");
-        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) strcat(buffer, "f"); else strcat(buffer, " ");
-        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) strcat(buffer, "s"); else strcat(buffer, " ");
-        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) strcat(buffer, "t"); else strcat(buffer, " ");
+        plvdi->item.pszText = _T("error");
+        if (FileTimeToLocalFileTime(&entry->bhfi.ftLastWriteTime, &LocalFileTime)) {
+            if (FileTimeToSystemTime(&LocalFileTime, &SystemTime)) {
+//                if (GetTimeFormat(UserDefaultLCID, 0, &SystemTime, NULL, buffer, sizeof(buffer))) {
+                if (GetTimeFormat(LOCALE_USER_DEFAULT, 0, &SystemTime, NULL, buffer, sizeof(buffer))) {
+                    plvdi->item.pszText = buffer;
+                }
+            }
+        }
+        break;
+    case 4:
+        plvdi->item.pszText = _T("");
+        _tcscpy(buffer, _T(" "));
+
+        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) _tcscat(buffer, _T("a")); else _tcscat(buffer, _T(" "));
+        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) _tcscat(buffer, _T("c")); else _tcscat(buffer, _T(" "));
+        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) _tcscat(buffer, _T("d")); else _tcscat(buffer, _T(" "));
+        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) _tcscat(buffer, _T("e")); else _tcscat(buffer, _T(" "));
+        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) _tcscat(buffer, _T("h")); else _tcscat(buffer, _T(" "));
+        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) _tcscat(buffer, _T("n")); else _tcscat(buffer, _T(" "));
+        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) _tcscat(buffer, _T("o")); else _tcscat(buffer, _T(" "));
+        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) _tcscat(buffer, _T("r")); else _tcscat(buffer, _T(" "));
+        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) _tcscat(buffer, _T("p")); else _tcscat(buffer, _T(" "));
+        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) _tcscat(buffer, _T("f")); else _tcscat(buffer, _T(" "));
+        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) _tcscat(buffer, _T("s")); else _tcscat(buffer, _T(" "));
+        if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) _tcscat(buffer, _T("t")); else _tcscat(buffer, _T(" "));
+        plvdi->item.pszText = buffer;
+        break;
+    default:
+        _tcscpy(buffer, _T(" "));
         plvdi->item.pszText = buffer;
+        break;
+    }
+} 
 /*
 FILE_ATTRIBUTE_ARCHIVE The file or directory is an archive file. Applications use this attribute to mark files for backup or removal. 
 FILE_ATTRIBUTE_COMPRESSED The file or directory is compressed. For a file, this means that all of the data in the file is compressed. For a directory, this means that compression is the default for newly created files and subdirectories. 
@@ -229,32 +333,13 @@ FILE_ATTRIBUTE_SPARSE_FILE The file is a sparse file.
 FILE_ATTRIBUTE_SYSTEM The file or directory is part of the operating system or is used exclusively by the operating system. 
 FILE_ATTRIBUTE_TEMPORARY The file is being used for temporary storage. File systems attempt to keep all the data in memory for quicker access, rather than flushing the data back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed.
  */
-        break;
-    default:
-        break;
-    }
-} 
-/*
-typedef struct _BY_HANDLE_FILE_INFORMATION {
-  DWORD    dwFileAttributes; 
-  FILETIME ftCreationTime; 
-  FILETIME ftLastAccessTime; 
-  FILETIME ftLastWriteTime; 
-  DWORD    dwVolumeSerialNumber; 
-  DWORD    nFileSizeHigh; 
-  DWORD    nFileSizeLow; 
-  DWORD    nNumberOfLinks; 
-  DWORD    nFileIndexHigh; 
-  DWORD    nFileIndexLow; 
-} BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION;  
- */ 
 
 
  // OnEndLabelEdit - processes the LVN_ENDLABELEDIT 
  // notification message. 
  // Returns TRUE if the label is changed, or FALSE otherwise. 
 
-BOOL OnEndLabelEdit(NMLVDISPINFO* plvdi)
+static BOOL OnEndLabelEdit(NMLVDISPINFO* plvdi)
 { 
     if (plvdi->item.iItem == -1) 
         return FALSE; 
@@ -268,9 +353,128 @@ BOOL OnEndLabelEdit(NMLVDISPINFO* plvdi)
     // many characters in the field. 
 } 
 
+/*
+typedef struct _BY_HANDLE_FILE_INFORMATION {
+  DWORD    dwFileAttributes; 
+  FILETIME ftCreationTime; 
+  FILETIME ftLastAccessTime; 
+  FILETIME ftLastWriteTime; 
+  DWORD    dwVolumeSerialNumber; 
+  DWORD    nFileSizeHigh; 
+  DWORD    nFileSizeLow; 
+  DWORD    nNumberOfLinks; 
+  DWORD    nFileIndexHigh; 
+  DWORD    nFileIndexLow; 
+} BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION;  
+ */
+/*
+typedef struct _WIN32_FIND_DATA {
+  DWORD    dwFileAttributes; 
+  FILETIME ftCreationTime; 
+  FILETIME ftLastAccessTime; 
+  FILETIME ftLastWriteTime; 
+  DWORD    nFileSizeHigh; 
+  DWORD    nFileSizeLow; 
+  DWORD    dwReserved0; 
+  DWORD    dwReserved1; 
+  TCHAR    cFileName[ MAX_PATH ]; 
+  TCHAR    cAlternateFileName[ 14 ]; 
+} WIN32_FIND_DATA, *PWIN32_FIND_DATA; 
+ */
+
+static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
+{
+    Entry* pItem1 = (Entry*)lParam1;
+    Entry* pItem2 = (Entry*)lParam2;
+
+    if (pItem1 != NULL && pItem2 != NULL) {
+               switch (lParamSort) {
+        case ID_VIEW_SORT_BY_NAME:
+            return _tcscmp(pItem1->data.cFileName, pItem2->data.cFileName);
+            break;
+        case ID_VIEW_SORT_BY_TYPE:
+//            if (pItem1->bhfi.nFileSizeLow != pItem2->bhfi.nFileSizeLow) {
+//                return (pItem1->bhfi.nFileSizeLow < pItem2->bhfi.nFileSizeLow) ? -1 : 1;
+//            }
+            break;
+        case ID_VIEW_SORT_BY_SIZE:
+            if (pItem1->bhfi.nFileSizeLow != pItem2->bhfi.nFileSizeLow) {
+                return (pItem1->bhfi.nFileSizeLow < pItem2->bhfi.nFileSizeLow) ? -1 : 1;
+            }
+            break;
+        case ID_VIEW_SORT_BY_DATE:
+            return CompareFileTime(&pItem1->bhfi.ftLastWriteTime, &pItem2->bhfi.ftLastWriteTime);
+            break;
+               }
+    }
+    return 0;
+}
+
+static void CmdSortItems(HWND hWnd, UINT cmd)
+{
+       CheckMenuItem(Globals.hMenuView, ID_VIEW_SORT_BY_NAME, MF_BYCOMMAND);
+       CheckMenuItem(Globals.hMenuView, ID_VIEW_SORT_BY_TYPE, MF_BYCOMMAND);
+       CheckMenuItem(Globals.hMenuView, ID_VIEW_SORT_BY_SIZE, MF_BYCOMMAND);
+       CheckMenuItem(Globals.hMenuView, ID_VIEW_SORT_BY_DATE, MF_BYCOMMAND);
+    ListView_SortItems(hWnd, &CompareFunc, cmd);
+    CheckMenuItem(Globals.hMenuView, cmd, MF_BYCOMMAND | MF_CHECKED);
+}
+
+static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+       UINT cmd = LOWORD(wParam);
+       //HWND hChildWnd;
+
+    if (1) {
+               switch (cmd) {
+        case ID_FILE_OPEN:
+            {
+            LVITEM item;
+            item.mask = LVIF_PARAM;
+//            UINT selected_count = ListView_GetSelectedCount(hWnd);
+
+            item.iItem = ListView_GetNextItem(hWnd, -1, LVNI_SELECTED);
+            if (item.iItem != -1) {
+                if (ListView_GetItem(hWnd, &item)) {
+                    Entry* entry = (Entry*)item.lParam;
+                    OpenTarget(hWnd, entry->data.cFileName);
+                }
+            }
+            }
+
+            break;
+        case ID_FILE_MOVE:
+            //OnFileMove(hWnd);
+            break;
+        case ID_FILE_COPY:
+        case ID_FILE_COPY_CLIPBOARD:
+        case ID_FILE_DELETE:
+        case ID_FILE_RENAME:
+        case ID_FILE_PROPERTIES:
+        case ID_FILE_COMPRESS:
+        case ID_FILE_UNCOMPRESS:
+            break;
+        case ID_FILE_RUN:
+            OnFileRun();
+            break;
+        case ID_FILE_PRINT:
+        case ID_FILE_ASSOCIATE:
+        case ID_FILE_CREATE_DIRECTORY:
+            break;
+        case ID_VIEW_SORT_BY_NAME:
+        case ID_VIEW_SORT_BY_TYPE:
+        case ID_VIEW_SORT_BY_SIZE:
+        case ID_VIEW_SORT_BY_DATE:
+            CmdSortItems(hWnd, cmd);
+            break;
+               default:
+            return FALSE;
+               }
+       }
+       return TRUE;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
-static WNDPROC g_orgListWndProc;
 
 static LRESULT CALLBACK ListWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
@@ -280,39 +484,85 @@ static LRESULT CALLBACK ListWndProc(HWND hWnd, UINT message, WPARAM wParam, LPAR
 
        switch (message) {
 /*
-        case WM_CREATE:
-            //CreateListView(hWnd);
-            return 0;
+    case WM_CREATE:
+        //CreateListView(hWnd);
+        return 0;
  */
-        case WM_NOTIFY:
-            switch (((LPNMHDR)lParam)->code) { 
-            case LVN_GETDISPINFO: 
-                OnGetDispInfo((NMLVDISPINFO*)lParam); 
-                break; 
-            case LVN_ENDLABELEDIT: 
-                return OnEndLabelEdit((NMLVDISPINFO*)lParam);
+       case WM_COMMAND:
+        if (!_CmdWndProc(hWnd, message, wParam, lParam)) {
+            return CallWindowProc(g_orgListWndProc, hWnd, message, wParam, lParam);
+        }
+               break;
+       case WM_DISPATCH_COMMAND:
+               return _CmdWndProc(hWnd, message, wParam, lParam);
+               break;
+    case WM_NOTIFY:
+        switch (((LPNMHDR)lParam)->code) { 
+        case LVN_GETDISPINFO: 
+            OnGetDispInfo((NMLVDISPINFO*)lParam); 
+            break; 
+        case NM_DBLCLK:
+            {
+            NMITEMACTIVATE* nmitem = (LPNMITEMACTIVATE)lParam;
+            LVHITTESTINFO info;
+
+            if (nmitem->hdr.hwndFrom != hWnd) break; 
+//            if (nmitem->hdr.idFrom != IDW_LISTVIEW) break; 
+//            if (nmitem->hdr.code != ???) break; 
+            switch (nmitem->uKeyFlags) {
+            case LVKF_ALT:     //  The ALT key is pressed.  
+                // properties dialog box ?
+                break;
+            case LVKF_CONTROL: //  The CTRL key is pressed.
+                // run dialog box for providing parameters...
+                break;
+            case LVKF_SHIFT:   //  The SHIFT key is pressed.   
                 break;
             }
-                       break;
-//            return 0;
+            info.pt.x = nmitem->ptAction.x;
+            info.pt.y = nmitem->ptAction.y;
+            if (ListView_HitTest(hWnd, &info) != -1) {
+                LVITEM item;
+                item.mask = LVIF_PARAM;
+                item.iItem = info.iItem;
+                if (ListView_GetItem(hWnd, &item)) {
+                    Entry* entry = (Entry*)item.lParam;
+                    OpenTarget(hWnd, entry->data.cFileName);
+                }
+            }
+            }
+            break;
 
+        case LVN_ENDLABELEDIT: 
+            return OnEndLabelEdit((NMLVDISPINFO*)lParam);
+            break;
+        default:
+            return CallWindowProc(g_orgListWndProc, hWnd, message, wParam, lParam);
+        }
+//        return 0;
+               break;
+/*
                case WM_SETFOCUS:
                        child->nFocusPanel = pane==&child->right? 1: 0;
                        ListBox_SetSel(hWnd, TRUE, 1);
                        //TODO: check menu items
                        break;
-
                case WM_KEYDOWN:
                        if (wParam == VK_TAB) {
                                //TODO: SetFocus(Globals.hDriveBar)
                                SetFocus(child->nFocusPanel? child->left.hWnd: child->right.hWnd);
                        }
+            break;
+ */
+        default:
+            return CallWindowProc(g_orgListWndProc, hWnd, message, wParam, lParam);
+            break;
        }
-       return CallWindowProc(g_orgListWndProc, hWnd, message, wParam, lParam);
+       return 0;
 }
 
 
-void CreateListWnd(HWND parent, Pane* pane, int id, LPSTR lpszPathName)
+void CreateListWnd(HWND parent, Pane* pane, int id, LPTSTR lpszPathName)
 {
 //     static int s_init = 0;
        Entry* entry = pane->root;
@@ -352,20 +602,6 @@ void RefreshList(HWND hWnd, Entry* entry)
         }
     }
 }
-/*
-typedef struct _WIN32_FIND_DATA {
-  DWORD    dwFileAttributes; 
-  FILETIME ftCreationTime; 
-  FILETIME ftLastAccessTime; 
-  FILETIME ftLastWriteTime; 
-  DWORD    nFileSizeHigh; 
-  DWORD    nFileSizeLow; 
-  DWORD    dwReserved0; 
-  DWORD    dwReserved1; 
-  TCHAR    cFileName[ MAX_PATH ]; 
-  TCHAR    cAlternateFileName[ 14 ]; 
-} WIN32_FIND_DATA, *PWIN32_FIND_DATA; 
- */
 
 /*
        Pane* pane = (Pane*)GetWindowLong(hWnd, GWL_USERDATA);