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.
26 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
37 //#include <shellapi.h>
51 ////////////////////////////////////////////////////////////////////////////////
55 BOOL bInMenuLoop
= FALSE
; // Tells us if we are in the menu loop
56 int nOldWidth
; // Holds the previous client area width
57 int nOldHeight
; // Holds the previous client area height
60 ////////////////////////////////////////////////////////////////////////////////
61 // Local module support methods
64 static void resize_frame_rect(HWND hWnd
, PRECT prect
)
69 if (IsWindowVisible(Globals
.hToolBar
)) {
70 SendMessage(Globals
.hToolBar
, WM_SIZE
, 0, 0);
71 GetClientRect(Globals
.hToolBar
, &rt
);
72 prect
->top
= rt
.bottom
+3;
73 prect
->bottom
-= rt
.bottom
+3;
75 if (IsWindowVisible(Globals
.hDriveBar
)) {
76 SendMessage(Globals
.hDriveBar
, WM_SIZE
, 0, 0);
77 GetClientRect(Globals
.hDriveBar
, &rt
);
78 new_top
= --prect
->top
+ rt
.bottom
+3;
79 MoveWindow(Globals
.hDriveBar
, 0, prect
->top
, rt
.right
, new_top
, TRUE
);
81 prect
->bottom
-= rt
.bottom
+2;
83 if (IsWindowVisible(Globals
.hStatusBar
)) {
85 // int parts[] = {300, 500};
86 // SendMessage(Globals.hStatusBar, WM_SIZE, 0, 0);
87 // SendMessage(Globals.hStatusBar, SB_SETPARTS, 2, (LPARAM)&parts);
88 GetClientRect(Globals
.hStatusBar
, &rt
);
89 prect
->bottom
-= rt
.bottom
;
91 MoveWindow(Globals
.hMDIClient
, prect
->left
-1,prect
->top
-1,prect
->right
+2,prect
->bottom
+1, TRUE
);
94 static void resize_frame(HWND hWnd
, int cx
, int cy
)
96 RECT rect
= {0, 0, cx
, cy
};
98 resize_frame_rect(hWnd
, &rect
);
101 void resize_frame_client(HWND hWnd
)
105 GetClientRect(hWnd
, &rect
);
106 resize_frame_rect(hWnd
, &rect
);
109 ////////////////////////////////////////////////////////////////////////////////
110 static HHOOK hcbthook
;
111 static ChildWnd
* newchild
= NULL
;
113 static LRESULT CALLBACK
CBTProc(int code
, WPARAM wParam
, LPARAM lParam
)
115 if (code
== HCBT_CREATEWND
&& newchild
) {
116 ChildWnd
* pChildWnd
= newchild
;
118 pChildWnd
->hWnd
= (HWND
)wParam
;
119 SetWindowLong(pChildWnd
->hWnd
, GWL_USERDATA
, (LPARAM
)pChildWnd
);
121 return CallNextHookEx(hcbthook
, code
, wParam
, lParam
);
126 BOOL FindChildWindow(int cmd)
128 TCHAR drv[_MAX_DRIVE];
129 LPCTSTR root = Globals.drives;
131 for(i = cmd - ID_DRIVE_FIRST; i--; root++)
134 if (activate_drive_window(root))
136 _tsplitpath(root, drv, 0, 0, 0);
137 if (!SetCurrentDirectory(drv)) {
138 display_error(hWnd, GetLastError());
145 static ChildWnd
* alloc_child_window(LPCTSTR path
)
147 TCHAR drv
[_MAX_DRIVE
+1], dir
[_MAX_DIR
], name
[_MAX_FNAME
], ext
[_MAX_EXT
];
148 ChildWnd
* pChildWnd
= (ChildWnd
*)malloc(sizeof(ChildWnd
));
149 Root
* root
= &pChildWnd
->root
;
152 memset(pChildWnd
, 0, sizeof(ChildWnd
));
153 pChildWnd
->left
.treePane
= TRUE
;
154 pChildWnd
->left
.visible_cols
= 0;
155 pChildWnd
->right
.treePane
= FALSE
;
156 #ifndef _NO_EXTENSIONS
157 pChildWnd
->right
.visible_cols
= COL_SIZE
|COL_DATE
|COL_TIME
|COL_ATTRIBUTES
|COL_INDEX
|COL_LINKS
;
159 pChildWnd
->right
.visible_cols
= COL_SIZE
|COL_DATE
|COL_TIME
|COL_ATTRIBUTES
;
161 pChildWnd
->pos
.length
= sizeof(WINDOWPLACEMENT
);
162 pChildWnd
->pos
.flags
= 0;
163 pChildWnd
->pos
.showCmd
= SW_SHOWNORMAL
;
164 pChildWnd
->pos
.rcNormalPosition
.left
= CW_USEDEFAULT
;
165 pChildWnd
->pos
.rcNormalPosition
.top
= CW_USEDEFAULT
;
166 pChildWnd
->pos
.rcNormalPosition
.right
= CW_USEDEFAULT
;
167 pChildWnd
->pos
.rcNormalPosition
.bottom
= CW_USEDEFAULT
;
168 pChildWnd
->nFocusPanel
= 0;
169 pChildWnd
->nSplitPos
= 200;
170 pChildWnd
->sortOrder
= SORT_NAME
;
171 pChildWnd
->header_wdths_ok
= FALSE
;
172 lstrcpy(pChildWnd
->szPath
, path
);
173 _tsplitpath(path
, drv
, dir
, name
, ext
);
174 #if !defined(_NO_EXTENSIONS) && defined(__linux__)
176 root
->drive_type
= GetDriveType(path
);
177 lstrcat(drv
, _T("/"));
178 lstrcpy(root
->volname
, _T("root fs"));
180 lstrcpy(root
->fs
, _T("unixfs"));
181 lstrcpy(root
->path
, _T("/"));
182 entry
= read_tree_unix(root
, path
, pChildWnd
->sortOrder
);
186 root
->drive_type
= GetDriveType(path
);
187 lstrcat(drv
, _T("\\"));
188 GetVolumeInformation(drv
, root
->volname
, _MAX_FNAME
, 0, 0, &root
->fs_flags
, root
->fs
, _MAX_DIR
);
189 lstrcpy(root
->path
, drv
);
190 entry
= read_tree_win(root
, path
, pChildWnd
->sortOrder
);
192 //@@lstrcpy(root->entry.data.cFileName, drv);
193 wsprintf(root
->entry
.data
.cFileName
, _T("%s - %s"), drv
, root
->fs
);
194 root
->entry
.data
.dwFileAttributes
= FILE_ATTRIBUTE_DIRECTORY
;
195 pChildWnd
->left
.root
= &root
->entry
;
196 set_curdir(pChildWnd
, entry
);
200 HWND
CreateChildWindow(int drv_id
)
202 //TCHAR drv[_MAX_DRIVE];
203 TCHAR path
[MAX_PATH
];
204 ChildWnd
* pChildWnd
= NULL
;
206 LPCTSTR root = Globals.drives;
208 for(i = cmd - ID_DRIVE_FIRST; i--; root++)
211 if (activate_drive_window(root))
213 _tsplitpath(root, drv, 0, 0, 0);
214 if (!SetCurrentDirectory(drv)) {
215 display_error(hWnd, GetLastError());
219 GetCurrentDirectory(MAX_PATH
, path
);
220 // pChildWnd = (ChildWnd*)malloc(sizeof(ChildWnd));
221 pChildWnd
= alloc_child_window(path
);
222 // if (!create_child_window(pChildWnd))
225 if (pChildWnd
!= NULL
) {
226 MDICREATESTRUCT mcs
= {
227 szChildClass
, path
, hInst
,
228 CW_USEDEFAULT
, CW_USEDEFAULT
,
229 CW_USEDEFAULT
, CW_USEDEFAULT
,
230 0/*style*/, 0/*lParam*/
232 hcbthook
= SetWindowsHookEx(WH_CBT
, CBTProc
, 0, GetCurrentThreadId());
233 newchild
= pChildWnd
;
234 pChildWnd
->hWnd
= (HWND
)SendMessage(Globals
.hMDIClient
, WM_MDICREATE
, 0, (LPARAM
)&mcs
);
235 UnhookWindowsHookEx(hcbthook
);
236 if (pChildWnd
->hWnd
== NULL
) {
238 newchild
= pChildWnd
= NULL
;
240 return pChildWnd
->hWnd
;
245 BOOL CALLBACK
CloseEnumProc(HWND hWnd
, LPARAM lParam
)
247 if (!GetWindow(hWnd
, GW_OWNER
)) {
248 SendMessage(GetParent(hWnd
), WM_MDIRESTORE
, (WPARAM
)hWnd
, 0);
249 if (SendMessage(hWnd
, WM_QUERYENDSESSION
, 0, 0)) {
250 SendMessage(GetParent(hWnd
), WM_MDIDESTROY
, (WPARAM
)hWnd
, 0);
256 void OnEnterMenuLoop(HWND hWnd
)
260 // Update the status bar pane sizes
262 SendMessage(Globals
.hStatusBar
, SB_SETPARTS
, 1, (long)&nParts
);
264 SendMessage(Globals
.hStatusBar
, SB_SETTEXT
, (WPARAM
)0, (LPARAM
)_T(""));
267 void OnExitMenuLoop(HWND hWnd
)
273 // Update the status bar pane sizes
274 GetClientRect(hWnd
, &rc
);
277 nParts
[2] = rc
.right
;
278 SendMessage(Globals
.hStatusBar
, SB_SETPARTS
, 3, (long)nParts
);
279 SendMessage(Globals
.hStatusBar
, SB_SETTEXT
, 0, (LPARAM
)_T(""));
280 SetupStatusBar(TRUE
);
284 void OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
288 strcpy(str
, TEXT(""));
289 if (nFlags
& MF_POPUP
) {
290 if (hSysMenu
!= GetMenu(hWnd
)) {
291 if (nItemID
== 2) nItemID
= 5;
294 if (LoadString(Globals
.hInstance
, nItemID
, str
, 100)) {
295 // load appropriate string
297 // first newline terminates actual string
298 lpsz
= _tcschr(lpsz
, '\n');
302 SendMessage(Globals
.hStatusBar
, SB_SETTEXT
, 0, (LPARAM
)str
);
306 static BOOL
activate_drive_window(LPCTSTR path
)
308 TCHAR drv1
[_MAX_DRIVE
], drv2
[_MAX_DRIVE
];
311 _tsplitpath(path
, drv1
, 0, 0, 0);
313 // search for a already open window for the same drive
314 for (child_wnd
= GetNextWindow(Globals
.hMDIClient
,GW_CHILD
);
316 child_wnd
= GetNextWindow(child_wnd
, GW_HWNDNEXT
)) {
317 ChildWnd
* pChildWnd
= (ChildWnd
*) GetWindowLong(child_wnd
, GWL_USERDATA
);
319 _tsplitpath(pChildWnd
->root
.path
, drv2
, 0, 0, 0);
320 if (!lstrcmpi(drv2
, drv1
)) {
321 SendMessage(Globals
.hMDIClient
, WM_MDIACTIVATE
, (WPARAM
)child_wnd
, 0);
322 if (IsMinimized(child_wnd
))
323 ShowWindow(child_wnd
, SW_SHOWNORMAL
);
331 static void toggle_child(HWND hWnd
, UINT cmd
, HWND hchild
)
333 BOOL vis
= IsWindowVisible(hchild
);
335 CheckMenuItem(Globals
.hMenuOptions
, cmd
, vis
?MF_BYCOMMAND
:MF_BYCOMMAND
|MF_CHECKED
);
336 ShowWindow(hchild
, vis
?SW_HIDE
:SW_SHOW
);
337 #ifndef _NO_EXTENSIONS
338 if (g_fullscreen
.mode
)
339 fullscreen_move(hWnd
);
341 resize_frame_client(hWnd
);
344 ////////////////////////////////////////////////////////////////////////////////
346 // FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
348 // PURPOSE: Processes WM_COMMAND messages for the main frame window.
352 LRESULT
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
354 UINT cmd
= LOWORD(wParam
);
356 // HWND hwndClient = (HWND)SendMessage(Globals.hMDIClient, WM_MDIGETACTIVE, 0, 0);
358 // if (SendMessage(hwndClient, WM_DISPATCH_COMMAND, wParam, lParam))
361 if (cmd
>= ID_DRIVE_FIRST
&& cmd
<= (ID_DRIVE_FIRST
+ 0xFF)) {
362 TCHAR drv
[_MAX_DRIVE
];
363 //TCHAR path[MAX_PATH];
364 //ChildWnd* pChildWnd;
365 LPCTSTR root
= Globals
.drives
;
367 for (i
= cmd
- ID_DRIVE_FIRST
; i
--; root
++)
370 if (activate_drive_window(root
))
372 _tsplitpath(root
, drv
, 0, 0, 0);
373 if (!SetCurrentDirectory(drv
)) {
374 display_error(hWnd
, GetLastError());
377 //GetCurrentDirectory(MAX_PATH, path); //@@ letztes Verzeichnis pro Laufwerk speichern
378 //CreateChildWindow(path);
379 CreateChildWindow(cmd
- ID_DRIVE_FIRST
);
381 // pChildWnd = alloc_child_window(path);
382 // if (!create_child_window(pChildWnd))
386 case ID_WINDOW_CLOSEALL
:
387 EnumChildWindows(Globals
.hMDIClient
, &CloseEnumProc
, 0);
389 case ID_WINDOW_CLOSE
:
390 hChildWnd
= (HWND
) SendMessage(Globals
.hMDIClient
, WM_MDIGETACTIVE
, 0, 0);
391 if (!SendMessage(hChildWnd
, WM_QUERYENDSESSION
, 0, 0))
392 SendMessage(Globals
.hMDIClient
, WM_MDIDESTROY
, (WPARAM
)hChildWnd
, 0);
395 SendMessage(hWnd
, WM_CLOSE
, 0, 0);
400 case ID_DISK_FORMAT_DISK
:
401 // SHFormatDrive(hWnd, 0 /* A: */, SHFMT_ID_DEFAULT, 0);
403 UINT OldMode
= SetErrorMode(0); // Get the current Error Mode settings.
404 SetErrorMode(OldMode
& ~SEM_FAILCRITICALERRORS
); // Force O/S to handle
405 // Call SHFormatDrive here.
406 SHFormatDrive(hWnd
, 0 /* A: */, SHFMT_ID_DEFAULT
, 0);
407 SetErrorMode(OldMode
); // Put it back the way it was.
410 case ID_OPTIONS_CONFIRMATION
:
412 // struct ExecuteDialog dlg = {{0}};
413 // if (DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_EXECUTE), hWnd, ExecuteDialogWndProg, (LPARAM)&dlg) == IDOK)
414 // ShellExecute(hWnd, _T("open")/*operation*/, dlg.cmd/*file*/, NULL/*parameters*/, NULL/*dir*/, dlg.cmdshow);
417 case ID_OPTIONS_FONT
:
419 case ID_OPTIONS_CUSTOMISE_TOOLBAR
:
421 case ID_OPTIONS_TOOLBAR
:
422 toggle_child(hWnd
, cmd
, Globals
.hToolBar
);
424 case ID_OPTIONS_DRIVEBAR
:
425 toggle_child(hWnd
, cmd
, Globals
.hDriveBar
);
427 case ID_OPTIONS_STATUSBAR
:
428 toggle_child(hWnd
, cmd
, Globals
.hStatusBar
);
430 case ID_OPTIONS_OPEN_NEW_WINDOW_ON_CONNECT
:
432 case ID_OPTIONS_MINIMISE_ON_USE
:
434 case ID_OPTIONS_SAVE_ON_EXIT
:
437 case ID_WINDOW_NEW_WINDOW
:
438 CreateChildWindow(-1);
440 // ChildWnd* pChildWnd = alloc_child_window(path);
441 // if (!create_child_window(pChildWnd))
445 case ID_WINDOW_CASCADE
:
446 SendMessage(Globals
.hMDIClient
, WM_MDICASCADE
, 0, 0);
448 case ID_WINDOW_TILE_HORZ
:
449 SendMessage(Globals
.hMDIClient
, WM_MDITILE
, MDITILE_HORIZONTAL
, 0);
451 case ID_WINDOW_TILE_VERT
:
452 SendMessage(Globals
.hMDIClient
, WM_MDITILE
, MDITILE_VERTICAL
, 0);
454 case ID_WINDOW_ARRANGE_ICONS
:
455 SendMessage(Globals
.hMDIClient
, WM_MDIICONARRANGE
, 0, 0);
457 case ID_HELP_CONTENTS
:
458 WinHelp(hWnd
, _T("winfile"), HELP_INDEX
, 0);
460 case ID_HELP_SEARCH_HELP
:
462 case ID_HELP_HOW_TO_USE_HELP
:
464 ShellAbout(hWnd
, szTitle
, "", LoadIcon(Globals
.hInstance
, (LPCTSTR
)IDI_WINFILE
));
472 if ((cmd<IDW_FIRST_CHILD || cmd>=IDW_FIRST_CHILD+0x100) &&
473 (cmd<SC_SIZE || cmd>SC_RESTORE)) {
474 MessageBox(hWnd, _T("Not yet implemented"), _T("Winefile"), MB_OK);
476 return DefFrameProc(hWnd, Globals.hMDIClient, message, wParam, lParam);
478 hChildWnd
= (HWND
)SendMessage(Globals
.hMDIClient
, WM_MDIGETACTIVE
, 0, 0);
479 if (IsWindow(hChildWnd
))
480 SendMessage(hChildWnd
, WM_COMMAND
, wParam
, lParam
);
482 return DefFrameProc(hWnd
, Globals
.hMDIClient
, message
, wParam
, lParam
);
489 ////////////////////////////////////////////////////////////////////////////////
491 // FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
493 // PURPOSE: Processes messages for the main frame window.
495 // WM_COMMAND - process the application menu
496 // WM_DESTROY - post a quit message and return
500 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
505 HMENU hMenuWindow
= GetSubMenu(Globals
.hMenuFrame
, GetMenuItemCount(Globals
.hMenuFrame
)-2);
506 CLIENTCREATESTRUCT ccs
= { hMenuWindow
, IDW_FIRST_CHILD
};
508 hMDIClient
= CreateWindow(_T("MDICLIENT"), NULL
,
509 WS_CHILD
|WS_CLIPCHILDREN
|WS_VISIBLE
,
511 hWnd
, (HMENU
)1, hInst
, &ccs
);
513 Globals
.hMDIClient
= CreateWindowEx(0, _T("MDICLIENT"), NULL
,
514 //WS_CHILD|WS_CLIPCHILDREN|WS_VSCROLL|WS_HSCROLL|WS_VISIBLE|WS_BORDER,
515 WS_CHILD
|WS_CLIPCHILDREN
|WS_VISIBLE
,
517 hWnd
, (HMENU
)0, hInst
, &ccs
);
522 return _CmdWndProc(hWnd
, message
, wParam
, lParam
);
525 resize_frame_client(hWnd
);
527 case WM_ENTERMENULOOP
:
528 OnEnterMenuLoop(hWnd
);
530 case WM_EXITMENULOOP
:
531 OnExitMenuLoop(hWnd
);
534 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
539 case WM_QUERYENDSESSION
:
541 SendMessage(hWnd
, WM_COMMAND
, ID_WINDOW_CLOSEALL
, 0);
542 if (GetWindow(Globals
.hMDIClient
, GW_CHILD
) != NULL
)
546 return DefFrameProc(hWnd
, Globals
.hMDIClient
, message
, wParam
, lParam
);