- Italian translation by Daniele Forsi (dforsi at gmail dot com)
[reactos.git] / reactos / base / shell / explorer / shell / mainframe.cpp
1 /*
2 * Copyright 2003, 2004, 2005 Martin Fuchs
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19
20 //
21 // Explorer clone
22 //
23 // mainframe.cpp
24 //
25 // Martin Fuchs, 23.07.2003
26 //
27
28
29 #include <precomp.h>
30
31 /* We can't include webchild.h here - otherwise MinGW produces errors like: "multiple definition of `QACONTAINERFLAGS'"
32 #include "webchild.h"
33 */
34 extern HWND create_webchildwindow(const WebChildWndInfo& info);
35
36 #include "../resource.h"
37
38 #include "../dialogs/settings.h" // for MdiSdiDlg
39
40 //#define _NO_REBAR
41
42 HWND MainFrameBase::Create(const ExplorerCmd& cmd)
43 {
44 HWND hFrame;
45
46 #ifndef _NO_MDI
47 if (cmd._mdi)
48 hFrame = MDIMainFrame::Create();
49 else
50 #endif
51 hFrame = SDIMainFrame::Create();
52
53 if (hFrame) {
54 HWND hwndOld = g_Globals._hMainWnd;
55
56 g_Globals._hMainWnd = hFrame;
57
58 if (hwndOld)
59 DestroyWindow(hwndOld);
60
61 ShowWindow(hFrame, cmd._cmdShow);
62 UpdateWindow(hFrame);
63
64 // Open the first child window after initializing the application
65 if (cmd.IsValidPath()) {
66 // We use the static s_path variable to store the path string in order
67 // to avoid accessing prematurely freed memory in the PostMessage handlers.
68 static String s_path = cmd._path;
69
70 PostMessage(hFrame, PM_OPEN_WINDOW, cmd._flags, (LPARAM)(LPCTSTR)s_path);
71 } else
72 PostMessage(hFrame, PM_OPEN_WINDOW, OWM_EXPLORE|OWM_DETAILS, 0);
73 }
74
75 return hFrame;
76 }
77
78
79 int MainFrameBase::OpenShellFolders(LPIDA pida, HWND hFrameWnd)
80 {
81 int cnt = 0;
82
83 LPCITEMIDLIST parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]);
84 ShellFolder folder(parent_pidl);
85 LOG(FmtString(TEXT("MainFrameBase::OpenShellFolders(): parent_pidl=%s"), (LPCTSTR)FileSysShellPath(parent_pidl)));
86
87 for(int i=pida->cidl; i>0; --i) {
88 LPCITEMIDLIST pidl = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[i]);
89
90 SFGAOF attribs = SFGAO_FOLDER;
91 HRESULT hr = folder->GetAttributesOf(1, &pidl, &attribs);
92
93 if (SUCCEEDED(hr))
94 if (attribs & SFGAO_FOLDER) {
95 try {
96 XMLPos explorer_options = g_Globals.get_cfg("general/explorer");
97
98 bool mdi = XMLBool(explorer_options, "mdi", true);
99 bool separateFolders = XMLBool(explorer_options, "separate-folders", true);
100
101 ShellPath pidl_abs = ShellPath(pidl).create_absolute_pidl(parent_pidl);
102 LOG(FmtString(TEXT("MainFrameBase::OpenShellFolders(): pidl_abs=%s"), (LPCTSTR)FileSysShellPath(pidl_abs)));
103
104 if (hFrameWnd && (mdi || !separateFolders)) {
105 int flags = OWM_PIDL;
106
107 if (separateFolders)
108 flags |= OWM_SEPARATE;
109
110 if (SendMessage(hFrameWnd, PM_OPEN_WINDOW, flags, (LPARAM)(LPCITEMIDLIST)pidl_abs))
111 ++cnt;
112 } else {
113 HWND hwnd;
114 #ifndef _NO_MDI
115 if (mdi)
116 hwnd = MDIMainFrame::Create(pidl_abs, 0);
117 else
118 #endif
119 hwnd = SDIMainFrame::Create(pidl_abs, 0);
120
121 if (hwnd)
122 ++cnt;
123 }
124 } catch(COMException& e) {
125 HandleException(e, g_Globals._hMainWnd);
126 }
127 }/*TEST
128 else { // !(attribs & SFGAO_FOLDER))
129 SHELLEXECUTEINFOA shexinfo;
130
131 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOA);
132 shexinfo.fMask = SEE_MASK_INVOKEIDLIST;
133 shexinfo.hwnd = NULL;
134 shexinfo.lpVerb = NULL;
135 shexinfo.lpFile = NULL;
136 shexinfo.lpParameters = NULL;
137 shexinfo.lpDirectory = NULL;
138 shexinfo.nShow = SW_NORMAL;
139 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
140
141 if (ShellExecuteExA(&shexinfo))
142 ++cnt;
143
144 ILFree((LPITEMIDLIST)shexinfo.lpIDList);
145 }*/
146 }
147
148 return cnt;
149 }
150
151
152 MainFrameBase::MainFrameBase(HWND hwnd)
153 : super(hwnd)
154 {
155 _himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0);
156
157 _hMenuFrame = GetMenu(hwnd);
158 _hMenuWindow = GetSubMenu(_hMenuFrame, GetMenuItemCount(_hMenuFrame)-3);
159
160 _menu_info._hMenuView = GetSubMenu(_hMenuFrame, 1);
161
162 _hAccel = LoadAccelerators(g_Globals._hInstance, MAKEINTRESOURCE(IDA_EXPLORER));
163
164
165 TBBUTTON toolbarBtns[] = {
166 #ifdef _NO_REBAR
167 {0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
168 #endif
169 {7, ID_GO_BACK, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
170 {8, ID_GO_FORWARD, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
171 {9, ID_GO_UP, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
172 {10, ID_GO_HOME, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
173 {11, ID_GO_SEARCH, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
174 {12, ID_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
175 {13, ID_STOP, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0}
176 };
177
178 _htoolbar = CreateToolbarEx(hwnd,
179 #ifndef _NO_REBAR
180 CCS_NOPARENTALIGN|CCS_NORESIZE|CCS_NODIVIDER|
181 #endif
182 WS_CHILD|TBSTYLE_FLAT|WS_VISIBLE, IDW_TOOLBAR, 2, g_Globals._hInstance, IDB_TOOLBAR,
183 toolbarBtns, sizeof(toolbarBtns)/sizeof(TBBUTTON),
184 16, 15, 16, 15, sizeof(TBBUTTON));
185
186 CheckMenuItem(_menu_info._hMenuView, ID_VIEW_TOOL_BAR, MF_BYCOMMAND|MF_CHECKED);
187
188
189 // address & command bar
190 WindowCanvas canvas(hwnd);
191 RECT rect = {0, 0, 0, 0};
192 DrawText(canvas, TEXT("My"), -1, &rect, DT_SINGLELINE|DT_NOPREFIX|DT_CALCRECT);
193 HFONT hfont = GetStockFont(DEFAULT_GUI_FONT);
194
195 _haddressedit = CreateWindow(TEXT("EDIT"), NULL, WS_CHILD|WS_VISIBLE, 0, 0, 0, rect.bottom,
196 hwnd, (HMENU)IDW_ADDRESSBAR, g_Globals._hInstance, 0);
197 SetWindowFont(_haddressedit, hfont, FALSE);
198 new EditController(_haddressedit);
199
200 _hcommandedit = CreateWindow(TEXT("EDIT"), TEXT("> "), WS_CHILD|WS_VISIBLE, 0, 0, 0, rect.bottom,
201 hwnd, (HMENU)IDW_COMMANDBAR, g_Globals._hInstance, 0);
202 SetWindowFont(_hcommandedit, hfont, FALSE);
203 new EditController(_hcommandedit);
204
205 /* CreateStatusWindow does not accept WS_BORDER
206 _hstatusbar = CreateWindowEx(WS_EX_NOPARENTNOTIFY, STATUSCLASSNAME, 0,
207 WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_BORDER|CCS_NODIVIDER, 0,0,0,0,
208 hwnd, (HMENU)IDW_STATUSBAR, g_Globals._hInstance, 0);*/
209
210 _hstatusbar = CreateStatusWindow(WS_CHILD|WS_VISIBLE, 0, hwnd, IDW_STATUSBAR);
211 CheckMenuItem(_menu_info._hMenuView, ID_VIEW_STATUSBAR, MF_BYCOMMAND|MF_CHECKED);
212
213 _hsidebar = CreateWindowEx(WS_EX_STATICEDGE, WC_TREEVIEW, TEXT("Sidebar"),
214 WS_CHILD|WS_TABSTOP|WS_BORDER|/*WS_VISIBLE|*/WS_CHILD|TVS_HASLINES|TVS_HASBUTTONS|TVS_SHOWSELALWAYS|TVS_INFOTIP,
215 -1, -1, 200, 0, _hwnd, (HMENU)IDW_SIDEBAR, g_Globals._hInstance, 0);
216
217 _himl_old = TreeView_SetImageList(_hsidebar, _himl, TVSIL_NORMAL);
218
219 CheckMenuItem(_menu_info._hMenuView, ID_VIEW_SIDE_BAR, MF_BYCOMMAND|MF_UNCHECKED/*MF_CHECKED*/);
220
221
222 // create rebar window to manage toolbar and drivebar
223 #ifndef _NO_REBAR
224 _hwndrebar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL,
225 WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|
226 RBS_VARHEIGHT|RBS_DBLCLKTOGGLE|
227 WS_BORDER|RBS_AUTOSIZE|RBS_BANDBORDERS,
228 0, 0, 0, 0, _hwnd, 0, g_Globals._hInstance, 0);
229
230 int btn_hgt = HIWORD(SendMessage(_htoolbar, TB_GETBUTTONSIZE, 0, 0));
231
232 REBARBANDINFO rbBand;
233
234 rbBand.cbSize = sizeof(REBARBANDINFO);
235 rbBand.fMask = RBBIM_TEXT|RBBIM_STYLE|RBBIM_CHILD|RBBIM_CHILDSIZE|RBBIM_SIZE;
236 #ifndef RBBS_HIDETITLE // missing in MinGW headers as of 25.02.2004
237 #define RBBS_HIDETITLE 0x400
238 #endif
239 rbBand.fStyle = RBBS_CHILDEDGE|RBBS_GRIPPERALWAYS|RBBS_HIDETITLE;
240
241 rbBand.cxMinChild = 0;
242 rbBand.cyMinChild = 0;
243 rbBand.cyChild = 0;
244 rbBand.cyMaxChild = 0;
245 rbBand.cyIntegral = btn_hgt;
246
247 rbBand.lpText = NULL;//TEXT("Toolbar");
248 rbBand.hwndChild = _htoolbar;
249 rbBand.cxMinChild = 0;
250 rbBand.cyMinChild = btn_hgt;
251 rbBand.cx = 284;
252 SendMessage(_hwndrebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
253 #endif
254 }
255
256
257 MainFrameBase::~MainFrameBase()
258 {
259 (void)TreeView_SetImageList(_hsidebar, _himl_old, TVSIL_NORMAL);
260 ImageList_Destroy(_himl);
261
262 // don't exit desktop when closing file manager window
263 if (!g_Globals._desktop_mode)
264 if (g_Globals._hMainWnd == _hwnd) // don't quit when switching between MDI and SDI mode
265 PostQuitMessage(0);
266 }
267
268
269 LRESULT MainFrameBase::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
270 {
271 LRESULT res;
272
273 if (ProcessMessage(nmsg, wparam, lparam, &res))
274 return res;
275 else
276 return super::WndProc(nmsg, wparam, lparam);
277 }
278
279 bool MainFrameBase::ProcessMessage(UINT nmsg, WPARAM wparam, LPARAM lparam, LRESULT* pres)
280 {
281 switch(nmsg) {
282 case PM_TRANSLATE_MSG:
283 *pres = TranslateMsg((MSG*)lparam);
284 return true;
285
286 case WM_SHOWWINDOW:
287 if (wparam) { // trigger child resizing after window creation - now we can succesfully call IsWindowVisible()
288 int height = SendMessage(_hwndrebar, RB_GETBARHEIGHT, 0, 0);
289 MoveWindow(_hwndrebar, 0, 0, LOWORD(lparam), height, TRUE);
290 resize_frame_client();
291 }
292 return false; // goto def;
293
294 case WM_CLOSE:
295 DestroyWindow(_hwnd);
296 g_Globals._hMainWnd = 0;
297 break;
298
299 case WM_DESTROY:
300 break;
301
302 case WM_SIZE: {
303 #ifdef _ROS_ ///@todo Work around to display rebar in ROS (with flickering) as long as the control isn't fixed
304 int height = SendMessage(_hwndrebar, RB_GETBARHEIGHT, 0, 0);
305 MoveWindow(_hwndrebar, 0, 0, LOWORD(lparam), height, TRUE);
306 #else
307 resize_frame(LOWORD(lparam), HIWORD(lparam));
308 SendMessage(_hwndrebar, WM_SIZE, 0, 0);
309 #endif
310 break;} // do not pass message to DefFrameProc
311
312 case WM_GETMINMAXINFO: {
313 LPMINMAXINFO lpmmi = (LPMINMAXINFO)lparam;
314
315 lpmmi->ptMaxTrackSize.x <<= 1;/*2*GetSystemMetrics(SM_CXSCREEN) / SM_CXVIRTUALSCREEN */
316 lpmmi->ptMaxTrackSize.y <<= 1;/*2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN */
317 break;}
318
319 case PM_FRM_CALC_CLIENT:
320 frame_get_clientspace((PRECT)lparam);
321 *pres = TRUE;
322 return true;
323
324 case PM_FRM_GET_MENUINFO:
325 *pres = (LPARAM)&_menu_info;
326 return true;
327
328 case PM_GET_CONTROLWINDOW:
329 if (wparam == FCW_STATUS) {
330 *pres = (LRESULT)(HWND)_hstatusbar;
331 return true;
332 }
333 break;
334
335 case PM_SETSTATUSTEXT:
336 SendMessage(_hstatusbar, SB_SETTEXT, 0, lparam);
337 break;
338
339 case PM_URL_CHANGED:
340 SetWindowText(_haddressedit, (LPCTSTR)lparam);
341 break;
342
343 default:
344 return false;
345 }
346
347 *pres = 0;
348 return true;
349 }
350
351 BOOL MainFrameBase::TranslateMsg(MSG* pmsg)
352 {
353 if (TranslateAccelerator(_hwnd, _hAccel, pmsg))
354 return TRUE;
355
356 return FALSE;
357 }
358
359
360 int MainFrameBase::Command(int id, int code)
361 {
362 CONTEXT("MainFrameBase::Command()");
363
364 switch(id) {
365 case ID_FILE_EXIT:
366 SendMessage(_hwnd, WM_CLOSE, 0, 0);
367 break;
368
369 case ID_VIEW_TOOL_BAR:
370 toggle_child(_hwnd, id, _htoolbar, 0);
371 break;
372
373 case ID_VIEW_STATUSBAR:
374 toggle_child(_hwnd, id, _hstatusbar);
375 break;
376
377 case ID_VIEW_SIDE_BAR:
378 // lazy initialization
379 if (!TreeView_GetCount(_hsidebar))
380 FillBookmarks();
381
382 toggle_child(_hwnd, id, _hsidebar);
383 break;
384
385 case ID_EXECUTE: {
386 ExecuteDialog dlg = {{0}, 0};
387
388 if (DialogBoxParam(g_Globals._hInstance, MAKEINTRESOURCE(IDD_EXECUTE), _hwnd, ExecuteDialog::WndProc, (LPARAM)&dlg) == IDOK) {
389 CONTEXT("ID_EXECUTE - ShellExecute()");
390
391 HINSTANCE hinst = ShellExecute(_hwnd, NULL/*operation*/, dlg.cmd/*file*/, NULL/*parameters*/, NULL/*dir*/, dlg.cmdshow);
392
393 if ((int)hinst <= 32)
394 display_error(_hwnd, GetLastError());
395 }
396 break;}
397
398 case ID_HELP:
399 WinHelp(_hwnd, TEXT("explorer")/*file explorer.hlp*/, HELP_INDEX, 0);
400 break;
401
402 case ID_VIEW_FULLSCREEN:
403 CheckMenuItem(_menu_info._hMenuView, id, toggle_fullscreen()?MF_CHECKED:0);
404 break;
405
406 case ID_TOOLS_OPTIONS:
407 Dialog::DoModal(IDD_MDI_SDI, WINDOW_CREATOR(MdiSdiDlg), _hwnd);
408 break;
409
410 case ID_ABOUT_WINDOWS:
411 ShellAbout(_hwnd, ResString(IDS_TITLE), NULL, 0);
412 break;
413
414 case ID_ABOUT_EXPLORER:
415 explorer_about(_hwnd);
416 break;
417
418 case ID_EXPLORER_FAQ:
419 launch_file(_hwnd, TEXT("http://www.sky.franken.de/explorer/"), SW_SHOW);
420 break;
421
422 case IDW_ADDRESSBAR:
423 if (code == 1) {
424 TCHAR url[BUFFER_LEN];
425
426 if (GetWindowText(_haddressedit, url, BUFFER_LEN))
427 go_to(url, false);
428 }
429 break;
430
431 case IDW_COMMANDBAR:
432 if (code == 1)
433 ExecuteCommandbar(NULL);
434 break;
435
436 default:
437 return 1; // no command handlers in Window::Command()
438 }
439
440 return 0;
441 }
442
443
444 void MainFrameBase::ExecuteCommandbar(LPCTSTR dir)
445 {
446 TCHAR cmd[BUFFER_LEN];
447
448 if (GetWindowText(_hcommandedit, cmd, BUFFER_LEN)) {
449 CONTEXT("ExecuteCommandbar - ShellExecute()");
450
451 // remove command prompt from 'cmd' string
452 LPCTSTR p = cmd;
453
454 if (*p == '>')
455 ++p;
456
457 while(*p == ' ')
458 ++p;
459
460 if (dir) {
461 // remove "file://" from directory URL
462 if (!_tcsnicmp(dir, TEXT("file://"), 7))
463 dir += 7;
464 }
465
466 ///@todo use SHGetFileInfo() with SHGFI_EXETYPE flag to determine EXE type and open console window
467
468 HINSTANCE hinst = ShellExecute(_hwnd, NULL, p, NULL, dir, SW_SHOWNORMAL);
469
470 if ((int)hinst <= 32)
471 display_error(_hwnd, GetLastError());
472 }
473 }
474
475
476 int MainFrameBase::Notify(int id, NMHDR* pnmh)
477 {
478 switch(pnmh->code) {
479 // resize children windows when the rebar size changes
480
481 case RBN_AUTOSIZE:
482 resize_frame_client();
483 break;
484
485 case TVN_GETINFOTIP: {
486 NMTVGETINFOTIP* pnmgit = (NMTVGETINFOTIP*)pnmh;
487
488 if (pnmgit->lParam) {
489 const BookmarkNode& node = *(BookmarkNode*)pnmgit->lParam;
490
491 if (node._type == BookmarkNode::BMNT_FOLDER) {
492 // display tooltips for bookmark folders
493 if (!node._pfolder->_description.empty())
494 lstrcpyn(pnmgit->pszText, node._pfolder->_description.c_str(), pnmgit->cchTextMax);
495 } else if (node._type == BookmarkNode::BMNT_BOOKMARK) {
496 // display tooltips for bookmark folders
497 String txt = node._pbookmark->_description;
498
499 if (!node._pbookmark->_url.empty()) {
500 if (!txt.empty())
501 txt += TEXT(" - ");
502
503 txt += node._pbookmark->_url;
504 }
505
506 lstrcpyn(pnmgit->pszText, txt.c_str(), pnmgit->cchTextMax);
507 }
508 }
509 break;}
510
511 case NM_DBLCLK: {
512 HTREEITEM hitem = TreeView_GetSelection(_hsidebar);
513 LPARAM lparam = TreeView_GetItemData(_hsidebar, hitem);
514
515 if (lparam) {
516 const BookmarkNode& node = *(BookmarkNode*)lparam;
517
518 if (node._type == BookmarkNode::BMNT_BOOKMARK) {
519 bool new_window = GetAsyncKeyState(VK_SHIFT)<0;
520
521 go_to(node._pbookmark->_url, new_window);
522 }
523 }
524 break;}
525 }
526
527 return 0;
528 }
529
530
531 void MainFrameBase::resize_frame(int cx, int cy)
532 {
533 if (cy <= 0)
534 return; // avoid resizing children when receiving RBN_AUTOSIZE while getting minimized
535
536 RECT rect = {0, 0, cx, cy};
537
538 if (_hwndrebar) {
539 int height = SendMessage(_hwndrebar, RB_GETBARHEIGHT, 0, 0);
540 rect.top += height;
541 rect.top += 5;
542 } else {
543 if (IsWindowVisible(_htoolbar)) {
544 SendMessage(_htoolbar, WM_SIZE, 0, 0);
545 WindowRect rt(_htoolbar);
546 rect.top = rt.bottom;
547 // rect.bottom -= rt.bottom;
548 }
549 }
550
551 if (IsWindowVisible(_hstatusbar)) {
552 int parts[] = {300, 500};
553
554 SendMessage(_hstatusbar, WM_SIZE, 0, 0);
555 SendMessage(_hstatusbar, SB_SETPARTS, 2, (LPARAM)&parts);
556 ClientRect rt(_hstatusbar);
557 rect.bottom -= rt.bottom;
558 }
559
560 if (IsWindowVisible(_haddressedit) || IsWindowVisible(_hcommandedit)) {
561 ClientRect rt(_haddressedit);
562 rect.bottom -= rt.bottom;
563
564 int mid = (rect.right-rect.left) / 2; ///@todo use split bar
565 SetWindowPos(_haddressedit, 0, 0, rect.bottom, mid, rt.bottom, SWP_NOACTIVATE|SWP_NOZORDER);
566 SetWindowPos(_hcommandedit, 0, mid+1, rect.bottom, rect.right-(mid+1), rt.bottom, SWP_NOACTIVATE|SWP_NOZORDER);
567 }
568
569 if (IsWindowVisible(_hsidebar)) {
570 WindowRect rt(_hsidebar);
571 rect.left += rt.right-rt.left;
572
573 SetWindowPos(_hsidebar, 0, -1, rect.top-1, rt.right-rt.left, rect.bottom-rect.top+1, SWP_NOACTIVATE|SWP_NOZORDER);
574 }
575 }
576
577 void MainFrameBase::resize_frame_client()
578 {
579 ClientRect rect(_hwnd);
580
581 resize_frame(rect.right, rect.bottom);
582 }
583
584 void MainFrameBase::frame_get_clientspace(PRECT prect)
585 {
586 if (!IsIconic(_hwnd))
587 GetClientRect(_hwnd, prect);
588 else {
589 WINDOWPLACEMENT wp;
590
591 GetWindowPlacement(_hwnd, &wp);
592
593 prect->left = prect->top = 0;
594 prect->right = wp.rcNormalPosition.right-wp.rcNormalPosition.left-
595 2*(GetSystemMetrics(SM_CXSIZEFRAME)+GetSystemMetrics(SM_CXEDGE));
596 prect->bottom = wp.rcNormalPosition.bottom-wp.rcNormalPosition.top-
597 2*(GetSystemMetrics(SM_CYSIZEFRAME)+GetSystemMetrics(SM_CYEDGE))-
598 GetSystemMetrics(SM_CYCAPTION)-GetSystemMetrics(SM_CYMENUSIZE);
599 }
600
601 if (IsWindowVisible(_htoolbar)) {
602 ClientRect rt(_htoolbar);
603 prect->top += rt.bottom+2;
604 }
605
606 if (IsWindowVisible(_hstatusbar)) {
607 ClientRect rt(_hstatusbar);
608 prect->bottom -= rt.bottom;
609 }
610 }
611
612 BOOL MainFrameBase::toggle_fullscreen()
613 {
614 RECT rt;
615
616 if ((_fullscreen._mode=!_fullscreen._mode)) {
617 GetWindowRect(_hwnd, &_fullscreen._orgPos);
618 _fullscreen._wasZoomed = IsZoomed(_hwnd);
619
620 Frame_CalcFrameClient(_hwnd, &rt);
621 ClientToScreen(_hwnd, (LPPOINT)&rt.left);
622 ClientToScreen(_hwnd, (LPPOINT)&rt.right);
623
624 rt.left = _fullscreen._orgPos.left-rt.left;
625 rt.top = _fullscreen._orgPos.top-rt.top;
626 rt.right = GetSystemMetrics(SM_CXSCREEN)+_fullscreen._orgPos.right-rt.right;
627 rt.bottom = GetSystemMetrics(SM_CYSCREEN)+_fullscreen._orgPos.bottom-rt.bottom;
628
629 MoveWindow(_hwnd, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, TRUE);
630 } else {
631 MoveWindow(_hwnd, _fullscreen._orgPos.left, _fullscreen._orgPos.top,
632 _fullscreen._orgPos.right-_fullscreen._orgPos.left,
633 _fullscreen._orgPos.bottom-_fullscreen._orgPos.top, TRUE);
634
635 if (_fullscreen._wasZoomed)
636 ShowWindow(_hwnd, WS_MAXIMIZE);
637 }
638
639 return _fullscreen._mode;
640 }
641
642 void MainFrameBase::fullscreen_move()
643 {
644 RECT rt, pos;
645 GetWindowRect(_hwnd, &pos);
646
647 Frame_CalcFrameClient(_hwnd, &rt);
648 ClientToScreen(_hwnd, (LPPOINT)&rt.left);
649 ClientToScreen(_hwnd, (LPPOINT)&rt.right);
650
651 rt.left = pos.left-rt.left;
652 rt.top = pos.top-rt.top;
653 rt.right = GetSystemMetrics(SM_CXSCREEN)+pos.right-rt.right;
654 rt.bottom = GetSystemMetrics(SM_CYSCREEN)+pos.bottom-rt.bottom;
655
656 MoveWindow(_hwnd, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, TRUE);
657 }
658
659
660 void MainFrameBase::toggle_child(HWND hwnd, UINT cmd, HWND hchild, int band_idx)
661 {
662 BOOL vis = IsWindowVisible(hchild);
663
664 CheckMenuItem(_menu_info._hMenuView, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
665
666 if (band_idx != -1)
667 SendMessage(_hwndrebar, RB_SHOWBAND, band_idx, !vis);
668 else
669 ShowWindow(hchild, vis? SW_HIDE: SW_SHOW);
670
671 if (_fullscreen._mode)
672 fullscreen_move();
673
674 resize_frame_client();
675 }
676
677 void MainFrameBase::FillBookmarks()
678 {
679 HiddenWindow hide(_hsidebar);
680 WindowCanvas canvas(_hwnd);
681
682 TreeView_DeleteAllItems(_hsidebar);
683
684 g_Globals._icon_cache.get_icon(ICID_FAVORITES).add_to_imagelist(_himl, canvas);
685 g_Globals._icon_cache.get_icon(ICID_BOOKMARK).add_to_imagelist(_himl, canvas);
686 ImageList_AddAlphaIcon(_himl, SmallIcon(IDI_DOT), GetStockBrush(WHITE_BRUSH), canvas);
687 g_Globals._icon_cache.get_icon(ICID_FOLDER).add_to_imagelist(_himl, canvas);
688 g_Globals._icon_cache.get_icon(ICID_FOLDER).add_to_imagelist(_himl, canvas);
689
690 TV_INSERTSTRUCT tvi;
691
692 tvi.hParent = TVI_ROOT;
693 tvi.hInsertAfter = TVI_LAST;
694 tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
695 ResString sFavorites(IDS_FAVORITES);
696 tvi.item.pszText = sFavorites.str();
697 tvi.item.iSelectedImage = tvi.item.iImage = 0;
698
699 HTREEITEM hitem_bookmarks = TreeView_InsertItem(_hsidebar, &tvi);
700
701 g_Globals._favorites.fill_tree(_hsidebar, hitem_bookmarks, _himl, canvas);
702
703 TreeView_Expand(_hsidebar, hitem_bookmarks, TVE_EXPAND);
704 }
705
706
707 bool MainFrameBase::go_to(LPCTSTR url, bool new_window)
708 {
709 ///@todo SDI implementation
710
711 return false;
712 }
713
714
715 #ifndef _NO_MDI
716
717 MDIMainFrame::MDIMainFrame(HWND hwnd)
718 : super(hwnd)
719 {
720 TBBUTTON mdiBtns[] = {
721 {0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
722 {0, ID_WINDOW_NEW, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
723 {1, ID_WINDOW_CASCADE, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
724 {2, ID_WINDOW_TILE_HORZ, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
725 {3, ID_WINDOW_TILE_VERT, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0}
726 };
727
728 SendMessage(_htoolbar, TB_ADDBUTTONS, sizeof(mdiBtns)/sizeof(TBBUTTON), (LPARAM)&mdiBtns);
729
730 CLIENTCREATESTRUCT ccs;
731
732 ccs.hWindowMenu = _hMenuWindow;
733 ccs.idFirstChild = IDW_FIRST_CHILD;
734
735 _hmdiclient = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("MDICLIENT"), NULL,
736 WS_CHILD|WS_CLIPCHILDREN|WS_VSCROLL|WS_HSCROLL|WS_VISIBLE|WS_BORDER,
737 0, 0, 0, 0,
738 hwnd, 0, g_Globals._hInstance, &ccs);
739
740 TBBUTTON extraBtns = {0, 0, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0};
741
742 #ifndef _NO_REBAR
743 _hextrabar = CreateToolbarEx(hwnd,
744 CCS_NOPARENTALIGN|CCS_NORESIZE|CCS_NODIVIDER|
745 WS_CHILD|TBSTYLE_FLAT|WS_VISIBLE|CCS_NOMOVEY|TBSTYLE_LIST,
746 IDW_EXTRABAR, 2, g_Globals._hInstance, IDB_DRIVEBAR, NULL, 0,
747 16, 15, 16, 15, sizeof(TBBUTTON));
748 #else
749 _hextrabar = CreateToolbarEx(hwnd,
750 WS_CHILD|WS_VISIBLE|CCS_NOMOVEY|TBSTYLE_LIST,CCS_NODIVIDER|
751 IDW_EXTRABAR, 2, g_Globals._hInstance, IDB_DRIVEBAR, &extraBtns, 1,
752 16, 13, 16, 13, sizeof(TBBUTTON));
753 #endif
754
755 CheckMenuItem(_menu_info._hMenuView, ID_VIEW_EXTRA_BAR, MF_BYCOMMAND|MF_CHECKED);
756
757
758 extraBtns.fsStyle = BTNS_BUTTON;
759
760 #ifdef __WINE__
761 // insert unix file system button
762 extraBtns.iString = SendMessage(_hextrabar, TB_ADDSTRING, 0, (LPARAM)TEXT("/\0"));
763 extraBtns.idCommand = ID_DRIVE_UNIX_FS;
764 SendMessage(_hextrabar, TB_INSERTBUTTON, INT_MAX, (LPARAM)&extraBtns);
765 #endif
766
767 // insert explorer window button
768 extraBtns.iString = SendMessage(_hextrabar, TB_ADDSTRING, 0, (LPARAM)TEXT("Explore\0"));
769 extraBtns.idCommand = ID_DRIVE_DESKTOP;
770 SendMessage(_hextrabar, TB_INSERTBUTTON, INT_MAX, (LPARAM)&extraBtns);
771
772 // insert shell namespace button
773 extraBtns.iString = SendMessage(_hextrabar, TB_ADDSTRING, 0, (LPARAM)TEXT("Shell\0"));
774 extraBtns.idCommand = ID_DRIVE_SHELL_NS;
775 extraBtns.iBitmap = 6;
776 SendMessage(_hextrabar, TB_INSERTBUTTON, INT_MAX, (LPARAM)&extraBtns);
777
778 // insert web control button
779 extraBtns.iString = SendMessage(_hextrabar, TB_ADDSTRING, 0, (LPARAM)TEXT("Web\0"));
780 extraBtns.idCommand = ID_WEB_WINDOW;
781 extraBtns.iBitmap = 7;
782 SendMessage(_hextrabar, TB_INSERTBUTTON, INT_MAX, (LPARAM)&extraBtns);
783
784 if ((HIWORD(GetVersion())>>14) == W_VER_NT) {
785 // insert NT object namespace button
786 extraBtns.iString = SendMessage(_hextrabar, TB_ADDSTRING, 0, (LPARAM)TEXT("NT Obj\0"));
787 extraBtns.idCommand = ID_DRIVE_NTOBJ_NS;
788 extraBtns.iBitmap = 8;
789 SendMessage(_hextrabar, TB_INSERTBUTTON, INT_MAX, (LPARAM)&extraBtns);
790 }
791 #ifndef _ROS_ // don't insert reg button for ROS. Regedit should be used.
792 // insert Registry button
793 extraBtns.iString = SendMessage(_hextrabar, TB_ADDSTRING, 0, (LPARAM)TEXT("Reg.\0"));
794 extraBtns.idCommand = ID_DRIVE_REGISTRY;
795 extraBtns.iBitmap = 9;
796 SendMessage(_hextrabar, TB_INSERTBUTTON, INT_MAX, (LPARAM)&extraBtns);
797 #endif
798
799 #ifdef _DEBUG
800 // insert FAT direct file system access button
801 extraBtns.iString = SendMessage(_hextrabar, TB_ADDSTRING, 0, (LPARAM)TEXT("FAT\0"));
802 extraBtns.idCommand = ID_DRIVE_FAT;
803 extraBtns.iBitmap = 10;
804 SendMessage(_hextrabar, TB_INSERTBUTTON, INT_MAX, (LPARAM)&extraBtns);
805 #endif
806
807
808 TBBUTTON drivebarBtn = {0, 0, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0};
809 #ifndef _NO_WIN_FS
810 PTSTR p;
811
812 #ifndef _NO_REBAR
813 _hdrivebar = CreateToolbarEx(hwnd,
814 CCS_NOPARENTALIGN|CCS_NORESIZE|CCS_NODIVIDER|
815 WS_CHILD|WS_VISIBLE|TBSTYLE_FLAT|CCS_NOMOVEY|TBSTYLE_LIST,
816 IDW_DRIVEBAR, 2, g_Globals._hInstance, IDB_DRIVEBAR, NULL, 0,
817 16, 15, 16, 15, sizeof(TBBUTTON));
818 #else
819 _hdrivebar = CreateToolbarEx(hwnd,
820 WS_CHILD|WS_VISIBLE|CCS_NOMOVEY|TBSTYLE_LIST|CCS_NODIVIDER,
821 IDW_DRIVEBAR, 2, g_Globals._hInstance, IDB_DRIVEBAR, &drivebarBtn, 1,
822 16, 13, 16, 13, sizeof(TBBUTTON));
823 #endif
824 #endif
825
826 CheckMenuItem(_menu_info._hMenuView, ID_VIEW_DRIVE_BAR, MF_BYCOMMAND|MF_CHECKED);
827
828
829 #ifndef _NO_WIN_FS
830 GetLogicalDriveStrings(BUFFER_LEN, _drives);
831
832 // register windows drive root strings
833 SendMessage(_hdrivebar, TB_ADDSTRING, 0, (LPARAM)_drives);
834
835 drivebarBtn.fsStyle = BTNS_BUTTON;
836 drivebarBtn.idCommand = ID_DRIVE_FIRST;
837
838 for(p=_drives; *p; ) {
839 switch(GetDriveType(p)) {
840 case DRIVE_REMOVABLE: drivebarBtn.iBitmap = 1; break;
841 case DRIVE_CDROM: drivebarBtn.iBitmap = 3; break;
842 case DRIVE_REMOTE: drivebarBtn.iBitmap = 4; break;
843 case DRIVE_RAMDISK: drivebarBtn.iBitmap = 5; break;
844 default:/*DRIVE_FIXED*/ drivebarBtn.iBitmap = 2;
845 }
846
847 SendMessage(_hdrivebar, TB_INSERTBUTTON, INT_MAX, (LPARAM)&drivebarBtn);
848 ++drivebarBtn.idCommand;
849 ++drivebarBtn.iString;
850
851 while(*p++);
852 }
853 #endif
854
855
856 #ifndef _NO_REBAR
857 int btn_hgt = HIWORD(SendMessage(_htoolbar, TB_GETBUTTONSIZE, 0, 0));
858
859 REBARBANDINFO rbBand;
860
861 rbBand.cbSize = sizeof(REBARBANDINFO);
862 rbBand.fMask = RBBIM_TEXT|RBBIM_STYLE|RBBIM_CHILD|RBBIM_CHILDSIZE|RBBIM_SIZE;
863 #ifndef RBBS_HIDETITLE // missing in MinGW headers as of 25.02.2004
864 #define RBBS_HIDETITLE 0x400
865 #endif
866 rbBand.fStyle = RBBS_CHILDEDGE|RBBS_GRIPPERALWAYS|RBBS_HIDETITLE;
867
868 TCHAR ExtrasBand[] = _T("Extras");
869 rbBand.lpText = ExtrasBand;
870 rbBand.hwndChild = _hextrabar;
871 rbBand.cxMinChild = 0;
872 rbBand.cyMinChild = btn_hgt;
873 rbBand.cx = 284;
874 SendMessage(_hwndrebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
875
876 #ifndef _NO_WIN_FS
877 rbBand.fStyle |= RBBS_BREAK;
878 TCHAR DrivesBand[] = _T("Drives");
879 rbBand.lpText = DrivesBand;
880 rbBand.hwndChild = _hdrivebar;
881 rbBand.cxMinChild = 0;
882 rbBand.cyMinChild = btn_hgt;
883 rbBand.cx = 400;
884 SendMessage(_hwndrebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
885 #endif
886 #endif
887 }
888
889
890 HWND MDIMainFrame::Create()
891 {
892 HMENU hMenuFrame = LoadMenu(g_Globals._hInstance, MAKEINTRESOURCE(IDM_MDIFRAME));
893
894 return Window::Create(WINDOW_CREATOR(MDIMainFrame), 0,
895 (LPCTSTR)(int)g_Globals._hframeClass, ResString(IDS_TITLE), WS_OVERLAPPEDWINDOW,
896 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
897 0/*hwndDesktop*/, hMenuFrame);
898 }
899
900 HWND MDIMainFrame::Create(LPCTSTR path, int mode)
901 {
902 HWND hFrame = Create();
903 if (!hFrame)
904 return 0;
905
906 ShowWindow(hFrame, SW_SHOW);
907
908 MDIMainFrame* pMainFrame = GET_WINDOW(MDIMainFrame, hFrame);
909
910 if (pMainFrame)
911 pMainFrame->CreateChild(path, mode);
912
913 return hFrame;
914 }
915
916 HWND MDIMainFrame::Create(LPCITEMIDLIST pidl, int mode)
917 {
918 HWND hFrame = Create();
919 if (!hFrame)
920 return 0;
921
922 ShowWindow(hFrame, SW_SHOW);
923
924 MDIMainFrame* pMainFrame = GET_WINDOW(MDIMainFrame, hFrame);
925
926 if (pMainFrame)
927 pMainFrame->CreateChild(pidl, mode);
928
929 return hFrame;
930 }
931
932
933 ChildWindow* MDIMainFrame::CreateChild(LPCTSTR path, int mode)
934 {
935 return reinterpret_cast<ChildWindow*>(SendMessage(_hwnd, PM_OPEN_WINDOW, mode, (LPARAM)path));
936 }
937
938 ChildWindow* MDIMainFrame::CreateChild(LPCITEMIDLIST pidl, int mode)
939 {
940 return reinterpret_cast<ChildWindow*>(SendMessage(_hwnd, PM_OPEN_WINDOW, mode|OWM_PIDL, (LPARAM)pidl));
941 }
942
943
944 BOOL MDIMainFrame::TranslateMsg(MSG* pmsg)
945 {
946 if (_hmdiclient && TranslateMDISysAccel(_hmdiclient, pmsg))
947 return TRUE;
948
949 return super::TranslateMsg(pmsg);
950 }
951
952 LRESULT MDIMainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
953 {
954 switch(nmsg) {
955 case PM_OPEN_WINDOW: {
956 CONTEXT("MDIMainFrame PM_OPEN_WINDOW");
957
958 TCHAR buffer[MAX_PATH];
959 LPCTSTR path;
960 ShellPath shell_path = DesktopFolderPath();
961
962 if (lparam) {
963 if (wparam & OWM_PIDL) {
964 // take over PIDL from lparam
965 shell_path.assign((LPCITEMIDLIST)lparam); // create as "rooted" window
966 FileSysShellPath fsp(shell_path);
967 path = fsp;
968
969 if (path) {
970 LOG(FmtString(TEXT("MDIMainFrame PM_OPEN_WINDOW: path=%s"), path));
971 lstrcpy(buffer, path);
972 path = buffer;
973 }
974 } else {
975 // take over path from lparam
976 path = (LPCTSTR)lparam;
977 shell_path = path; // create as "rooted" window
978 }
979 } else {
980 ///@todo read paths and window placements from registry
981 if (!GetCurrentDirectory(MAX_PATH, buffer))
982 *buffer = '\0';
983
984 path = buffer;
985 }
986
987 if (path && _tcsstr(path, TEXT("://"))) { // "http://...", "ftp://", ...
988 OBJ_CONTEXT("create WebChild window", path);
989
990 return (LRESULT)GET_WINDOW(ChildWindow, create_webchildwindow(WebChildWndInfo(_hmdiclient, path)));
991 } else {
992 OBJ_CONTEXT("create ShellChildWndInfo", path);
993
994 // Shell Namespace as default view
995 ShellChildWndInfo create_info(_hmdiclient, path, shell_path);
996
997 if (wparam & OWM_ROOTED)
998 create_info._root_shell_path = shell_path;
999 else
1000 create_info._root_shell_path = DesktopFolderPath(); //SpecialFolderPath(CSIDL_DRIVES, _hwnd);
1001
1002 create_info._pos.showCmd = wparam&OWM_SEPARATE? SW_SHOWNORMAL: SW_SHOWMAXIMIZED;
1003 create_info._pos.rcNormalPosition.left = CW_USEDEFAULT;
1004 create_info._pos.rcNormalPosition.top = CW_USEDEFAULT;
1005 create_info._pos.rcNormalPosition.right = CW_USEDEFAULT;
1006 create_info._pos.rcNormalPosition.bottom = CW_USEDEFAULT;
1007
1008 create_info._open_mode = wparam;
1009
1010 // FileChildWindow::create(_hmdiclient, create_info);
1011 return (LRESULT)MDIShellBrowserChild::create(create_info);
1012 }
1013 return TRUE;} // success
1014
1015 default: {
1016 LRESULT res;
1017
1018 if (super::ProcessMessage(nmsg, wparam, lparam, &res))
1019 return res;
1020 else
1021 return DefFrameProc(_hwnd, _hmdiclient, nmsg, wparam, lparam);
1022 }
1023 }
1024
1025 return 0;
1026 }
1027
1028 int MDIMainFrame::Command(int id, int code)
1029 {
1030 CONTEXT("MDIMainFrame::Command()");
1031
1032 HWND hwndClient = (HWND) SendMessage(_hmdiclient, WM_MDIGETACTIVE, 0, 0);
1033
1034 if (hwndClient)
1035 if (SendMessage(hwndClient, PM_DISPATCH_COMMAND, MAKELONG(id,code), 0))
1036 return 0;
1037
1038 #ifndef _NO_WIN_FS
1039 if (id>=ID_DRIVE_FIRST && id<=ID_DRIVE_FIRST+0xFF) {
1040 TCHAR drv[_MAX_DRIVE], path[MAX_PATH];
1041 LPCTSTR root = _drives;
1042
1043 for(int i=id-ID_DRIVE_FIRST; i--; root++)
1044 while(*root)
1045 ++root;
1046
1047 if (activate_drive_window(root))
1048 return 0;
1049
1050 _tsplitpath_s(root, drv, COUNTOF(drv), NULL, 0, NULL, 0, NULL, 0);
1051
1052 if (!SetCurrentDirectory(drv)) {
1053 display_error(_hwnd, GetLastError());
1054 return 0;
1055 }
1056
1057 GetCurrentDirectory(MAX_PATH, path); ///@todo store last directory per drive
1058
1059 FileChildWindow::create(FileChildWndInfo(_hmdiclient, path));
1060
1061 return 1;
1062 }
1063 #endif
1064
1065 switch(id) {
1066 case ID_WINDOW_NEW: {
1067 TCHAR path[MAX_PATH];
1068
1069 GetCurrentDirectory(MAX_PATH, path);
1070
1071 FileChildWindow::create(FileChildWndInfo(_hmdiclient, path));
1072 break;}
1073
1074 case ID_WINDOW_CASCADE:
1075 SendMessage(_hmdiclient, WM_MDICASCADE, 0, 0);
1076 break;
1077
1078 case ID_WINDOW_TILE_HORZ:
1079 SendMessage(_hmdiclient, WM_MDITILE, MDITILE_HORIZONTAL, 0);
1080 break;
1081
1082 case ID_WINDOW_TILE_VERT:
1083 SendMessage(_hmdiclient, WM_MDITILE, MDITILE_VERTICAL, 0);
1084 break;
1085
1086 case ID_WINDOW_ARRANGE:
1087 SendMessage(_hmdiclient, WM_MDIICONARRANGE, 0, 0);
1088 break;
1089
1090 case ID_VIEW_EXTRA_BAR:
1091 toggle_child(_hwnd, id, _hextrabar, 1);
1092 break;
1093
1094 #ifndef _NO_WIN_FS
1095 case ID_VIEW_DRIVE_BAR:
1096 toggle_child(_hwnd, id, _hdrivebar, 2);
1097 break;
1098 #endif
1099
1100 #ifdef __WINE__
1101 case ID_DRIVE_UNIX_FS: {
1102 TCHAR path[MAX_PATH];
1103 FileChildWindow* child;
1104
1105 getcwd(path, COUNTOF(path));
1106
1107 if (activate_child_window(TEXT("unixfs")))
1108 break;
1109
1110 FileChildWindow::create(_hmdiclient, FileChildWndInfo(path));
1111 break;}
1112 #endif
1113
1114 case ID_DRIVE_DESKTOP: {
1115 TCHAR path[MAX_PATH];
1116
1117 if (activate_child_window(TEXT("Desktop")))
1118 break;
1119
1120 GetCurrentDirectory(MAX_PATH, path);
1121
1122 MDIShellBrowserChild::create(ShellChildWndInfo(_hmdiclient, path, DesktopFolderPath()));
1123 break;}
1124
1125 case ID_DRIVE_SHELL_NS: {
1126 TCHAR path[MAX_PATH];
1127 GetCurrentDirectory(MAX_PATH, path);
1128
1129 if (activate_child_window(TEXT("Shell")))
1130 break;
1131
1132 FileChildWindow::create(ShellChildWndInfo(_hmdiclient, path, DesktopFolderPath()));
1133 break;}
1134
1135 case ID_DRIVE_NTOBJ_NS: {
1136 if (activate_child_window(TEXT("NTOBJ")))
1137 break;
1138
1139 FileChildWindow::create(NtObjChildWndInfo(_hmdiclient, TEXT("\\")));
1140 break;}
1141
1142 case ID_DRIVE_REGISTRY: {
1143 if (activate_child_window(TEXT("Registry")))
1144 break;
1145
1146 FileChildWindow::create(RegistryChildWndInfo(_hmdiclient, TEXT("\\")));
1147 break;}
1148
1149 case ID_DRIVE_FAT: {
1150
1151 ///@todo prompt for image file
1152
1153 if (activate_child_window(TEXT("FAT")))
1154 break;
1155
1156 FileChildWindow::create(FATChildWndInfo(_hmdiclient, TEXT("FAT Image"))); //@@
1157 break;}
1158
1159 case ID_WEB_WINDOW:
1160 #ifdef _DEBUG
1161 create_webchildwindow(WebChildWndInfo(_hmdiclient, TEXT("http://localhost")));
1162 #else
1163 create_webchildwindow(WebChildWndInfo(_hmdiclient, TEXT("http://www.reactos.org")));
1164 #endif
1165 break;
1166
1167 case ID_EXPLORER_FAQ:
1168 create_webchildwindow(WebChildWndInfo(_hmdiclient, TEXT("http://www.sky.franken.de/explorer/")));
1169 break;
1170
1171 case ID_VIEW_SDI:
1172 MainFrameBase::Create(ExplorerCmd());
1173 break;
1174
1175 case IDW_COMMANDBAR:
1176 if (code == 1) {
1177 TCHAR url[BUFFER_LEN];
1178 LPCTSTR dir;
1179
1180 if (GetWindowText(_haddressedit, url, BUFFER_LEN))
1181 dir = url;
1182 else
1183 dir = NULL;
1184
1185 ExecuteCommandbar(dir);
1186 }
1187 break;
1188
1189 ///@todo There are even more menu items!
1190
1191 default:
1192 if (super::Command(id, code) == 0)
1193 return 0;
1194 else
1195 return DefFrameProc(_hwnd, _hmdiclient, WM_COMMAND, MAKELONG(id,code), 0);
1196 }
1197
1198 return 0;
1199 }
1200
1201
1202 void MDIMainFrame::frame_get_clientspace(PRECT prect)
1203 {
1204 super::frame_get_clientspace(prect);
1205
1206 #ifndef _NO_WIN_FS
1207 if (IsWindowVisible(_hdrivebar)) {
1208 ClientRect rt(_hdrivebar);
1209 prect->top += rt.bottom+2;
1210 }
1211 #endif
1212 }
1213
1214 void MDIMainFrame::resize_frame(int cx, int cy)
1215 {
1216 if (cy <= 0)
1217 return; // avoid resizing children when receiving RBN_AUTOSIZE while getting minimized
1218
1219 RECT rect = {0, 0, cx, cy};
1220
1221 if (_hwndrebar) {
1222 int height = SendMessage(_hwndrebar, RB_GETBARHEIGHT, 0, 0);
1223 rect.top += height;
1224 rect.top += 5;
1225 } else {
1226 if (IsWindowVisible(_htoolbar)) {
1227 SendMessage(_htoolbar, WM_SIZE, 0, 0);
1228 WindowRect rt(_htoolbar);
1229 rect.top = rt.bottom;
1230 // rect.bottom -= rt.bottom;
1231 }
1232
1233 if (IsWindowVisible(_hextrabar)) {
1234 SendMessage(_hextrabar, WM_SIZE, 0, 0);
1235 WindowRect rt(_hextrabar);
1236 int new_top = --rect.top + rt.bottom;
1237 MoveWindow(_hextrabar, 0, rect.top, rt.right, new_top, TRUE);
1238 rect.top = new_top;
1239 // rect.bottom -= rt.bottom;
1240 }
1241
1242 #ifndef _NO_WIN_FS
1243 if (IsWindowVisible(_hdrivebar)) {
1244 SendMessage(_hdrivebar, WM_SIZE, 0, 0);
1245 WindowRect rt(_hdrivebar);
1246 int new_top = --rect.top + rt.bottom;
1247 MoveWindow(_hdrivebar, 0, rect.top, rt.right, new_top, TRUE);
1248 rect.top = new_top;
1249 // rect.bottom -= rt.bottom;
1250 }
1251 #endif
1252 }
1253
1254 if (IsWindowVisible(_hstatusbar)) {
1255 int parts[] = {300, 500};
1256
1257 SendMessage(_hstatusbar, WM_SIZE, 0, 0);
1258 SendMessage(_hstatusbar, SB_SETPARTS, 2, (LPARAM)&parts);
1259 ClientRect rt(_hstatusbar);
1260 rect.bottom -= rt.bottom;
1261 }
1262
1263 if (IsWindowVisible(_haddressedit) || IsWindowVisible(_hcommandedit)) {
1264 ClientRect rt(_haddressedit);
1265 rect.bottom -= rt.bottom;
1266
1267 int mid = (rect.right-rect.left) / 2; ///@todo use split bar
1268 SetWindowPos(_haddressedit, 0, 0, rect.bottom, mid, rt.bottom, SWP_NOACTIVATE|SWP_NOZORDER);
1269 SetWindowPos(_hcommandedit, 0, mid+1, rect.bottom, rect.right-(mid+1), rt.bottom, SWP_NOACTIVATE|SWP_NOZORDER);
1270 }
1271
1272 if (IsWindowVisible(_hsidebar)) {
1273 WindowRect rt(_hsidebar);
1274 rect.left += rt.right-rt.left;
1275
1276 SetWindowPos(_hsidebar, 0, -1, rect.top-1, rt.right-rt.left, rect.bottom-rect.top+1, SWP_NOACTIVATE|SWP_NOZORDER);
1277 }
1278
1279 MoveWindow(_hmdiclient, rect.left-1, rect.top-1, rect.right-rect.left+1, rect.bottom-rect.top+1, TRUE);
1280 }
1281
1282 bool MDIMainFrame::activate_drive_window(LPCTSTR path)
1283 {
1284 TCHAR drv1[_MAX_DRIVE], drv2[_MAX_DRIVE];
1285 HWND child_wnd;
1286
1287 _tsplitpath_s(path, drv1, COUNTOF(drv1), NULL, 0, NULL, 0, NULL, 0);
1288
1289 // search for a already open window for the same drive
1290 for(child_wnd=GetNextWindow(_hmdiclient,GW_CHILD); child_wnd; child_wnd=GetNextWindow(child_wnd, GW_HWNDNEXT)) {
1291 FileChildWindow* child = (FileChildWindow*) SendMessage(child_wnd, PM_GET_FILEWND_PTR, 0, 0);
1292
1293 if (child) {
1294 _tsplitpath_s(child->get_root()._path, drv2, COUNTOF(drv2), NULL, 0, NULL, 0, NULL, 0);
1295
1296 if (!lstrcmpi(drv2, drv1)) {
1297 SendMessage(_hmdiclient, WM_MDIACTIVATE, (WPARAM)child_wnd, 0);
1298
1299 if (IsMinimized(child_wnd))
1300 ShowWindow(child_wnd, SW_SHOWNORMAL);
1301
1302 return true;
1303 }
1304 }
1305 }
1306
1307 return false;
1308 }
1309
1310 bool MDIMainFrame::activate_child_window(LPCTSTR filesys)
1311 {
1312 HWND child_wnd;
1313
1314 // search for a already open window of the given file system name
1315 for(child_wnd=GetNextWindow(_hmdiclient,GW_CHILD); child_wnd; child_wnd=GetNextWindow(child_wnd, GW_HWNDNEXT)) {
1316 FileChildWindow* child = (FileChildWindow*) SendMessage(child_wnd, PM_GET_FILEWND_PTR, 0, 0);
1317
1318 if (child) {
1319 if (!lstrcmpi(child->get_root()._fs, filesys)) {
1320 SendMessage(_hmdiclient, WM_MDIACTIVATE, (WPARAM)child_wnd, 0);
1321
1322 if (IsMinimized(child_wnd))
1323 ShowWindow(child_wnd, SW_SHOWNORMAL);
1324
1325 return true;
1326 }
1327 } else {
1328 ShellBrowser* shell_child = (ShellBrowser*) SendMessage(child_wnd, PM_GET_SHELLBROWSER_PTR, 0, 0);
1329
1330 if (shell_child) {
1331 if (!lstrcmpi(shell_child->get_root()._fs, filesys)) {
1332 SendMessage(_hmdiclient, WM_MDIACTIVATE, (WPARAM)child_wnd, 0);
1333
1334 if (IsMinimized(child_wnd))
1335 ShowWindow(child_wnd, SW_SHOWNORMAL);
1336
1337 return true;
1338 }
1339 }
1340 }
1341 }
1342
1343 return false;
1344 }
1345
1346 bool MDIMainFrame::go_to(LPCTSTR url, bool new_window)
1347 {
1348 if (!new_window) {
1349 HWND hwndClient = (HWND) SendMessage(_hmdiclient, WM_MDIGETACTIVE, 0, 0);
1350
1351 if (hwndClient)
1352 if (SendMessage(hwndClient, PM_JUMP_TO_URL, 0, (LPARAM)url))
1353 return true;
1354 }
1355
1356 if (CreateChild(url))
1357 return true;
1358
1359 return super::go_to(url, new_window);
1360 }
1361
1362 #endif // _NO_MDI
1363
1364
1365 SDIMainFrame::SDIMainFrame(HWND hwnd)
1366 : super(hwnd)
1367 {
1368 _split_pos = DEFAULT_SPLIT_POS;
1369 _last_split = DEFAULT_SPLIT_POS;
1370
1371 /* wait for PM_OPEN_WINDOW message before creating a shell view
1372 update_shell_browser();*/
1373 }
1374
1375 HWND SDIMainFrame::Create()
1376 {
1377 HMENU hMenuFrame = LoadMenu(g_Globals._hInstance, MAKEINTRESOURCE(IDM_SDIFRAME));
1378
1379 return Window::Create(WINDOW_CREATOR(SDIMainFrame), 0,
1380 (LPCTSTR)(int)g_Globals._hframeClass, ResString(IDS_TITLE), WS_OVERLAPPEDWINDOW,
1381 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
1382 0/*hwndDesktop*/, hMenuFrame);
1383 }
1384
1385 HWND SDIMainFrame::Create(LPCITEMIDLIST pidl, int mode)
1386 {
1387 HWND hFrame = Create();
1388 if (!hFrame)
1389 return 0;
1390
1391 ShowWindow(hFrame, SW_SHOW);
1392
1393 SDIMainFrame* pFrame = GET_WINDOW(SDIMainFrame, hFrame);
1394
1395 if (pFrame)
1396 pFrame->jump_to(pidl, mode);
1397
1398 return hFrame;
1399 }
1400
1401 HWND SDIMainFrame::Create(LPCTSTR path, int mode)
1402 {
1403 HWND hFrame = Create();
1404 if (!hFrame)
1405 return 0;
1406
1407 ShowWindow(hFrame, SW_SHOW);
1408
1409 MDIMainFrame* pMainFrame = GET_WINDOW(MDIMainFrame, hFrame);
1410
1411 if (pMainFrame)
1412 pMainFrame->CreateChild(path, mode);
1413
1414 return hFrame;
1415 }
1416
1417 LRESULT SDIMainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
1418 {
1419 switch(nmsg) {
1420 case WM_SIZE:
1421 resize_frame(LOWORD(lparam), HIWORD(lparam));
1422 break;
1423
1424 case WM_PAINT: {
1425 PaintCanvas canvas(_hwnd);
1426
1427 if (_left_hwnd) {
1428 ClientRect rt(_hwnd);
1429 rt.left = _split_pos-SPLIT_WIDTH/2;
1430 rt.right = _split_pos+SPLIT_WIDTH/2+1;
1431
1432 if (_right_hwnd) {
1433 WindowRect right_rect(_right_hwnd);
1434 ScreenToClient(_hwnd, &right_rect);
1435 rt.top = right_rect.top;
1436 rt.bottom = right_rect.bottom;
1437 }
1438
1439 HBRUSH lastBrush = SelectBrush(canvas, GetStockBrush(COLOR_SPLITBAR));
1440 Rectangle(canvas, rt.left, rt.top-1, rt.right, rt.bottom+1);
1441 SelectObject(canvas, lastBrush);
1442 }
1443 break;}
1444
1445 case WM_SETCURSOR:
1446 if (_left_hwnd)
1447 if (LOWORD(lparam) == HTCLIENT) {
1448 POINT pt;
1449 GetCursorPos(&pt);
1450 ScreenToClient(_hwnd, &pt);
1451
1452 if (pt.x>=_split_pos-SPLIT_WIDTH/2 && pt.x<_split_pos+SPLIT_WIDTH/2+1) {
1453 SetCursor(LoadCursor(0, IDC_SIZEWE));
1454 return TRUE;
1455 }
1456 }
1457 goto def;
1458
1459 case WM_LBUTTONDOWN:
1460 if (_left_hwnd) {
1461 int x = GET_X_LPARAM(lparam);
1462
1463 ClientRect rt(_hwnd);
1464
1465 if (x>=_split_pos-SPLIT_WIDTH/2 && x<_split_pos+SPLIT_WIDTH/2+1) {
1466 _last_split = _split_pos;
1467 SetCapture(_hwnd);
1468 }
1469 }
1470 break;
1471
1472 case WM_LBUTTONUP:
1473 if (GetCapture() == _hwnd)
1474 ReleaseCapture();
1475 break;
1476
1477 case WM_KEYDOWN:
1478 if (wparam == VK_ESCAPE)
1479 if (GetCapture() == _hwnd) {
1480 _split_pos = _last_split;
1481 resize_children();
1482 _last_split = -1;
1483 ReleaseCapture();
1484 SetCursor(LoadCursor(0, IDC_ARROW));
1485 }
1486 break;
1487
1488 case WM_MOUSEMOVE:
1489 if (GetCapture() == _hwnd) {
1490 int x = GET_X_LPARAM(lparam);
1491
1492 ClientRect rt(_hwnd);
1493
1494 if (x>=0 && x<rt.right) {
1495 _split_pos = x;
1496 resize_children();
1497 rt.left = x-SPLIT_WIDTH/2;
1498 rt.right = x+SPLIT_WIDTH/2+1;
1499 InvalidateRect(_hwnd, &rt, FALSE);
1500 UpdateWindow(_left_hwnd);
1501 UpdateWindow(_hwnd);
1502 UpdateWindow(_right_hwnd);
1503 }
1504 }
1505 break;
1506
1507 case PM_OPEN_WINDOW: {
1508 CONTEXT("SDIMainFrame PM_OPEN_WINDOW");
1509
1510 TCHAR buffer[MAX_PATH];
1511 LPCTSTR path;
1512 ShellPath shell_path = DesktopFolderPath();
1513
1514 if (lparam) {
1515 if (wparam & OWM_PIDL) {
1516 // take over PIDL from lparam
1517 shell_path.assign((LPCITEMIDLIST)lparam); // create as "rooted" window
1518 FileSysShellPath fsp(shell_path);
1519 path = fsp;
1520
1521 if (path) {
1522 LOG(FmtString(TEXT("SDIMainFrame PM_OPEN_WINDOW: path=%s"), path));
1523 lstrcpy(buffer, path);
1524 path = buffer;
1525 }
1526 } else {
1527 // take over path from lparam
1528 path = (LPCTSTR)lparam;
1529 shell_path = path; // create as "rooted" window
1530 }
1531 } else {
1532 ///@todo read paths and window placements from registry
1533 if (!GetCurrentDirectory(MAX_PATH, buffer))
1534 *buffer = '\0';
1535
1536 path = buffer;
1537 shell_path = path;
1538 }
1539
1540 if (wparam & OWM_ROOTED)
1541 _shellpath_info._root_shell_path = shell_path;
1542 else
1543 _shellpath_info._root_shell_path = DesktopFolderPath(); //SpecialFolderPath(CSIDL_DRIVES, _hwnd);
1544
1545 jump_to(shell_path, wparam); ///@todo content of 'path' not used any more
1546 return TRUE;} // success
1547
1548 default: def:
1549 return super::WndProc(nmsg, wparam, lparam);
1550 }
1551
1552 return 0;
1553 }
1554
1555 int SDIMainFrame::Command(int id, int code)
1556 {
1557 switch(id) {
1558 case ID_VIEW_MDI:
1559 MainFrameBase::Create(ExplorerCmd(_url, true));
1560 break;
1561
1562 case IDW_COMMANDBAR:
1563 if (code == 1)
1564 ExecuteCommandbar(_url);
1565 break;
1566
1567 default:
1568 return super::Command(id, code);
1569 }
1570
1571 return 0;
1572 }
1573
1574 void SDIMainFrame::resize_frame(int cx, int cy)
1575 {
1576 if (cy <= 0)
1577 return; // avoid resizing children when receiving RBN_AUTOSIZE while getting minimized
1578
1579 RECT rect = {0, 0, cx, cy};
1580
1581 if (_hwndrebar) {
1582 int height = ClientRect(_hwndrebar).bottom;
1583 rect.top += height;
1584 rect.top += 5;
1585 } else {
1586 if (IsWindowVisible(_htoolbar)) {
1587 SendMessage(_htoolbar, WM_SIZE, 0, 0);
1588 WindowRect rt(_htoolbar);
1589 rect.top = rt.bottom;
1590 // rect.bottom -= rt.bottom;
1591 }
1592 }
1593
1594 if (IsWindowVisible(_hstatusbar)) {
1595 int parts[] = {300, 500};
1596
1597 SendMessage(_hstatusbar, WM_SIZE, 0, 0);
1598 SendMessage(_hstatusbar, SB_SETPARTS, 2, (LPARAM)&parts);
1599 ClientRect rt(_hstatusbar);
1600 rect.bottom -= rt.bottom;
1601 }
1602
1603 if (IsWindowVisible(_haddressedit) || IsWindowVisible(_hcommandedit)) {
1604 ClientRect rt(_haddressedit);
1605 rect.bottom -= rt.bottom;
1606
1607 int mid = (rect.right-rect.left) / 2; ///@todo use split bar
1608 SetWindowPos(_haddressedit, 0, 0, rect.bottom, mid, rt.bottom, SWP_NOACTIVATE|SWP_NOZORDER);
1609 SetWindowPos(_hcommandedit, 0, mid+1, rect.bottom, rect.right-(mid+1), rt.bottom, SWP_NOACTIVATE|SWP_NOZORDER);
1610 }
1611
1612 if (IsWindowVisible(_hsidebar)) {
1613 WindowRect rt(_hsidebar);
1614 rect.left += rt.right-rt.left;
1615
1616 SetWindowPos(_hsidebar, 0, -1, rect.top-1, rt.right-rt.left, rect.bottom-rect.top+1, SWP_NOACTIVATE|SWP_NOZORDER);
1617 }
1618
1619 _clnt_rect = rect;
1620
1621 resize_children();
1622 }
1623
1624 void SDIMainFrame::resize_children()
1625 {
1626 HDWP hdwp = BeginDeferWindowPos(2);
1627
1628 int cx = _clnt_rect.left;
1629
1630 if (_left_hwnd) {
1631 cx = _split_pos + SPLIT_WIDTH/2;
1632
1633 hdwp = DeferWindowPos(hdwp, _left_hwnd, 0, _clnt_rect.left, _clnt_rect.top, _split_pos-SPLIT_WIDTH/2-_clnt_rect.left, _clnt_rect.bottom-_clnt_rect.top, SWP_NOZORDER|SWP_NOACTIVATE);
1634 } else {
1635 //_split_pos = -1;
1636 cx = 0;
1637 }
1638
1639 if (_right_hwnd)
1640 hdwp = DeferWindowPos(hdwp, _right_hwnd, 0, _clnt_rect.left+cx+1, _clnt_rect.top, _clnt_rect.right-cx, _clnt_rect.bottom-_clnt_rect.top, SWP_NOZORDER|SWP_NOACTIVATE);
1641
1642 EndDeferWindowPos(hdwp);
1643 }
1644
1645 void SDIMainFrame::update_clnt_rect()
1646 {
1647 ClientRect rect(_hwnd);
1648
1649 resize_frame(rect.right, rect.bottom);
1650 }
1651
1652 void SDIMainFrame::update_shell_browser()
1653 {
1654 int split_pos = DEFAULT_SPLIT_POS;
1655
1656 if (_shellBrowser.get()) {
1657 split_pos = _split_pos;
1658 delete _shellBrowser.release();
1659 }
1660
1661 // create explorer treeview
1662 if (_shellpath_info._open_mode & OWM_EXPLORE) {
1663 if (!_left_hwnd) {
1664 ClientRect rect(_hwnd);
1665
1666 _left_hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, NULL,
1667 WS_CHILD|WS_TABSTOP|WS_VISIBLE|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_NOTOOLTIPS|TVS_SHOWSELALWAYS,
1668 0, rect.top, split_pos-SPLIT_WIDTH/2, rect.bottom-rect.top,
1669 _hwnd, (HMENU)IDC_FILETREE, g_Globals._hInstance, 0);
1670
1671 // display tree window as long as the shell view is not yet visible
1672 resize_frame(rect.right, rect.bottom);
1673 MoveWindow(_left_hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);
1674 }
1675 } else {
1676 if (_left_hwnd) {
1677 DestroyWindow(_left_hwnd);
1678 _left_hwnd = 0;
1679 }
1680 }
1681
1682 _shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _hwnd, _left_hwnd, _right_hwnd,
1683 _shellpath_info, this, _cm_ifs));
1684
1685 if (_left_hwnd)
1686 _shellBrowser->Init();
1687
1688 // update _clnt_rect and set size of new created shell view windows
1689 update_clnt_rect();
1690 }
1691
1692 void SDIMainFrame::entry_selected(Entry* entry)
1693 {
1694 if (_left_hwnd)
1695 _shellBrowser->select_folder(entry, false);
1696
1697 _shellBrowser->UpdateFolderView(entry->get_shell_folder());
1698
1699 // set size of new created shell view windows
1700 resize_children();
1701
1702 TCHAR path[MAX_PATH];
1703
1704 if (entry->get_path(path, COUNTOF(path))) {
1705 String url;
1706
1707 if (path[0] == ':')
1708 url.printf(TEXT("shell://%s"), path);
1709 else
1710 url.printf(TEXT("file://%s"), path);
1711
1712 set_url(url);
1713 }
1714 }
1715
1716 void SDIMainFrame::set_url(LPCTSTR url)
1717 {
1718 if (_url != url) {
1719 _url = url;
1720
1721 SetWindowText(_haddressedit, url); //SendMessage(_hwndFrame, PM_URL_CHANGED, 0, (LPARAM)url);
1722 }
1723 }
1724
1725 void SDIMainFrame::jump_to(LPCTSTR path, int mode)
1726 {/*@@todo
1727 if (_shellBrowser.get() && (_shellpath_info._open_mode&~OWM_PIDL)==(mode&~OWM_PIDL)) {
1728 _shellBrowser->jump_to(path);
1729
1730 _shellpath_info._shell_path = path;
1731 } else */{
1732 _shellpath_info._open_mode = mode;
1733 _shellpath_info._shell_path = path;
1734
1735 update_shell_browser();
1736 }
1737 }
1738
1739 void SDIMainFrame::jump_to(LPCITEMIDLIST path, int mode)
1740 {
1741 if (_shellBrowser.get() && (_shellpath_info._open_mode&~OWM_PIDL)==(mode&~OWM_PIDL)) {
1742 ShellPath shell_path = path;
1743
1744 _shellBrowser->jump_to(shell_path);
1745
1746 _shellpath_info._shell_path = shell_path;
1747 } else {
1748 _shellpath_info._open_mode = mode;
1749 _shellpath_info._shell_path = path;
1750
1751 update_shell_browser();
1752 }
1753 }