6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
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.
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.
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.
23 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
42 #define FRM_CALC_CLIENT 0xBF83
43 #define Frame_CalcFrameClient(hWnd, prt) ((BOOL)SNDMSG(hWnd, FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt))
46 void display_error(HWND hWnd
, DWORD error
)
50 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|FORMAT_MESSAGE_FROM_SYSTEM
,
51 0, error
, MAKELANGID(LANG_NEUTRAL
,SUBLANG_DEFAULT
), (PTSTR
)&msg
, 0, NULL
))
52 MessageBox(hWnd
, msg
, _T("Winefile"), MB_OK
);
54 MessageBox(hWnd
, _T("Error"), _T("Winefile"), MB_OK
);
59 static void read_directory_win(Entry
* parent
, LPCTSTR path
)
61 Entry
* entry
= (Entry
*) malloc(sizeof(Entry
));
62 int level
= parent
->level
+ 1;
65 //#ifndef _NO_EXTENSIONS
69 TCHAR buffer
[MAX_PATH
], *p
;
70 for(p
=buffer
; *path
; )
73 lstrcpy(p
, _T("\\*"));
75 memset(entry
, 0, sizeof(Entry
));
76 hFind
= FindFirstFile(buffer
, &entry
->data
);
78 if (hFind
!= INVALID_HANDLE_VALUE
) {
84 entry
->expanded
= FALSE
;
85 entry
->scanned
= FALSE
;
88 //#ifdef _NO_EXTENSIONS
90 // hide directory entry "."
91 if (entry
->data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
92 LPCTSTR name
= entry
->data
.cFileName
;
94 if (name
[0]=='.' && name
[1]=='\0')
98 entry
->unix_dir
= FALSE
;
99 entry
->bhfi_valid
= FALSE
;
101 lstrcpy(p
+1, entry
->data
.cFileName
);
103 hFile
= CreateFile(buffer
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
104 0, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
106 if (hFile
!= INVALID_HANDLE_VALUE
) {
107 if (GetFileInformationByHandle(hFile
, &entry
->bhfi
))
108 entry
->bhfi_valid
= TRUE
;
116 entry
= (Entry
*) malloc(sizeof(Entry
));
117 memset(entry
, 0, sizeof(Entry
));
121 } while(FindNextFile(hFind
, &entry
->data
));
131 parent
->scanned
= TRUE
;
135 void read_directory(Entry
* parent
, LPCTSTR path
, int sortOrder
)
137 TCHAR buffer
[MAX_PATH
];
142 #if !defined(_NO_EXTENSIONS) && defined(__linux__)
143 if (parent
->unix_dir
)
145 read_directory_unix(parent
, path
);
147 if (Globals
.prescan_node
) {
156 for(entry
=parent
->down
; entry
; entry
=entry
->next
)
157 if (entry
->data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
158 lstrcpy(d
, entry
->data
.cFileName
);
159 read_directory_unix(entry
, buffer
);
160 SortDirectory(entry
, sortOrder
);
167 read_directory_win(parent
, path
);
169 if (Globals
.prescan_node
) {
178 for(entry
=parent
->down
; entry
; entry
=entry
->next
)
179 if (entry
->data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
180 lstrcpy(d
, entry
->data
.cFileName
);
181 read_directory_win(entry
, buffer
);
182 SortDirectory(entry
, sortOrder
);
187 SortDirectory(parent
, sortOrder
);
190 // get full path of specified directory entry
191 void get_path(Entry
* dir
, PTSTR path
)
197 for(entry
=dir
; entry
; level
++) {
198 LPCTSTR name
= entry
->data
.cFileName
;
202 for(l
=0; *s
&& *s
!=_T('/') && *s
!=_T('\\'); s
++)
206 memmove(path
+l
+1, path
, len
*sizeof(TCHAR
));
207 memcpy(path
+1, name
, l
*sizeof(TCHAR
));
210 #ifndef _NO_EXTENSIONS
219 memmove(path
+l
, path
, len
*sizeof(TCHAR
));
220 memcpy(path
, name
, l
*sizeof(TCHAR
));
227 #ifndef _NO_EXTENSIONS
229 path
[len
++] = _T('/');
232 path
[len
++] = _T('\\');
235 path
[len
] = _T('\0');
239 #ifndef _NO_EXTENSIONS
241 void frame_get_clientspace(HWND hWnd
, PRECT prect
)
246 GetClientRect(hWnd
, prect
);
249 GetWindowPlacement(hWnd
, &wp
);
250 prect
->left
= prect
->top
= 0;
251 prect
->right
= wp
.rcNormalPosition
.right
-wp
.rcNormalPosition
.left
-
252 2*(GetSystemMetrics(SM_CXSIZEFRAME
)+GetSystemMetrics(SM_CXEDGE
));
253 prect
->bottom
= wp
.rcNormalPosition
.bottom
-wp
.rcNormalPosition
.top
-
254 2*(GetSystemMetrics(SM_CYSIZEFRAME
)+GetSystemMetrics(SM_CYEDGE
))-
255 GetSystemMetrics(SM_CYCAPTION
)-GetSystemMetrics(SM_CYMENUSIZE
);
257 if (IsWindowVisible(Globals
.hToolBar
)) {
258 GetClientRect(Globals
.hToolBar
, &rt
);
259 prect
->top
+= rt
.bottom
+2;
261 if (IsWindowVisible(Globals
.hDriveBar
)) {
262 GetClientRect(Globals
.hDriveBar
, &rt
);
263 prect
->top
+= rt
.bottom
+2;
265 if (IsWindowVisible(Globals
.hStatusBar
)) {
266 GetClientRect(Globals
.hStatusBar
, &rt
);
267 prect
->bottom
-= rt
.bottom
;
275 int is_exe_file(LPCTSTR ext
)
277 const static LPCTSTR executable_extensions
[] = {
282 #ifndef _NO_EXTENSIONS
289 TCHAR ext_buffer
[_MAX_EXT
];
294 for (s
= ext
+ 1, d
= ext_buffer
; (*d
= tolower(*s
)); s
++)
296 for (p
= executable_extensions
; *p
; p
++)
297 if (!_tcscmp(ext_buffer
, *p
))
302 int is_registered_type(LPCTSTR ext
)
309 void set_curdir(ChildWnd
* child
, Entry
* entry
)
311 TCHAR path
[MAX_PATH
];
313 // child->left.cur = entry;
314 // child->right.root = entry;
315 // child->right.cur = entry;
318 scan_entry(child
, entry
);
320 // ListBox_ResetContent(child->hListWnd);
321 // insert_entries(&child->right, entry->down, -1);
323 // RefreshList(child->hListWnd, entry);
325 // calc_widths(&child->right, FALSE);
326 //#ifndef _NO_EXTENSIONS
327 // set_header(&child->right);
330 RefreshList(child
->hListWnd
, entry
->down
);
332 get_path(entry
, path
);
333 lstrcpy(child
->szPath
, path
);
334 SetWindowText(child
->hWnd
, path
);
335 SetCurrentDirectory(path
);
339 // calculate prefered width for all visible columns
340 BOOL
calc_widths(Pane
* pane
, BOOL anyway
)
342 int col
, x
, cx
, spc
=3*Globals
.spaceSize
.cx
;
343 int entries
= ListBox_GetCount(pane
->hWnd
);
344 int orgWidths
[COLUMNS
];
345 int orgPositions
[COLUMNS
+1];
351 memcpy(orgWidths
, pane
->widths
, sizeof(orgWidths
));
352 memcpy(orgPositions
, pane
->positions
, sizeof(orgPositions
));
355 for (col
= 0; col
< COLUMNS
; col
++)
356 pane
->widths
[col
] = 0;
358 hdc
= GetDC(pane
->hWnd
);
359 hfontOld
= SelectFont(hdc
, Globals
.hFont
);
361 for (cnt
= 0; cnt
< entries
; cnt
++) {
363 Entry
* entry
= (Entry
*) ListBox_GetItemData(pane
->hWnd
, cnt
);
364 DRAWITEMSTRUCT dis
= {0/*CtlType*/, 0/*CtlID*/,
365 0/*itemID*/, 0/*itemAction*/, 0/*itemState*/,
366 pane
->hWnd
/*hwndItem*/, hdc
};
367 draw_item(pane
, &dis
, entry
, COLUMNS
);
370 SelectObject(hdc
, hfontOld
);
371 ReleaseDC(pane
->hWnd
, hdc
);
374 for ( col
= 0; col
< COLUMNS
; col
++) {
375 pane
->positions
[col
] = x
;
376 cx
= pane
->widths
[col
];
379 if (cx
< IMAGE_WIDTH
)
381 pane
->widths
[col
] = cx
;
385 pane
->positions
[COLUMNS
] = x
;
386 ListBox_SetHorizontalExtent(pane
->hWnd
, x
);
389 if (!memcmp(orgWidths
, pane
->widths
, sizeof(orgWidths
)))
392 // don't move, if only collapsing an entry
393 if (!anyway
&& pane
->widths
[0]<orgWidths
[0] &&
394 !memcmp(orgWidths
+1, pane
->widths
+1, sizeof(orgWidths
)-sizeof(int))) {
395 pane
->widths
[0] = orgWidths
[0];
396 memcpy(pane
->positions
, orgPositions
, sizeof(orgPositions
));
400 InvalidateRect(pane
->hWnd
, 0, TRUE
);
405 // calculate one prefered column width
407 void calc_single_width(Pane
* pane
, int col
)
411 int entries
= ListBox_GetCount(pane
->hWnd
);
415 pane
->widths
[col
] = 0;
416 hdc
= GetDC(pane
->hWnd
);
417 hfontOld
= SelectFont(hdc
, Globals
.hFont
);
418 for (cnt
= 0; cnt
< entries
; cnt
++) {
420 Entry
* entry
= (Entry
*) ListBox_GetItemData(pane
->hWnd
, cnt
);
421 DRAWITEMSTRUCT dis
= {0, 0, 0, 0, 0, pane
->hWnd
, hdc
};
422 draw_item(pane
, &dis
, entry
, col
);
425 SelectObject(hdc
, hfontOld
);
426 ReleaseDC(pane
->hWnd
, hdc
);
427 cx
= pane
->widths
[col
];
429 cx
+= 3*Globals
.spaceSize
.cx
;
430 if (cx
< IMAGE_WIDTH
)
433 pane
->widths
[col
] = cx
;
434 x
= pane
->positions
[col
] + cx
;
435 for(; col
<COLUMNS
; ) {
436 pane
->positions
[++col
] = x
;
437 x
+= pane
->widths
[col
];
439 ListBox_SetHorizontalExtent(pane
->hWnd
, x
);
443 #ifndef _NO_EXTENSIONS
445 static struct FullScreenParameters
{
453 BOOL
toggle_fullscreen(HWND hWnd
)
457 if ((g_fullscreen
.mode
=!g_fullscreen
.mode
)) {
458 GetWindowRect(hWnd
, &g_fullscreen
.orgPos
);
459 g_fullscreen
.wasZoomed
= IsZoomed(hWnd
);
461 Frame_CalcFrameClient(hWnd
, &rt
);
462 ClientToScreen(hWnd
, (LPPOINT
)&rt
.left
);
463 ClientToScreen(hWnd
, (LPPOINT
)&rt
.right
);
465 rt
.left
= g_fullscreen
.orgPos
.left
-rt
.left
;
466 rt
.top
= g_fullscreen
.orgPos
.top
-rt
.top
;
467 rt
.right
= GetSystemMetrics(SM_CXSCREEN
)+g_fullscreen
.orgPos
.right
-rt
.right
;
468 rt
.bottom
= GetSystemMetrics(SM_CYSCREEN
)+g_fullscreen
.orgPos
.bottom
-rt
.bottom
;
470 MoveWindow(hWnd
, rt
.left
, rt
.top
, rt
.right
-rt
.left
, rt
.bottom
-rt
.top
, TRUE
);
472 MoveWindow(hWnd
, g_fullscreen
.orgPos
.left
, g_fullscreen
.orgPos
.top
,
473 g_fullscreen
.orgPos
.right
-g_fullscreen
.orgPos
.left
,
474 g_fullscreen
.orgPos
.bottom
-g_fullscreen
.orgPos
.top
, TRUE
);
476 if (g_fullscreen
.wasZoomed
)
477 ShowWindow(hWnd
, WS_MAXIMIZE
);
480 return g_fullscreen
.mode
;
483 void fullscreen_move(HWND hWnd
)
486 GetWindowRect(hWnd
, &pos
);
488 Frame_CalcFrameClient(hWnd
, &rt
);
489 ClientToScreen(hWnd
, (LPPOINT
)&rt
.left
);
490 ClientToScreen(hWnd
, (LPPOINT
)&rt
.right
);
492 rt
.left
= pos
.left
-rt
.left
;
493 rt
.top
= pos
.top
-rt
.top
;
494 rt
.right
= GetSystemMetrics(SM_CXSCREEN
)+pos
.right
-rt
.right
;
495 rt
.bottom
= GetSystemMetrics(SM_CYSCREEN
)+pos
.bottom
-rt
.bottom
;
497 MoveWindow(hWnd
, rt
.left
, rt
.top
, rt
.right
-rt
.left
, rt
.bottom
-rt
.top
, TRUE
);