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>
52 ////////////////////////////////////////////////////////////////////////////////
56 BOOL bInMenuLoop
= FALSE
; // Tells us if we are in the menu loop
57 int nOldWidth
; // Holds the previous client area width
58 int nOldHeight
; // Holds the previous client area height
61 ////////////////////////////////////////////////////////////////////////////////
62 // Local module support methods
65 static void resize_frame_rect(HWND hWnd
, PRECT prect
)
70 if (IsWindowVisible(Globals
.hToolBar
)) {
71 SendMessage(Globals
.hToolBar
, WM_SIZE
, 0, 0);
72 GetClientRect(Globals
.hToolBar
, &rt
);
73 prect
->top
= rt
.bottom
+3;
74 prect
->bottom
-= rt
.bottom
+3;
76 if (IsWindowVisible(Globals
.hDriveBar
)) {
77 SendMessage(Globals
.hDriveBar
, WM_SIZE
, 0, 0);
78 GetClientRect(Globals
.hDriveBar
, &rt
);
79 new_top
= --prect
->top
+ rt
.bottom
+3;
80 MoveWindow(Globals
.hDriveBar
, 0, prect
->top
, rt
.right
, new_top
, TRUE
);
82 prect
->bottom
-= rt
.bottom
+2;
84 if (IsWindowVisible(Globals
.hStatusBar
)) {
86 // int parts[] = {300, 500};
87 // SendMessage(Globals.hStatusBar, WM_SIZE, 0, 0);
88 // SendMessage(Globals.hStatusBar, SB_SETPARTS, 2, (LPARAM)&parts);
89 GetClientRect(Globals
.hStatusBar
, &rt
);
90 prect
->bottom
-= rt
.bottom
;
92 MoveWindow(Globals
.hMDIClient
, prect
->left
-1,prect
->top
-1,prect
->right
+2,prect
->bottom
+1, TRUE
);
95 static void resize_frame(HWND hWnd
, int cx
, int cy
)
97 RECT rect
= {0, 0, cx
, cy
};
99 resize_frame_rect(hWnd
, &rect
);
102 void resize_frame_client(HWND hWnd
)
106 GetClientRect(hWnd
, &rect
);
107 resize_frame_rect(hWnd
, &rect
);
110 ////////////////////////////////////////////////////////////////////////////////
111 static HHOOK hcbthook
;
112 static ChildWnd
* newchild
= NULL
;
114 static LRESULT CALLBACK
CBTProc(int code
, WPARAM wParam
, LPARAM lParam
)
116 if (code
== HCBT_CREATEWND
&& newchild
) {
117 ChildWnd
* pChildWnd
= newchild
;
119 pChildWnd
->hWnd
= (HWND
)wParam
;
120 SetWindowLong(pChildWnd
->hWnd
, GWL_USERDATA
, (LPARAM
)pChildWnd
);
122 return CallNextHookEx(hcbthook
, code
, wParam
, lParam
);
127 BOOL FindChildWindow(int cmd)
129 TCHAR drv[_MAX_DRIVE];
130 LPCTSTR root = Globals.drives;
132 for(i = cmd - ID_DRIVE_FIRST; i--; root++)
135 if (activate_drive_window(root))
137 _tsplitpath(root, drv, 0, 0, 0);
138 if (!SetCurrentDirectory(drv)) {
139 display_error(hWnd, GetLastError());
146 static ChildWnd
* alloc_child_window(LPCTSTR path
)
148 TCHAR drv
[_MAX_DRIVE
+1], dir
[_MAX_DIR
], name
[_MAX_FNAME
], ext
[_MAX_EXT
];
149 ChildWnd
* pChildWnd
= (ChildWnd
*)malloc(sizeof(ChildWnd
));
150 Root
* root
= &pChildWnd
->root
;
153 memset(pChildWnd
, 0, sizeof(ChildWnd
));
154 pChildWnd
->left
.treePane
= TRUE
;
155 pChildWnd
->left
.visible_cols
= 0;
156 pChildWnd
->right
.treePane
= FALSE
;
157 #ifndef _NO_EXTENSIONS
158 pChildWnd
->right
.visible_cols
= COL_SIZE
|COL_DATE
|COL_TIME
|COL_ATTRIBUTES
|COL_INDEX
|COL_LINKS
;
160 pChildWnd
->right
.visible_cols
= COL_SIZE
|COL_DATE
|COL_TIME
|COL_ATTRIBUTES
;
162 pChildWnd
->pos
.length
= sizeof(WINDOWPLACEMENT
);
163 pChildWnd
->pos
.flags
= 0;
164 pChildWnd
->pos
.showCmd
= SW_SHOWNORMAL
;
165 pChildWnd
->pos
.rcNormalPosition
.left
= CW_USEDEFAULT
;
166 pChildWnd
->pos
.rcNormalPosition
.top
= CW_USEDEFAULT
;
167 pChildWnd
->pos
.rcNormalPosition
.right
= CW_USEDEFAULT
;
168 pChildWnd
->pos
.rcNormalPosition
.bottom
= CW_USEDEFAULT
;
169 pChildWnd
->nFocusPanel
= 0;
170 pChildWnd
->nSplitPos
= 200;
171 pChildWnd
->sortOrder
= SORT_NAME
;
172 pChildWnd
->header_wdths_ok
= FALSE
;
173 lstrcpy(pChildWnd
->szPath
, path
);
174 _tsplitpath(path
, drv
, dir
, name
, ext
);
175 #if !defined(_NO_EXTENSIONS) && defined(__linux__)
177 root
->drive_type
= GetDriveType(path
);
178 lstrcat(drv
, _T("/"));
179 lstrcpy(root
->volname
, _T("root fs"));
181 lstrcpy(root
->fs
, _T("unixfs"));
182 lstrcpy(root
->path
, _T("/"));
183 entry
= read_tree_unix(root
, path
, pChildWnd
->sortOrder
);
187 root
->drive_type
= GetDriveType(path
);
188 lstrcat(drv
, _T("\\"));
189 GetVolumeInformation(drv
, root
->volname
, _MAX_FNAME
, 0, 0, &root
->fs_flags
, root
->fs
, _MAX_DIR
);
190 lstrcpy(root
->path
, drv
);
191 entry
= read_tree_win(root
, path
, pChildWnd
->sortOrder
);
193 //@@lstrcpy(root->entry.data.cFileName, drv);
194 wsprintf(root
->entry
.data
.cFileName
, _T("%s - %s"), drv
, root
->fs
);
195 root
->entry
.data
.dwFileAttributes
= FILE_ATTRIBUTE_DIRECTORY
;
196 pChildWnd
->left
.root
= &root
->entry
;
197 set_curdir(pChildWnd
, entry
);
201 HWND
CreateChildWindow(int drv_id
)
203 //TCHAR drv[_MAX_DRIVE];
204 TCHAR path
[MAX_PATH
];
205 ChildWnd
* pChildWnd
= NULL
;
207 LPCTSTR root = Globals.drives;
209 for(i = cmd - ID_DRIVE_FIRST; i--; root++)
212 if (activate_drive_window(root))
214 _tsplitpath(root, drv, 0, 0, 0);
215 if (!SetCurrentDirectory(drv)) {
216 display_error(hWnd, GetLastError());
220 GetCurrentDirectory(MAX_PATH
, path
);
221 // pChildWnd = (ChildWnd*)malloc(sizeof(ChildWnd));
222 pChildWnd
= alloc_child_window(path
);
223 // if (!create_child_window(pChildWnd))
226 if (pChildWnd
!= NULL
) {
227 MDICREATESTRUCT mcs
= {
228 szChildClass
, path
, hInst
,
229 CW_USEDEFAULT
, CW_USEDEFAULT
,
230 CW_USEDEFAULT
, CW_USEDEFAULT
,
231 0/*style*/, 0/*lParam*/
233 hcbthook
= SetWindowsHookEx(WH_CBT
, CBTProc
, 0, GetCurrentThreadId());
234 newchild
= pChildWnd
;
235 pChildWnd
->hWnd
= (HWND
)SendMessage(Globals
.hMDIClient
, WM_MDICREATE
, 0, (LPARAM
)&mcs
);
236 UnhookWindowsHookEx(hcbthook
);
237 if (pChildWnd
->hWnd
== NULL
) {
239 newchild
= pChildWnd
= NULL
;
241 return pChildWnd
->hWnd
;
246 BOOL CALLBACK
CloseEnumProc(HWND hWnd
, LPARAM lParam
)
248 if (!GetWindow(hWnd
, GW_OWNER
)) {
249 SendMessage(GetParent(hWnd
), WM_MDIRESTORE
, (WPARAM
)hWnd
, 0);
250 if (SendMessage(hWnd
, WM_QUERYENDSESSION
, 0, 0)) {
251 SendMessage(GetParent(hWnd
), WM_MDIDESTROY
, (WPARAM
)hWnd
, 0);
257 void OnEnterMenuLoop(HWND hWnd
)
261 // Update the status bar pane sizes
263 SendMessage(Globals
.hStatusBar
, SB_SETPARTS
, 1, (long)&nParts
);
265 SendMessage(Globals
.hStatusBar
, SB_SETTEXT
, (WPARAM
)0, (LPARAM
)_T(""));
268 void OnExitMenuLoop(HWND hWnd
)
274 // Update the status bar pane sizes
275 GetClientRect(hWnd
, &rc
);
278 nParts
[2] = rc
.right
;
279 SendMessage(Globals
.hStatusBar
, SB_SETPARTS
, 3, (long)nParts
);
280 SendMessage(Globals
.hStatusBar
, SB_SETTEXT
, 0, (LPARAM
)_T(""));
281 SetupStatusBar(TRUE
);
285 void OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
289 strcpy(str
, TEXT(""));
290 if (nFlags
& MF_POPUP
) {
291 if (hSysMenu
!= GetMenu(hWnd
)) {
292 if (nItemID
== 2) nItemID
= 5;
295 if (LoadString(Globals
.hInstance
, nItemID
, str
, 100)) {
296 // load appropriate string
298 // first newline terminates actual string
299 lpsz
= _tcschr(lpsz
, '\n');
303 SendMessage(Globals
.hStatusBar
, SB_SETTEXT
, 0, (LPARAM
)str
);
307 static BOOL
activate_drive_window(LPCTSTR path
)
309 TCHAR drv1
[_MAX_DRIVE
], drv2
[_MAX_DRIVE
];
312 _tsplitpath(path
, drv1
, 0, 0, 0);
314 // search for a already open window for the same drive
315 for (child_wnd
= GetNextWindow(Globals
.hMDIClient
,GW_CHILD
);
317 child_wnd
= GetNextWindow(child_wnd
, GW_HWNDNEXT
)) {
318 ChildWnd
* pChildWnd
= (ChildWnd
*) GetWindowLong(child_wnd
, GWL_USERDATA
);
320 _tsplitpath(pChildWnd
->root
.path
, drv2
, 0, 0, 0);
321 if (!lstrcmpi(drv2
, drv1
)) {
322 SendMessage(Globals
.hMDIClient
, WM_MDIACTIVATE
, (WPARAM
)child_wnd
, 0);
323 if (IsMinimized(child_wnd
))
324 ShowWindow(child_wnd
, SW_SHOWNORMAL
);
332 static void toggle_child(HWND hWnd
, UINT cmd
, HWND hchild
)
334 BOOL vis
= IsWindowVisible(hchild
);
336 CheckMenuItem(Globals
.hMenuOptions
, cmd
, vis
?MF_BYCOMMAND
:MF_BYCOMMAND
|MF_CHECKED
);
337 ShowWindow(hchild
, vis
?SW_HIDE
:SW_SHOW
);
338 #ifndef _NO_EXTENSIONS
339 if (g_fullscreen
.mode
)
340 fullscreen_move(hWnd
);
342 resize_frame_client(hWnd
);
345 ////////////////////////////////////////////////////////////////////////////////
348 LRESULT CALLBACK
EnumNetConnectionsProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
355 DWORD dwScope, // scope of enumeration
356 DWORD dwType, // resource types to list
357 DWORD dwUsage, // resource usage to list
358 LPNETRESOURCE lpNetResource, // resource structure
359 LPHANDLE lphEnum // enumeration handle buffer
362 result = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_DISK, RESOURCEUSAGE_ALL, NULL, &EnumNetConnectionsProc);
365 DWORD
MapNetworkDrives(HWND hWnd
, BOOL connect
)
370 WNetConnectionDialog(hWnd
, RESOURCETYPE_DISK
);
372 WNetDisconnectDialog(hWnd
, RESOURCETYPE_DISK
);
376 NETRESOURCE netResouce
;
377 CONNECTDLGSTRUCT connectDlg
;
379 //netResouce.dwScope;
381 netResouce
.dwDisplayType
= 0;
382 //netResouce.dwUsage;
383 //netResouce.lpLocalName;
384 //netResouce.lpRemoteName;
385 //netResouce.lpComment;
386 //netResouce.lpProvider;
388 //connectDlg.cbStructure;
389 connectDlg
.hwndOwner
= hWnd
;
390 connectDlg
.lpConnRes
= &netResouce
;
391 //connectDlg.dwFlags;
392 //connectDlg.dwDevNum;
394 result
= WNetConnectionDialog1(&connectDlg
);
396 DISCDLGSTRUCT disconnectDlg
;
397 //disconnectDlg.cbStructure;
398 disconnectDlg
.hwndOwner
= hWnd
;
399 //disconnectDlg.lpLocalName;
400 //disconnectDlg.lpRemoteName;
401 //disconnectDlg.dwFlags;
402 result
= WNetDisconnectDialog1(&disconnectDlg
);
408 ////////////////////////////////////////////////////////////////////////////////
410 // FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
412 // PURPOSE: Processes WM_COMMAND messages for the main frame window.
416 LRESULT
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
418 UINT cmd
= LOWORD(wParam
);
420 // HWND hwndClient = (HWND)SendMessage(Globals.hMDIClient, WM_MDIGETACTIVE, 0, 0);
422 // if (SendMessage(hwndClient, WM_DISPATCH_COMMAND, wParam, lParam))
425 if (cmd
>= ID_DRIVE_FIRST
&& cmd
<= (ID_DRIVE_FIRST
+ 0xFF)) {
426 TCHAR drv
[_MAX_DRIVE
];
427 //TCHAR path[MAX_PATH];
428 //ChildWnd* pChildWnd;
429 LPCTSTR root
= Globals
.drives
;
431 for (i
= cmd
- ID_DRIVE_FIRST
; i
--; root
++)
434 if (activate_drive_window(root
))
436 _tsplitpath(root
, drv
, 0, 0, 0);
437 if (!SetCurrentDirectory(drv
)) {
438 display_error(hWnd
, GetLastError());
441 //GetCurrentDirectory(MAX_PATH, path); //@@ letztes Verzeichnis pro Laufwerk speichern
442 //CreateChildWindow(path);
443 CreateChildWindow(cmd
- ID_DRIVE_FIRST
);
445 // pChildWnd = alloc_child_window(path);
446 // if (!create_child_window(pChildWnd))
450 case ID_WINDOW_CLOSEALL
:
451 EnumChildWindows(Globals
.hMDIClient
, &CloseEnumProc
, 0);
453 case ID_WINDOW_CLOSE
:
454 hChildWnd
= (HWND
) SendMessage(Globals
.hMDIClient
, WM_MDIGETACTIVE
, 0, 0);
455 if (!SendMessage(hChildWnd
, WM_QUERYENDSESSION
, 0, 0))
456 SendMessage(Globals
.hMDIClient
, WM_MDIDESTROY
, (WPARAM
)hChildWnd
, 0);
459 SendMessage(hWnd
, WM_CLOSE
, 0, 0);
464 case ID_DISK_COPY_DISK
:
466 case ID_DISK_LABEL_DISK
:
468 case ID_DISK_FORMAT_DISK
:
469 // SHFormatDrive(hWnd, 0 /* A: */, SHFMT_ID_DEFAULT, 0);
471 UINT OldMode
= SetErrorMode(0); // Get the current Error Mode settings.
472 SetErrorMode(OldMode
& ~SEM_FAILCRITICALERRORS
); // Force O/S to handle
473 // Call SHFormatDrive here.
474 SHFormatDrive(hWnd
, 0 /* A: */, SHFMT_ID_DEFAULT
, 0);
475 SetErrorMode(OldMode
); // Put it back the way it was.
478 case ID_DISK_CONNECT_NETWORK_DRIVE
:
479 MapNetworkDrives(hWnd
, TRUE
);
481 case ID_DISK_DISCONNECT_NETWORK_DRIVE
:
482 MapNetworkDrives(hWnd
, FALSE
);
484 case ID_DISK_SHARE_AS
:
486 case ID_DISK_STOP_SHARING
:
488 case ID_DISK_SELECT_DRIVE
:
492 case ID_VIEW_BY_FILE_TYPE
:
494 struct ExecuteDialog dlg
= {{0}};
495 if (DialogBoxParam(Globals
.hInstance
, MAKEINTRESOURCE(IDD_DIALOG_VIEW_TYPE
), hWnd
, ViewFileTypeWndProc
, (LPARAM
)&dlg
) == IDOK
) {
499 case ID_OPTIONS_CONFIRMATION
:
501 struct ExecuteDialog dlg
= {{0}};
502 if (DialogBoxParam(Globals
.hInstance
, MAKEINTRESOURCE(IDD_DIALOG_OPTIONS_CONFIRMATON
), hWnd
, OptionsConfirmationWndProc
, (LPARAM
)&dlg
) == IDOK
) {
506 case ID_OPTIONS_FONT
:
508 case ID_OPTIONS_CUSTOMISE_TOOLBAR
:
510 case ID_OPTIONS_TOOLBAR
:
511 toggle_child(hWnd
, cmd
, Globals
.hToolBar
);
513 case ID_OPTIONS_DRIVEBAR
:
514 toggle_child(hWnd
, cmd
, Globals
.hDriveBar
);
516 case ID_OPTIONS_STATUSBAR
:
517 toggle_child(hWnd
, cmd
, Globals
.hStatusBar
);
519 case ID_OPTIONS_OPEN_NEW_WINDOW_ON_CONNECT
:
521 case ID_OPTIONS_MINIMISE_ON_USE
:
523 case ID_OPTIONS_SAVE_ON_EXIT
:
526 case ID_WINDOW_NEW_WINDOW
:
527 CreateChildWindow(-1);
529 // ChildWnd* pChildWnd = alloc_child_window(path);
530 // if (!create_child_window(pChildWnd))
534 case ID_WINDOW_CASCADE
:
535 SendMessage(Globals
.hMDIClient
, WM_MDICASCADE
, 0, 0);
537 case ID_WINDOW_TILE_HORZ
:
538 SendMessage(Globals
.hMDIClient
, WM_MDITILE
, MDITILE_HORIZONTAL
, 0);
540 case ID_WINDOW_TILE_VERT
:
541 SendMessage(Globals
.hMDIClient
, WM_MDITILE
, MDITILE_VERTICAL
, 0);
543 case ID_WINDOW_ARRANGE_ICONS
:
544 SendMessage(Globals
.hMDIClient
, WM_MDIICONARRANGE
, 0, 0);
546 case ID_HELP_CONTENTS
:
547 WinHelp(hWnd
, _T("winfile"), HELP_INDEX
, 0);
549 case ID_HELP_SEARCH_HELP
:
551 case ID_HELP_HOW_TO_USE_HELP
:
553 ShellAbout(hWnd
, szTitle
, "", LoadIcon(Globals
.hInstance
, (LPCTSTR
)IDI_WINFILE
));
561 if ((cmd<IDW_FIRST_CHILD || cmd>=IDW_FIRST_CHILD+0x100) &&
562 (cmd<SC_SIZE || cmd>SC_RESTORE)) {
563 MessageBox(hWnd, _T("Not yet implemented"), _T("Winefile"), MB_OK);
565 return DefFrameProc(hWnd, Globals.hMDIClient, message, wParam, lParam);
567 hChildWnd
= (HWND
)SendMessage(Globals
.hMDIClient
, WM_MDIGETACTIVE
, 0, 0);
568 if (IsWindow(hChildWnd
))
569 SendMessage(hChildWnd
, WM_COMMAND
, wParam
, lParam
);
571 return DefFrameProc(hWnd
, Globals
.hMDIClient
, message
, wParam
, lParam
);
578 ////////////////////////////////////////////////////////////////////////////////
580 // FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
582 // PURPOSE: Processes messages for the main frame window.
584 // WM_COMMAND - process the application menu
585 // WM_DESTROY - post a quit message and return
589 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
594 HMENU hMenuWindow
= GetSubMenu(Globals
.hMenuFrame
, GetMenuItemCount(Globals
.hMenuFrame
)-2);
595 CLIENTCREATESTRUCT ccs
= { hMenuWindow
, IDW_FIRST_CHILD
};
597 hMDIClient
= CreateWindow(_T("MDICLIENT"), NULL
,
598 WS_CHILD
|WS_CLIPCHILDREN
|WS_VISIBLE
,
600 hWnd
, (HMENU
)1, hInst
, &ccs
);
602 Globals
.hMDIClient
= CreateWindowEx(0, _T("MDICLIENT"), NULL
,
603 //WS_CHILD|WS_CLIPCHILDREN|WS_VSCROLL|WS_HSCROLL|WS_VISIBLE|WS_BORDER,
604 WS_CHILD
|WS_CLIPCHILDREN
|WS_VISIBLE
,
606 hWnd
, (HMENU
)0, hInst
, &ccs
);
611 return _CmdWndProc(hWnd
, message
, wParam
, lParam
);
614 resize_frame_client(hWnd
);
616 case WM_ENTERMENULOOP
:
617 OnEnterMenuLoop(hWnd
);
619 case WM_EXITMENULOOP
:
620 OnExitMenuLoop(hWnd
);
623 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
628 case WM_QUERYENDSESSION
:
630 SendMessage(hWnd
, WM_COMMAND
, ID_WINDOW_CLOSEALL
, 0);
631 if (GetWindow(Globals
.hMDIClient
, GW_CHILD
) != NULL
)
635 return DefFrameProc(hWnd
, Globals
.hMDIClient
, message
, wParam
, lParam
);