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 } 1694