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