Updated with progress. Still far to go....
[reactos.git] / rosapps / winfile / listview.c
1 /*
2 * ReactOS winfile
3 *
4 * listview.c
5 *
6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #ifdef _MSC_VER
24 #include "stdafx.h"
25 #else
26 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
27 #include <windows.h>
28 #include <commctrl.h>
29 #include <stdlib.h>
30 #include <malloc.h>
31 #include <memory.h>
32 #include <tchar.h>
33 #include <process.h>
34 #include <stdio.h>
35 #endif
36
37 #include <shellapi.h>
38 //#include <winspool.h>
39 #include <windowsx.h>
40 #include <shellapi.h>
41 #include <ctype.h>
42 #include <assert.h>
43 #define ASSERT assert
44
45 #include "main.h"
46 #include "listview.h"
47 #include "dialogs.h"
48 #include "utils.h"
49 #include "run.h"
50 #include "trace.h"
51
52
53 ////////////////////////////////////////////////////////////////////////////////
54 // Global Variables:
55 //
56
57 extern HINSTANCE hInst;
58
59 static WNDPROC g_orgListWndProc;
60
61
62 ////////////////////////////////////////////////////////////////////////////////
63 // Local module support methods
64 //
65
66 static void init_output(HWND hWnd)
67 {
68 TCHAR b[16];
69 HFONT old_font;
70 HDC hdc = GetDC(hWnd);
71
72 if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, _T("1000"), 0, b, 16) > 4)
73 Globals.num_sep = b[1];
74 else
75 Globals.num_sep = _T('.');
76
77 old_font = SelectFont(hdc, Globals.hFont);
78 GetTextExtentPoint32(hdc, _T(" "), 1, &Globals.spaceSize);
79 SelectFont(hdc, old_font);
80 ReleaseDC(hWnd, hdc);
81 }
82
83 static void AddEntryToList(HWND hwndLV, int idx, Entry* entry)
84 {
85 LVITEM item;
86
87 item.mask = LVIF_TEXT | LVIF_PARAM;
88 item.iItem = 0;//idx;
89 item.iSubItem = 0;
90 item.state = 0;
91 item.stateMask = 0;
92 // item.pszText = entry->data.cFileName;
93 item.pszText = LPSTR_TEXTCALLBACK;
94 // item.cchTextMax = strlen(entry->data.cFileName);
95 item.cchTextMax = 0;
96 item.iImage = 0;
97 // item.iImage = I_IMAGECALLBACK;
98 item.lParam = (LPARAM)entry;
99 #if (_WIN32_IE >= 0x0300)
100 item.iIndent = 0;
101 #endif
102 ListView_InsertItem(hwndLV, &item);
103 }
104
105 // insert listctrl entries after index idx
106 static void InsertListEntries(HWND hWnd, Entry* entry, int idx)
107 {
108 ShowWindow(hWnd, SW_HIDE);
109
110 if (idx == -1) {
111 }
112 idx = 0;
113
114 for (; entry; entry = entry->next) {
115 #ifndef _LEFT_FILES
116 if (entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
117 continue;
118 #endif
119 //ListBox_InsertItemData(hWnd, idx, entry);
120 AddEntryToList(hWnd, idx, entry);
121 ++idx;
122 }
123 ShowWindow(hWnd, SW_SHOW);
124 }
125
126 #define MAX_LIST_COLUMNS 5
127 static int default_column_widths[MAX_LIST_COLUMNS] = { 175, 100, 100, 100, 70 };
128 static int column_alignment[MAX_LIST_COLUMNS] = { LVCFMT_LEFT, LVCFMT_RIGHT, LVCFMT_RIGHT, LVCFMT_RIGHT, LVCFMT_LEFT };
129
130 static void CreateListColumns(HWND hWndListView)
131 {
132 TCHAR szText[50];
133 int index;
134 LV_COLUMN lvC;
135
136 // Create columns.
137 lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
138 lvC.pszText = szText;
139
140 // Load the column labels from the resource file.
141 for (index = 0; index < MAX_LIST_COLUMNS; index++) {
142 lvC.iSubItem = index;
143 lvC.cx = default_column_widths[index];
144 lvC.fmt = column_alignment[index];
145 LoadString(hInst, IDS_LIST_COLUMN_FIRST + index, szText, sizeof(szText));
146 if (ListView_InsertColumn(hWndListView, index, &lvC) == -1) {
147 // TODO: handle failure condition...
148 break;
149 }
150 }
151 }
152
153 static HWND CreateListView(HWND hwndParent, int id)
154 {
155 RECT rcClient; // dimensions of client area
156 HWND hwndLV; // handle to list view control
157
158 // Get the dimensions of the parent window's client area, and create the list view control.
159 GetClientRect(hwndParent, &rcClient);
160 hwndLV = CreateWindowEx(0, WC_LISTVIEW, _T("List View"),
161 // WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT | LVS_NOCOLUMNHEADER,
162 WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT,
163 0, 0, rcClient.right, rcClient.bottom,
164 hwndParent, (HMENU)id, hInst, NULL);
165
166 // Initialize the image list, and add items to the control.
167 /*
168 if (!InitListViewImageLists(hwndLV) ||
169 !InitListViewItems(hwndLV, lpszPathName)) {
170 DestroyWindow(hwndLV);
171 return FALSE;
172 }
173 */
174 ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
175 CreateListColumns(hwndLV);
176
177 return hwndLV;
178 }
179
180 /*
181 int GetNumberFormat(
182 LCID Locale, // locale
183 DWORD dwFlags, // options
184 LPCTSTR lpValue, // input number string
185 CONST NUMBERFMT *lpFormat, // formatting information
186 LPTSTR lpNumberStr, // output buffer
187 int cchNumber // size of output buffer
188 );
189 */
190 /*
191 typedef struct _numberfmt {
192 UINT NumDigits;
193 UINT LeadingZero;
194 UINT Grouping;
195 LPTSTR lpDecimalSep;
196 LPTSTR lpThousandSep;
197 UINT NegativeOrder;
198 } NUMBERFMT, *LPNUMBERFMT;
199 */
200 /*
201 typedef struct _BY_HANDLE_FILE_INFORMATION {
202 DWORD dwFileAttributes;
203 FILETIME ftCreationTime;
204 FILETIME ftLastAccessTime;
205 FILETIME ftLastWriteTime;
206 DWORD dwVolumeSerialNumber;
207 DWORD nFileSizeHigh;
208 DWORD nFileSizeLow;
209 DWORD nNumberOfLinks;
210 DWORD nFileIndexHigh;
211 DWORD nFileIndexLow;
212 } BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION;
213
214 GetDriveTypeW
215 GetFileType
216 GetLocaleInfoW
217 GetNumberFormatW
218
219 BOOL FileTimeToLocalFileTime(
220 CONST FILETIME *lpFileTime, // UTC file time to convert
221 LPFILETIME lpLocalFileTime // converted file time
222 );
223
224 BOOL FileTimeToSystemTime(
225 CONST FILETIME *lpFileTime, // file time to convert
226 LPSYSTEMTIME lpSystemTime // receives system time
227 );
228 */
229
230 // OnGetDispInfo - processes the LVN_GETDISPINFO
231 // notification message.
232
233 static void OnGetDispInfo(NMLVDISPINFO* plvdi)
234 {
235 SYSTEMTIME SystemTime;
236 FILETIME LocalFileTime;
237 static TCHAR buffer[200];
238
239 // LVITEM* pItem = &(plvdi->item);
240 // Entry* entry = (Entry*)pItem->lParam;
241 Entry* entry = (Entry*)plvdi->item.lParam;
242 ASSERT(entry);
243
244 plvdi->item.pszText = NULL;
245
246 switch (plvdi->item.iSubItem) {
247 case 0:
248 plvdi->item.pszText = entry->data.cFileName;
249 // item.cchTextMax = strlen(entry->data.cFileName);
250 // plvdi->item.pszText = rgPetInfo[plvdi->item.iItem].szKind;
251 break;
252 case 1:
253 if (entry->bhfi_valid) {
254 NUMBERFMT numFmt;
255 memset(&numFmt, 0, sizeof(numFmt));
256 numFmt.NumDigits = 0;
257 numFmt.LeadingZero = 0;
258 numFmt.Grouping = 3;
259 numFmt.lpDecimalSep = _T(".");
260 numFmt.lpThousandSep = _T(",");
261 numFmt.NegativeOrder = 0;
262
263 //entry->bhfi.nFileSizeLow;
264 //entry->bhfi.nFileSizeHigh;
265 //entry->bhfi.ftCreationTime
266 wsprintf(buffer, _T("%u"), entry->bhfi.nFileSizeLow);
267 if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, buffer, &numFmt,
268 buffer + sizeof(buffer)/2, sizeof(buffer)/2)) {
269 plvdi->item.pszText = buffer + sizeof(buffer)/2;
270 } else {
271 plvdi->item.pszText = buffer;
272 }
273 } else {
274 plvdi->item.pszText = _T("unknown");
275 }
276 break;
277 case 2:
278 plvdi->item.pszText = _T("error");
279 if (FileTimeToLocalFileTime(&entry->bhfi.ftLastWriteTime, &LocalFileTime)) {
280 if (FileTimeToSystemTime(&LocalFileTime, &SystemTime)) {
281 if (GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &SystemTime, NULL, buffer, sizeof(buffer))) {
282 plvdi->item.pszText = buffer;
283 }
284 }
285 }
286 break;
287 case 3:
288 plvdi->item.pszText = _T("error");
289 if (FileTimeToLocalFileTime(&entry->bhfi.ftLastWriteTime, &LocalFileTime)) {
290 if (FileTimeToSystemTime(&LocalFileTime, &SystemTime)) {
291 // if (GetTimeFormat(UserDefaultLCID, 0, &SystemTime, NULL, buffer, sizeof(buffer))) {
292 if (GetTimeFormat(LOCALE_USER_DEFAULT, 0, &SystemTime, NULL, buffer, sizeof(buffer))) {
293 plvdi->item.pszText = buffer;
294 }
295 }
296 }
297 break;
298 case 4:
299 plvdi->item.pszText = _T("");
300 _tcscpy(buffer, _T(" "));
301
302 if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) _tcscat(buffer, _T("a")); else _tcscat(buffer, _T(" "));
303 if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) _tcscat(buffer, _T("c")); else _tcscat(buffer, _T(" "));
304 if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) _tcscat(buffer, _T("d")); else _tcscat(buffer, _T(" "));
305 if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) _tcscat(buffer, _T("e")); else _tcscat(buffer, _T(" "));
306 if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) _tcscat(buffer, _T("h")); else _tcscat(buffer, _T(" "));
307 if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) _tcscat(buffer, _T("n")); else _tcscat(buffer, _T(" "));
308 if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) _tcscat(buffer, _T("o")); else _tcscat(buffer, _T(" "));
309 if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) _tcscat(buffer, _T("r")); else _tcscat(buffer, _T(" "));
310 if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) _tcscat(buffer, _T("p")); else _tcscat(buffer, _T(" "));
311 if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) _tcscat(buffer, _T("f")); else _tcscat(buffer, _T(" "));
312 if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) _tcscat(buffer, _T("s")); else _tcscat(buffer, _T(" "));
313 if (entry->bhfi.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) _tcscat(buffer, _T("t")); else _tcscat(buffer, _T(" "));
314 plvdi->item.pszText = buffer;
315 break;
316 default:
317 _tcscpy(buffer, _T(" "));
318 plvdi->item.pszText = buffer;
319 break;
320 }
321 }
322 /*
323 FILE_ATTRIBUTE_ARCHIVE The file or directory is an archive file. Applications use this attribute to mark files for backup or removal.
324 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.
325 FILE_ATTRIBUTE_DIRECTORY The handle identifies a directory.
326 FILE_ATTRIBUTE_ENCRYPTED The file or directory is encrypted. For a file, this means that all data in the file is encrypted. For a directory, this means that encryption is the default for newly created files and subdirectories.
327 FILE_ATTRIBUTE_HIDDEN The file or directory is hidden. It is not included in an ordinary directory listing.
328 FILE_ATTRIBUTE_NORMAL The file has no other attributes. This attribute is valid only if used alone.
329 FILE_ATTRIBUTE_OFFLINE The file data is not immediately available. This attribute indicates that the file data has been physically moved to offline storage. This attribute is used by Remote Storage, the hierarchical storage management software in Windows 2000. Applications should not arbitrarily change this attribute.
330 FILE_ATTRIBUTE_READONLY The file or directory is read-only. Applications can read the file but cannot write to it or delete it. In the case of a directory, applications cannot delete it.
331 FILE_ATTRIBUTE_REPARSE_POINT The file has an associated reparse point.
332 FILE_ATTRIBUTE_SPARSE_FILE The file is a sparse file.
333 FILE_ATTRIBUTE_SYSTEM The file or directory is part of the operating system or is used exclusively by the operating system.
334 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.
335 */
336
337
338 // OnEndLabelEdit - processes the LVN_ENDLABELEDIT
339 // notification message.
340 // Returns TRUE if the label is changed, or FALSE otherwise.
341
342 static BOOL OnEndLabelEdit(NMLVDISPINFO* plvdi)
343 {
344 if (plvdi->item.iItem == -1)
345 return FALSE;
346
347 // Copy the new label text to the application-defined structure.
348 // lstrcpyn(rgPetInfo[plvdi->item.iItem].szKind, plvdi->item.pszText, 10);
349
350 return TRUE;
351 // To make a more robust application you should send an EM_LIMITTEXT
352 // message to the edit control to prevent the user from entering too
353 // many characters in the field.
354 }
355
356 /*
357 typedef struct _BY_HANDLE_FILE_INFORMATION {
358 DWORD dwFileAttributes;
359 FILETIME ftCreationTime;
360 FILETIME ftLastAccessTime;
361 FILETIME ftLastWriteTime;
362 DWORD dwVolumeSerialNumber;
363 DWORD nFileSizeHigh;
364 DWORD nFileSizeLow;
365 DWORD nNumberOfLinks;
366 DWORD nFileIndexHigh;
367 DWORD nFileIndexLow;
368 } BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION;
369 */
370 /*
371 typedef struct _WIN32_FIND_DATA {
372 DWORD dwFileAttributes;
373 FILETIME ftCreationTime;
374 FILETIME ftLastAccessTime;
375 FILETIME ftLastWriteTime;
376 DWORD nFileSizeHigh;
377 DWORD nFileSizeLow;
378 DWORD dwReserved0;
379 DWORD dwReserved1;
380 TCHAR cFileName[ MAX_PATH ];
381 TCHAR cAlternateFileName[ 14 ];
382 } WIN32_FIND_DATA, *PWIN32_FIND_DATA;
383 */
384
385 static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
386 {
387 Entry* pItem1 = (Entry*)lParam1;
388 Entry* pItem2 = (Entry*)lParam2;
389
390 if (pItem1 != NULL && pItem2 != NULL) {
391 switch (lParamSort) {
392 case ID_VIEW_SORT_BY_NAME:
393 return _tcscmp(pItem1->data.cFileName, pItem2->data.cFileName);
394 break;
395 case ID_VIEW_SORT_BY_TYPE:
396 // if (pItem1->bhfi.nFileSizeLow != pItem2->bhfi.nFileSizeLow) {
397 // return (pItem1->bhfi.nFileSizeLow < pItem2->bhfi.nFileSizeLow) ? -1 : 1;
398 // }
399 break;
400 case ID_VIEW_SORT_BY_SIZE:
401 if (pItem1->bhfi.nFileSizeLow != pItem2->bhfi.nFileSizeLow) {
402 return (pItem1->bhfi.nFileSizeLow < pItem2->bhfi.nFileSizeLow) ? -1 : 1;
403 }
404 break;
405 case ID_VIEW_SORT_BY_DATE:
406 return CompareFileTime(&pItem1->bhfi.ftLastWriteTime, &pItem2->bhfi.ftLastWriteTime);
407 break;
408 }
409 }
410 return 0;
411 }
412
413 static void CmdSortItems(HWND hWnd, UINT cmd)
414 {
415 CheckMenuItem(Globals.hMenuView, ID_VIEW_SORT_BY_NAME, MF_BYCOMMAND);
416 CheckMenuItem(Globals.hMenuView, ID_VIEW_SORT_BY_TYPE, MF_BYCOMMAND);
417 CheckMenuItem(Globals.hMenuView, ID_VIEW_SORT_BY_SIZE, MF_BYCOMMAND);
418 CheckMenuItem(Globals.hMenuView, ID_VIEW_SORT_BY_DATE, MF_BYCOMMAND);
419 ListView_SortItems(hWnd, &CompareFunc, cmd);
420 CheckMenuItem(Globals.hMenuView, cmd, MF_BYCOMMAND | MF_CHECKED);
421 }
422
423 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
424 {
425 UINT cmd = LOWORD(wParam);
426 //HWND hChildWnd;
427
428 if (1) {
429 switch (cmd) {
430 case ID_FILE_OPEN:
431 {
432 LVITEM item;
433 item.mask = LVIF_PARAM;
434 // UINT selected_count = ListView_GetSelectedCount(hWnd);
435
436 item.iItem = ListView_GetNextItem(hWnd, -1, LVNI_SELECTED);
437 if (item.iItem != -1) {
438 if (ListView_GetItem(hWnd, &item)) {
439 Entry* entry = (Entry*)item.lParam;
440 OpenTarget(hWnd, entry->data.cFileName);
441 }
442 }
443 }
444
445 break;
446 case ID_FILE_MOVE:
447 //OnFileMove(hWnd);
448 break;
449 case ID_FILE_COPY:
450 case ID_FILE_COPY_CLIPBOARD:
451 case ID_FILE_DELETE:
452 case ID_FILE_RENAME:
453 case ID_FILE_PROPERTIES:
454 case ID_FILE_COMPRESS:
455 case ID_FILE_UNCOMPRESS:
456 break;
457 case ID_FILE_RUN:
458 OnFileRun();
459 break;
460 case ID_FILE_PRINT:
461 case ID_FILE_ASSOCIATE:
462 case ID_FILE_CREATE_DIRECTORY:
463 break;
464 case ID_VIEW_SORT_BY_NAME:
465 case ID_VIEW_SORT_BY_TYPE:
466 case ID_VIEW_SORT_BY_SIZE:
467 case ID_VIEW_SORT_BY_DATE:
468 CmdSortItems(hWnd, cmd);
469 break;
470 default:
471 return FALSE;
472 }
473 }
474 return TRUE;
475 }
476
477 ////////////////////////////////////////////////////////////////////////////////
478
479 static LRESULT CALLBACK ListWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
480 {
481 ChildWnd* child = (ChildWnd*)GetWindowLong(GetParent(hWnd), GWL_USERDATA);
482 Pane* pane = (Pane*)GetWindowLong(hWnd, GWL_USERDATA);
483 ASSERT(child);
484
485 switch (message) {
486 /*
487 case WM_CREATE:
488 //CreateListView(hWnd);
489 return 0;
490 */
491 case WM_COMMAND:
492 if (!_CmdWndProc(hWnd, message, wParam, lParam)) {
493 return CallWindowProc(g_orgListWndProc, hWnd, message, wParam, lParam);
494 }
495 break;
496 case WM_DISPATCH_COMMAND:
497 return _CmdWndProc(hWnd, message, wParam, lParam);
498 break;
499 case WM_NOTIFY:
500 switch (((LPNMHDR)lParam)->code) {
501 case LVN_GETDISPINFO:
502 OnGetDispInfo((NMLVDISPINFO*)lParam);
503 break;
504 case NM_DBLCLK:
505 {
506 NMITEMACTIVATE* nmitem = (LPNMITEMACTIVATE)lParam;
507 LVHITTESTINFO info;
508
509 if (nmitem->hdr.hwndFrom != hWnd) break;
510 // if (nmitem->hdr.idFrom != IDW_LISTVIEW) break;
511 // if (nmitem->hdr.code != ???) break;
512 switch (nmitem->uKeyFlags) {
513 case LVKF_ALT: // The ALT key is pressed.
514 // properties dialog box ?
515 break;
516 case LVKF_CONTROL: // The CTRL key is pressed.
517 // run dialog box for providing parameters...
518 break;
519 case LVKF_SHIFT: // The SHIFT key is pressed.
520 break;
521 }
522 info.pt.x = nmitem->ptAction.x;
523 info.pt.y = nmitem->ptAction.y;
524 if (ListView_HitTest(hWnd, &info) != -1) {
525 LVITEM item;
526 item.mask = LVIF_PARAM;
527 item.iItem = info.iItem;
528 if (ListView_GetItem(hWnd, &item)) {
529 Entry* entry = (Entry*)item.lParam;
530 OpenTarget(hWnd, entry->data.cFileName);
531 }
532 }
533 }
534 break;
535
536 case LVN_ENDLABELEDIT:
537 return OnEndLabelEdit((NMLVDISPINFO*)lParam);
538 break;
539 default:
540 return CallWindowProc(g_orgListWndProc, hWnd, message, wParam, lParam);
541 }
542 // return 0;
543 break;
544 /*
545 case WM_SETFOCUS:
546 child->nFocusPanel = pane==&child->right? 1: 0;
547 ListBox_SetSel(hWnd, TRUE, 1);
548 //TODO: check menu items
549 break;
550 case WM_KEYDOWN:
551 if (wParam == VK_TAB) {
552 //TODO: SetFocus(Globals.hDriveBar)
553 SetFocus(child->nFocusPanel? child->left.hWnd: child->right.hWnd);
554 }
555 break;
556 */
557 default:
558 return CallWindowProc(g_orgListWndProc, hWnd, message, wParam, lParam);
559 break;
560 }
561 return 0;
562 }
563
564
565 void CreateListWnd(HWND parent, Pane* pane, int id, LPTSTR lpszPathName)
566 {
567 // static int s_init = 0;
568 Entry* entry = pane->root;
569
570 pane->treePane = 0;
571 #if 1
572 pane->hWnd = CreateListView(parent, id);
573 #else
574 pane->hWnd = CreateWindow(_T("ListBox"), _T(""), WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|
575 LBS_DISABLENOSCROLL|LBS_NOINTEGRALHEIGHT|LBS_OWNERDRAWFIXED|LBS_NOTIFY,
576 0, 0, 0, 0, parent, (HMENU)id, Globals.hInstance, 0);
577 #endif
578 SetWindowLong(pane->hWnd, GWL_USERDATA, (LPARAM)pane);
579 g_orgListWndProc = SubclassWindow(pane->hWnd, ListWndProc);
580 SendMessage(pane->hWnd, WM_SETFONT, (WPARAM)Globals.hFont, FALSE);
581
582 // insert entries into listbox
583 if (entry) {
584 InsertListEntries(pane->hWnd, entry, -1);
585 }
586
587 // calculate column widths
588 // if (!s_init) {
589 // s_init = 1;
590 // init_output(pane->hWnd);
591 // }
592 // calc_widths(pane, TRUE);
593 }
594
595 void RefreshList(HWND hWnd, Entry* entry)
596 {
597 if (hWnd != NULL) {
598 ListView_DeleteAllItems(hWnd);
599 if (entry != NULL) {
600 //TRACE("RefreshList(...) entry name: %s\n", entry->data.cFileName);
601 InsertListEntries(hWnd, entry, -1);
602 }
603 }
604 }
605
606 /*
607 Pane* pane = (Pane*)GetWindowLong(hWnd, GWL_USERDATA);
608 if (pane != NULL) {
609 // ListBox_RemoveAll(hWnd, TRUE, 1);
610 ListView_DeleteAllItems(pane->hWnd);
611 if (entry) {
612 InsertListEntries(pane->hWnd, entry, -1);
613 }
614 }
615 */
616