2 * Copyright 2003, 2004, 2005 Martin Fuchs
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.
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.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 // Martin Fuchs, 23.07.2003
31 /* We can't include webchild.h here - otherwise MinGW produces errors like: "multiple definition of `QACONTAINERFLAGS'"
34 extern HWND
create_webchildwindow(const WebChildWndInfo
& info
);
36 #include "../resource.h"
38 #include "../dialogs/settings.h" // for MdiSdiDlg
41 HWND
MainFrameBase::Create(const ExplorerCmd
& cmd
)
47 hFrame
= MDIMainFrame::Create();
50 hFrame
= SDIMainFrame::Create();
53 HWND hwndOld
= g_Globals
._hMainWnd
;
55 g_Globals
._hMainWnd
= hFrame
;
58 DestroyWindow(hwndOld
);
60 ShowWindow(hFrame
, cmd
._cmdShow
);
63 // Open the first child window after initializing the application
64 if (cmd
.IsValidPath()) {
65 // We use the static s_path variable to store the path string in order
66 // to avoid accessing prematurely freed memory in the PostMessage handlers.
67 static String s_path
= cmd
._path
;
69 PostMessage(hFrame
, PM_OPEN_WINDOW
, cmd
._flags
, (LPARAM
)(LPCTSTR
)s_path
);
71 PostMessage(hFrame
, PM_OPEN_WINDOW
, OWM_EXPLORE
|OWM_DETAILS
, 0);
78 int MainFrameBase::OpenShellFolders(LPIDA pida
, HWND hFrameWnd
)
82 LPCITEMIDLIST parent_pidl
= (LPCITEMIDLIST
) ((LPBYTE
)pida
+pida
->aoffset
[0]);
83 ShellFolder
folder(parent_pidl
);
84 LOG(FmtString(TEXT("MainFrameBase::OpenShellFolders(): parent_pidl=%s"), (LPCTSTR
)FileSysShellPath(parent_pidl
)));
86 for(int i
=pida
->cidl
; i
>0; --i
) {
87 LPCITEMIDLIST pidl
= (LPCITEMIDLIST
) ((LPBYTE
)pida
+pida
->aoffset
[i
]);
89 SFGAOF attribs
= SFGAO_FOLDER
;
90 HRESULT hr
= folder
->GetAttributesOf(1, &pidl
, &attribs
);
93 if (attribs
& SFGAO_FOLDER
) {
95 XMLPos explorer_options
= g_Globals
.get_cfg("general/explorer");
97 bool mdi
= XMLBool(explorer_options
, "mdi", true);
98 bool separateFolders
= XMLBool(explorer_options
, "separate-folders", true);
100 ShellPath pidl_abs
= ShellPath(pidl
).create_absolute_pidl(parent_pidl
);
101 LOG(FmtString(TEXT("MainFrameBase::OpenShellFolders(): pidl_abs=%s"), (LPCTSTR
)FileSysShellPath(pidl_abs
)));
103 if (hFrameWnd
&& (mdi
|| !separateFolders
)) {
104 int flags
= OWM_PIDL
;
107 flags
|= OWM_SEPARATE
;
109 if (SendMessage(hFrameWnd
, PM_OPEN_WINDOW
, flags
, (LPARAM
)(LPCITEMIDLIST
)pidl_abs
))
115 hwnd
= MDIMainFrame::Create(pidl_abs
, 0);
118 hwnd
= SDIMainFrame::Create(pidl_abs
, 0);
123 } catch(COMException
& e
) {
124 HandleException(e
, g_Globals
._hMainWnd
);
127 else { // !(attribs & SFGAO_FOLDER))
128 SHELLEXECUTEINFOA shexinfo;
130 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOA);
131 shexinfo.fMask = SEE_MASK_INVOKEIDLIST;
132 shexinfo.hwnd = NULL;
133 shexinfo.lpVerb = NULL;
134 shexinfo.lpFile = NULL;
135 shexinfo.lpParameters = NULL;
136 shexinfo.lpDirectory = NULL;
137 shexinfo.nShow = SW_NORMAL;
138 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
140 if (ShellExecuteExA(&shexinfo))
143 ILFree((LPITEMIDLIST)shexinfo.lpIDList);
151 MainFrameBase::MainFrameBase(HWND hwnd
)
154 _himl
= ImageList_Create(GetSystemMetrics(SM_CXSMICON
), GetSystemMetrics(SM_CYSMICON
), ILC_MASK
|ILC_COLOR24
, 2, 0);
156 _hMenuFrame
= GetMenu(hwnd
);
157 _hMenuWindow
= GetSubMenu(_hMenuFrame
, GetMenuItemCount(_hMenuFrame
)-3);
159 _menu_info
._hMenuView
= GetSubMenu(_hMenuFrame
, 1);
161 _hAccel
= LoadAccelerators(g_Globals
._hInstance
, MAKEINTRESOURCE(IDA_EXPLORER
));
164 TBBUTTON toolbarBtns
[] = {
166 {0, 0, 0, BTNS_SEP
, {0, 0}, 0, 0},
168 {7, ID_GO_BACK
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0, 0}, 0, 0},
169 {8, ID_GO_FORWARD
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0, 0}, 0, 0},
170 {9, ID_GO_UP
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0, 0}, 0, 0},
171 {10, ID_GO_HOME
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0, 0}, 0, 0},
172 {11, ID_GO_SEARCH
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0, 0}, 0, 0},
173 {12, ID_REFRESH
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0, 0}, 0, 0},
174 {13, ID_STOP
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0, 0}, 0, 0}
177 _htoolbar
= CreateToolbarEx(hwnd
,
179 CCS_NOPARENTALIGN
|CCS_NORESIZE
|
181 WS_CHILD
|WS_VISIBLE
, IDW_TOOLBAR
, 2, g_Globals
._hInstance
, IDB_TOOLBAR
,
182 toolbarBtns
, sizeof(toolbarBtns
)/sizeof(TBBUTTON
),
183 16, 15, 16, 15, sizeof(TBBUTTON
));
185 CheckMenuItem(_menu_info
._hMenuView
, ID_VIEW_TOOL_BAR
, MF_BYCOMMAND
|MF_CHECKED
);
188 // address & command bar
189 WindowCanvas
canvas(hwnd
);
190 RECT rect
= {0, 0, 0, 0};
191 DrawText(canvas
, TEXT("My"), -1, &rect
, DT_SINGLELINE
|DT_NOPREFIX
|DT_CALCRECT
);
192 HFONT hfont
= GetStockFont(DEFAULT_GUI_FONT
);
194 _haddressedit
= CreateWindow(TEXT("EDIT"), NULL
, WS_CHILD
|WS_VISIBLE
, 0, 0, 0, rect
.bottom
,
195 hwnd
, (HMENU
)IDW_ADDRESSBAR
, g_Globals
._hInstance
, 0);
196 SetWindowFont(_haddressedit
, hfont
, FALSE
);
197 new EditController(_haddressedit
);
199 _hcommandedit
= CreateWindow(TEXT("EDIT"), TEXT("> "), WS_CHILD
|WS_VISIBLE
, 0, 0, 0, rect
.bottom
,
200 hwnd
, (HMENU
)IDW_COMMANDBAR
, g_Globals
._hInstance
, 0);
201 SetWindowFont(_hcommandedit
, hfont
, FALSE
);
202 new EditController(_hcommandedit
);
204 /* CreateStatusWindow does not accept WS_BORDER
205 _hstatusbar = CreateWindowEx(WS_EX_NOPARENTNOTIFY, STATUSCLASSNAME, 0,
206 WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_BORDER|CCS_NODIVIDER, 0,0,0,0,
207 hwnd, (HMENU)IDW_STATUSBAR, g_Globals._hInstance, 0);*/
209 _hstatusbar
= CreateStatusWindow(WS_CHILD
|WS_VISIBLE
, 0, hwnd
, IDW_STATUSBAR
);
210 CheckMenuItem(_menu_info
._hMenuView
, ID_VIEW_STATUSBAR
, MF_BYCOMMAND
|MF_CHECKED
);
212 _hsidebar
= CreateWindowEx(WS_EX_STATICEDGE
, WC_TREEVIEW
, TEXT("Sidebar"),
213 WS_CHILD
|WS_TABSTOP
|WS_BORDER
|/*WS_VISIBLE|*/WS_CHILD
|TVS_HASLINES
|TVS_HASBUTTONS
|TVS_SHOWSELALWAYS
|TVS_INFOTIP
,
214 -1, -1, 200, 0, _hwnd
, (HMENU
)IDW_SIDEBAR
, g_Globals
._hInstance
, 0);
216 _himl_old
= TreeView_SetImageList(_hsidebar
, _himl
, TVSIL_NORMAL
);
218 CheckMenuItem(_menu_info
._hMenuView
, ID_VIEW_SIDE_BAR
, MF_BYCOMMAND
|MF_UNCHECKED
/*MF_CHECKED*/);
221 // create rebar window to manage toolbar and drivebar
223 _hwndrebar
= CreateWindowEx(WS_EX_TOOLWINDOW
, REBARCLASSNAME
, NULL
,
224 WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CLIPCHILDREN
|
225 RBS_VARHEIGHT
|RBS_AUTOSIZE
|RBS_DBLCLKTOGGLE
|
226 CCS_NODIVIDER
|CCS_NOPARENTALIGN
,
227 0, 0, 0, 0, _hwnd
, 0, g_Globals
._hInstance
, 0);
229 int btn_hgt
= HIWORD(SendMessage(_htoolbar
, TB_GETBUTTONSIZE
, 0, 0));
231 REBARBANDINFO rbBand
;
233 rbBand
.cbSize
= sizeof(REBARBANDINFO
);
234 rbBand
.fMask
= RBBIM_TEXT
|RBBIM_STYLE
|RBBIM_CHILD
|RBBIM_CHILDSIZE
|RBBIM_SIZE
;
235 #ifndef RBBS_HIDETITLE // missing in MinGW headers as of 25.02.2004
236 #define RBBS_HIDETITLE 0x400
238 rbBand
.fStyle
= RBBS_CHILDEDGE
|RBBS_GRIPPERALWAYS
|RBBS_HIDETITLE
;
240 rbBand
.cxMinChild
= 0;
241 rbBand
.cyMinChild
= 0;
243 rbBand
.cyMaxChild
= 0;
244 rbBand
.cyIntegral
= btn_hgt
;
246 rbBand
.lpText
= NULL
;//TEXT("Toolbar");
247 rbBand
.hwndChild
= _htoolbar
;
248 rbBand
.cxMinChild
= 0;
249 rbBand
.cyMinChild
= btn_hgt
+ 4;
251 SendMessage(_hwndrebar
, RB_INSERTBAND
, (WPARAM
)-1, (LPARAM
)&rbBand
);
256 MainFrameBase::~MainFrameBase()
258 (void)TreeView_SetImageList(_hsidebar
, _himl_old
, TVSIL_NORMAL
);
259 ImageList_Destroy(_himl
);
261 // don't exit desktop when closing file manager window
262 if (!g_Globals
._desktop_mode
)
263 if (g_Globals
._hMainWnd
== _hwnd
) // don't quit when switching between MDI and SDI mode
268 LRESULT
MainFrameBase::WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
272 if (ProcessMessage(nmsg
, wparam
, lparam
, &res
))
275 return super::WndProc(nmsg
, wparam
, lparam
);
278 bool MainFrameBase::ProcessMessage(UINT nmsg
, WPARAM wparam
, LPARAM lparam
, LRESULT
* pres
)
281 case PM_TRANSLATE_MSG
:
282 *pres
= TranslateMsg((MSG
*)lparam
);
286 if (wparam
) // trigger child resizing after window creation - now we can succesfully call IsWindowVisible()
287 resize_frame_client();
288 return false; // goto def;
291 DestroyWindow(_hwnd
);
292 g_Globals
._hMainWnd
= 0;
299 resize_frame(LOWORD(lparam
), HIWORD(lparam
));
300 break; // do not pass message to DefFrameProc
302 case WM_GETMINMAXINFO
: {
303 LPMINMAXINFO lpmmi
= (LPMINMAXINFO
)lparam
;
305 lpmmi
->ptMaxTrackSize
.x
<<= 1;/*2*GetSystemMetrics(SM_CXSCREEN) / SM_CXVIRTUALSCREEN */
306 lpmmi
->ptMaxTrackSize
.y
<<= 1;/*2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN */
309 case PM_FRM_CALC_CLIENT
:
310 frame_get_clientspace((PRECT
)lparam
);
314 case PM_FRM_GET_MENUINFO
:
315 *pres
= (LPARAM
)&_menu_info
;
318 case PM_GET_CONTROLWINDOW
:
319 if (wparam
== FCW_STATUS
) {
320 *pres
= (LRESULT
)(HWND
)_hstatusbar
;
325 case PM_SETSTATUSTEXT
:
326 SendMessage(_hstatusbar
, SB_SETTEXT
, 0, lparam
);
330 SetWindowText(_haddressedit
, (LPCTSTR
)lparam
);
341 BOOL
MainFrameBase::TranslateMsg(MSG
* pmsg
)
343 if (TranslateAccelerator(_hwnd
, _hAccel
, pmsg
))
350 int MainFrameBase::Command(int id
, int code
)
352 CONTEXT("MainFrameBase::Command()");
356 SendMessage(_hwnd
, WM_CLOSE
, 0, 0);
359 case ID_VIEW_TOOL_BAR
:
360 toggle_child(_hwnd
, id
, _htoolbar
, 0);
363 case ID_VIEW_STATUSBAR
:
364 toggle_child(_hwnd
, id
, _hstatusbar
);
367 case ID_VIEW_SIDE_BAR
:
368 // lazy initialization
369 if (!TreeView_GetCount(_hsidebar
))
372 toggle_child(_hwnd
, id
, _hsidebar
);
376 ExecuteDialog dlg
= {{0}, 0};
378 if (DialogBoxParam(g_Globals
._hInstance
, MAKEINTRESOURCE(IDD_EXECUTE
), _hwnd
, ExecuteDialog::WndProc
, (LPARAM
)&dlg
) == IDOK
) {
379 CONTEXT("ID_EXECUTE - ShellExecute()");
381 HINSTANCE hinst
= ShellExecute(_hwnd
, NULL
/*operation*/, dlg
.cmd
/*file*/, NULL
/*parameters*/, NULL
/*dir*/, dlg
.cmdshow
);
383 if ((int)hinst
<= 32)
384 display_error(_hwnd
, GetLastError());
389 WinHelp(_hwnd
, TEXT("explorer")/*file explorer.hlp*/, HELP_INDEX
, 0);
392 case ID_VIEW_FULLSCREEN
:
393 CheckMenuItem(_menu_info
._hMenuView
, id
, toggle_fullscreen()?MF_CHECKED
:0);
396 case ID_TOOLS_OPTIONS
:
397 Dialog::DoModal(IDD_MDI_SDI
, WINDOW_CREATOR(MdiSdiDlg
), _hwnd
);
400 case ID_ABOUT_WINDOWS
:
401 ShellAbout(_hwnd
, ResString(IDS_TITLE
), NULL
, 0);
404 case ID_ABOUT_EXPLORER
:
405 explorer_about(_hwnd
);
408 case ID_EXPLORER_FAQ
:
409 launch_file(_hwnd
, TEXT("http://www.sky.franken.de/explorer/"), SW_SHOW
);
414 TCHAR url
[BUFFER_LEN
];
416 if (GetWindowText(_haddressedit
, url
, BUFFER_LEN
))
423 ExecuteCommandbar(NULL
);
427 return 1; // no command handlers in Window::Command()
434 void MainFrameBase::ExecuteCommandbar(LPCTSTR dir
)
436 TCHAR cmd
[BUFFER_LEN
];
438 if (GetWindowText(_hcommandedit
, cmd
, BUFFER_LEN
)) {
439 CONTEXT("ExecuteCommandbar - ShellExecute()");
441 // remove command prompt from 'cmd' string
451 // remove "file://" from directory URL
452 if (!_tcsnicmp(dir
, TEXT("file://"), 7))
456 ///@todo use SHGetFileInfo() with SHGFI_EXETYPE flag to determine EXE type and open console window
458 HINSTANCE hinst
= ShellExecute(_hwnd
, NULL
, p
, NULL
, dir
, SW_SHOWNORMAL
);
460 if ((int)hinst
<= 32)
461 display_error(_hwnd
, GetLastError());
466 int MainFrameBase::Notify(int id
, NMHDR
* pnmh
)
469 // resize children windows when the rebar size changes
471 resize_frame_client();
474 case TVN_GETINFOTIP
: {
475 NMTVGETINFOTIP
* pnmgit
= (NMTVGETINFOTIP
*)pnmh
;
477 if (pnmgit
->lParam
) {
478 const BookmarkNode
& node
= *(BookmarkNode
*)pnmgit
->lParam
;
480 if (node
._type
== BookmarkNode::BMNT_FOLDER
) {
481 // display tooltips for bookmark folders
482 if (!node
._pfolder
->_description
.empty())
483 lstrcpyn(pnmgit
->pszText
, node
._pfolder
->_description
.c_str(), pnmgit
->cchTextMax
);
484 } else if (node
._type
== BookmarkNode::BMNT_BOOKMARK
) {
485 // display tooltips for bookmark folders
486 String txt
= node
._pbookmark
->_description
;
488 if (!node
._pbookmark
->_url
.empty()) {
492 txt
+= node
._pbookmark
->_url
;
495 lstrcpyn(pnmgit
->pszText
, txt
.c_str(), pnmgit
->cchTextMax
);
501 HTREEITEM hitem
= TreeView_GetSelection(_hsidebar
);
502 LPARAM lparam
= TreeView_GetItemData(_hsidebar
, hitem
);
505 const BookmarkNode
& node
= *(BookmarkNode
*)lparam
;
507 if (node
._type
== BookmarkNode::BMNT_BOOKMARK
) {
508 bool new_window
= GetAsyncKeyState(VK_SHIFT
)<0;
510 go_to(node
._pbookmark
->_url
, new_window
);
520 void MainFrameBase::resize_frame(int cx
, int cy
)
523 return; // avoid resizing children when receiving RBN_AUTOSIZE while getting minimized
525 RECT rect
= {0, 0, cx
, cy
};
528 int height
= ClientRect(_hwndrebar
).bottom
;
529 MoveWindow(_hwndrebar
, rect
.left
, rect
.top
, rect
.right
-rect
.left
, height
, TRUE
);
532 if (IsWindowVisible(_htoolbar
)) {
533 SendMessage(_htoolbar
, WM_SIZE
, 0, 0);
534 WindowRect
rt(_htoolbar
);
535 rect
.top
= rt
.bottom
;
536 // rect.bottom -= rt.bottom;
540 if (IsWindowVisible(_hstatusbar
)) {
541 int parts
[] = {300, 500};
543 SendMessage(_hstatusbar
, WM_SIZE
, 0, 0);
544 SendMessage(_hstatusbar
, SB_SETPARTS
, 2, (LPARAM
)&parts
);
545 ClientRect
rt(_hstatusbar
);
546 rect
.bottom
-= rt
.bottom
;
549 if (IsWindowVisible(_haddressedit
) || IsWindowVisible(_hcommandedit
)) {
550 ClientRect
rt(_haddressedit
);
551 rect
.bottom
-= rt
.bottom
;
553 int mid
= (rect
.right
-rect
.left
) / 2; ///@todo use split bar
554 SetWindowPos(_haddressedit
, 0, 0, rect
.bottom
, mid
, rt
.bottom
, SWP_NOACTIVATE
|SWP_NOZORDER
);
555 SetWindowPos(_hcommandedit
, 0, mid
+1, rect
.bottom
, rect
.right
-(mid
+1), rt
.bottom
, SWP_NOACTIVATE
|SWP_NOZORDER
);
558 if (IsWindowVisible(_hsidebar
)) {
559 WindowRect
rt(_hsidebar
);
560 rect
.left
+= rt
.right
-rt
.left
;
562 SetWindowPos(_hsidebar
, 0, -1, rect
.top
-1, rt
.right
-rt
.left
, rect
.bottom
-rect
.top
+1, SWP_NOACTIVATE
|SWP_NOZORDER
);
566 void MainFrameBase::resize_frame_client()
568 ClientRect
rect(_hwnd
);
570 resize_frame(rect
.right
, rect
.bottom
);
573 void MainFrameBase::frame_get_clientspace(PRECT prect
)
575 if (!IsIconic(_hwnd
))
576 GetClientRect(_hwnd
, prect
);
580 GetWindowPlacement(_hwnd
, &wp
);
582 prect
->left
= prect
->top
= 0;
583 prect
->right
= wp
.rcNormalPosition
.right
-wp
.rcNormalPosition
.left
-
584 2*(GetSystemMetrics(SM_CXSIZEFRAME
)+GetSystemMetrics(SM_CXEDGE
));
585 prect
->bottom
= wp
.rcNormalPosition
.bottom
-wp
.rcNormalPosition
.top
-
586 2*(GetSystemMetrics(SM_CYSIZEFRAME
)+GetSystemMetrics(SM_CYEDGE
))-
587 GetSystemMetrics(SM_CYCAPTION
)-GetSystemMetrics(SM_CYMENUSIZE
);
590 if (IsWindowVisible(_htoolbar
)) {
591 ClientRect
rt(_htoolbar
);
592 prect
->top
+= rt
.bottom
+2;
595 if (IsWindowVisible(_hstatusbar
)) {
596 ClientRect
rt(_hstatusbar
);
597 prect
->bottom
-= rt
.bottom
;
601 BOOL
MainFrameBase::toggle_fullscreen()
605 if ((_fullscreen
._mode
=!_fullscreen
._mode
)) {
606 GetWindowRect(_hwnd
, &_fullscreen
._orgPos
);
607 _fullscreen
._wasZoomed
= IsZoomed(_hwnd
);
609 Frame_CalcFrameClient(_hwnd
, &rt
);
610 ClientToScreen(_hwnd
, (LPPOINT
)&rt
.left
);
611 ClientToScreen(_hwnd
, (LPPOINT
)&rt
.right
);
613 rt
.left
= _fullscreen
._orgPos
.left
-rt
.left
;
614 rt
.top
= _fullscreen
._orgPos
.top
-rt
.top
;
615 rt
.right
= GetSystemMetrics(SM_CXSCREEN
)+_fullscreen
._orgPos
.right
-rt
.right
;
616 rt
.bottom
= GetSystemMetrics(SM_CYSCREEN
)+_fullscreen
._orgPos
.bottom
-rt
.bottom
;
618 MoveWindow(_hwnd
, rt
.left
, rt
.top
, rt
.right
-rt
.left
, rt
.bottom
-rt
.top
, TRUE
);
620 MoveWindow(_hwnd
, _fullscreen
._orgPos
.left
, _fullscreen
._orgPos
.top
,
621 _fullscreen
._orgPos
.right
-_fullscreen
._orgPos
.left
,
622 _fullscreen
._orgPos
.bottom
-_fullscreen
._orgPos
.top
, TRUE
);
624 if (_fullscreen
._wasZoomed
)
625 ShowWindow(_hwnd
, WS_MAXIMIZE
);
628 return _fullscreen
._mode
;
631 void MainFrameBase::fullscreen_move()
634 GetWindowRect(_hwnd
, &pos
);
636 Frame_CalcFrameClient(_hwnd
, &rt
);
637 ClientToScreen(_hwnd
, (LPPOINT
)&rt
.left
);
638 ClientToScreen(_hwnd
, (LPPOINT
)&rt
.right
);
640 rt
.left
= pos
.left
-rt
.left
;
641 rt
.top
= pos
.top
-rt
.top
;
642 rt
.right
= GetSystemMetrics(SM_CXSCREEN
)+pos
.right
-rt
.right
;
643 rt
.bottom
= GetSystemMetrics(SM_CYSCREEN
)+pos
.bottom
-rt
.bottom
;
645 MoveWindow(_hwnd
, rt
.left
, rt
.top
, rt
.right
-rt
.left
, rt
.bottom
-rt
.top
, TRUE
);
649 void MainFrameBase::toggle_child(HWND hwnd
, UINT cmd
, HWND hchild
, int band_idx
)
651 BOOL vis
= IsWindowVisible(hchild
);
653 CheckMenuItem(_menu_info
._hMenuView
, cmd
, vis
?MF_BYCOMMAND
:MF_BYCOMMAND
|MF_CHECKED
);
656 SendMessage(_hwndrebar
, RB_SHOWBAND
, band_idx
, !vis
);
658 ShowWindow(hchild
, vis
? SW_HIDE
: SW_SHOW
);
660 if (_fullscreen
._mode
)
663 resize_frame_client();
666 void MainFrameBase::FillBookmarks()
668 HiddenWindow
hide(_hsidebar
);
669 WindowCanvas
canvas(_hwnd
);
671 TreeView_DeleteAllItems(_hsidebar
);
673 g_Globals
._icon_cache
.get_icon(ICID_FAVORITES
).add_to_imagelist(_himl
, canvas
);
674 g_Globals
._icon_cache
.get_icon(ICID_BOOKMARK
).add_to_imagelist(_himl
, canvas
);
675 ImageList_AddAlphaIcon(_himl
, SmallIcon(IDI_DOT
), GetStockBrush(WHITE_BRUSH
), canvas
);
676 g_Globals
._icon_cache
.get_icon(ICID_FOLDER
).add_to_imagelist(_himl
, canvas
);
677 g_Globals
._icon_cache
.get_icon(ICID_FOLDER
).add_to_imagelist(_himl
, canvas
);
681 tvi
.hParent
= TVI_ROOT
;
682 tvi
.hInsertAfter
= TVI_LAST
;
683 tvi
.item
.mask
= TVIF_TEXT
|TVIF_IMAGE
|TVIF_SELECTEDIMAGE
;
684 ResString
sFavorites(IDS_FAVORITES
);
685 tvi
.item
.pszText
= sFavorites
.str();
686 tvi
.item
.iSelectedImage
= tvi
.item
.iImage
= 0;
688 HTREEITEM hitem_bookmarks
= TreeView_InsertItem(_hsidebar
, &tvi
);
690 g_Globals
._favorites
.fill_tree(_hsidebar
, hitem_bookmarks
, _himl
, canvas
);
692 TreeView_Expand(_hsidebar
, hitem_bookmarks
, TVE_EXPAND
);
696 bool MainFrameBase::go_to(LPCTSTR url
, bool new_window
)
698 ///@todo SDI implementation
706 MDIMainFrame::MDIMainFrame(HWND hwnd
)
709 TBBUTTON mdiBtns
[] = {
710 {0, 0, 0, BTNS_SEP
, {0, 0}, 0, 0},
711 {0, ID_WINDOW_NEW
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0, 0}, 0, 0},
712 {1, ID_WINDOW_CASCADE
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0, 0}, 0, 0},
713 {2, ID_WINDOW_TILE_HORZ
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0, 0}, 0, 0},
714 {3, ID_WINDOW_TILE_VERT
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0, 0}, 0, 0}
717 SendMessage(_htoolbar
, TB_ADDBUTTONS
, sizeof(mdiBtns
)/sizeof(TBBUTTON
), (LPARAM
)&mdiBtns
);
719 CLIENTCREATESTRUCT ccs
;
721 ccs
.hWindowMenu
= _hMenuWindow
;
722 ccs
.idFirstChild
= IDW_FIRST_CHILD
;
724 _hmdiclient
= CreateWindowEx(0, TEXT("MDICLIENT"), NULL
,
725 WS_CHILD
|WS_CLIPCHILDREN
|WS_VSCROLL
|WS_HSCROLL
|WS_VISIBLE
|WS_BORDER
,
727 hwnd
, 0, g_Globals
._hInstance
, &ccs
);
729 TBBUTTON extraBtns
= {0, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0, 0}, 0, 0};
732 _hextrabar
= CreateToolbarEx(hwnd
,
733 CCS_NOPARENTALIGN
|CCS_NORESIZE
|
734 WS_CHILD
|WS_VISIBLE
|CCS_NOMOVEY
|TBSTYLE_LIST
,
735 IDW_EXTRABAR
, 2, g_Globals
._hInstance
, IDB_DRIVEBAR
, NULL
, 0,
736 16, 13, 16, 13, sizeof(TBBUTTON
));
738 _hextrabar
= CreateToolbarEx(hwnd
,
739 WS_CHILD
|WS_VISIBLE
|CCS_NOMOVEY
|TBSTYLE_LIST
,
740 IDW_EXTRABAR
, 2, g_Globals
._hInstance
, IDB_DRIVEBAR
, &extraBtns
, 1,
741 16, 13, 16, 13, sizeof(TBBUTTON
));
744 CheckMenuItem(_menu_info
._hMenuView
, ID_VIEW_EXTRA_BAR
, MF_BYCOMMAND
|MF_CHECKED
);
747 extraBtns
.fsStyle
= BTNS_BUTTON
;
750 // insert unix file system button
751 extraBtns
.iString
= SendMessage(_hextrabar
, TB_ADDSTRING
, 0, (LPARAM
)TEXT("/\0"));
752 extraBtns
.idCommand
= ID_DRIVE_UNIX_FS
;
753 SendMessage(_hextrabar
, TB_INSERTBUTTON
, INT_MAX
, (LPARAM
)&extraBtns
);
756 // insert explorer window button
757 extraBtns
.iString
= SendMessage(_hextrabar
, TB_ADDSTRING
, 0, (LPARAM
)TEXT("Explore\0"));
758 extraBtns
.idCommand
= ID_DRIVE_DESKTOP
;
759 SendMessage(_hextrabar
, TB_INSERTBUTTON
, INT_MAX
, (LPARAM
)&extraBtns
);
761 // insert shell namespace button
762 extraBtns
.iString
= SendMessage(_hextrabar
, TB_ADDSTRING
, 0, (LPARAM
)TEXT("Shell\0"));
763 extraBtns
.idCommand
= ID_DRIVE_SHELL_NS
;
764 extraBtns
.iBitmap
= 6;
765 SendMessage(_hextrabar
, TB_INSERTBUTTON
, INT_MAX
, (LPARAM
)&extraBtns
);
767 // insert web control button
768 extraBtns
.iString
= SendMessage(_hextrabar
, TB_ADDSTRING
, 0, (LPARAM
)TEXT("Web\0"));
769 extraBtns
.idCommand
= ID_WEB_WINDOW
;
770 extraBtns
.iBitmap
= 7;
771 SendMessage(_hextrabar
, TB_INSERTBUTTON
, INT_MAX
, (LPARAM
)&extraBtns
);
773 if ((HIWORD(GetVersion())>>14) == W_VER_NT
) {
774 // insert NT object namespace button
775 extraBtns
.iString
= SendMessage(_hextrabar
, TB_ADDSTRING
, 0, (LPARAM
)TEXT("NT Obj\0"));
776 extraBtns
.idCommand
= ID_DRIVE_NTOBJ_NS
;
777 extraBtns
.iBitmap
= 8;
778 SendMessage(_hextrabar
, TB_INSERTBUTTON
, INT_MAX
, (LPARAM
)&extraBtns
);
781 // insert Registry button
782 extraBtns
.iString
= SendMessage(_hextrabar
, TB_ADDSTRING
, 0, (LPARAM
)TEXT("Reg.\0"));
783 extraBtns
.idCommand
= ID_DRIVE_REGISTRY
;
784 extraBtns
.iBitmap
= 9;
785 SendMessage(_hextrabar
, TB_INSERTBUTTON
, INT_MAX
, (LPARAM
)&extraBtns
);
788 // insert FAT direct file system access button
789 extraBtns
.iString
= SendMessage(_hextrabar
, TB_ADDSTRING
, 0, (LPARAM
)TEXT("FAT\0"));
790 extraBtns
.idCommand
= ID_DRIVE_FAT
;
791 extraBtns
.iBitmap
= 10;
792 SendMessage(_hextrabar
, TB_INSERTBUTTON
, INT_MAX
, (LPARAM
)&extraBtns
);
796 TBBUTTON drivebarBtn
= {0, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0, 0}, 0, 0};
800 _hdrivebar
= CreateToolbarEx(hwnd
,
801 CCS_NOPARENTALIGN
|CCS_NORESIZE
|
802 WS_CHILD
|WS_VISIBLE
|CCS_NOMOVEY
|TBSTYLE_LIST
,
803 IDW_DRIVEBAR
, 2, g_Globals
._hInstance
, IDB_DRIVEBAR
, NULL
, 0,
804 16, 13, 16, 13, sizeof(TBBUTTON
));
806 _hdrivebar
= CreateToolbarEx(hwnd
,
807 WS_CHILD
|WS_VISIBLE
|CCS_NOMOVEY
|TBSTYLE_LIST
,
808 IDW_DRIVEBAR
, 2, g_Globals
._hInstance
, IDB_DRIVEBAR
, &drivebarBtn
, 1,
809 16, 13, 16, 13, sizeof(TBBUTTON
));
812 CheckMenuItem(_menu_info
._hMenuView
, ID_VIEW_DRIVE_BAR
, MF_BYCOMMAND
|MF_CHECKED
);
815 GetLogicalDriveStrings(BUFFER_LEN
, _drives
);
817 // register windows drive root strings
818 SendMessage(_hdrivebar
, TB_ADDSTRING
, 0, (LPARAM
)_drives
);
820 drivebarBtn
.fsStyle
= BTNS_BUTTON
;
821 drivebarBtn
.idCommand
= ID_DRIVE_FIRST
;
823 for(p
=_drives
; *p
; ) {
824 switch(GetDriveType(p
)) {
825 case DRIVE_REMOVABLE
: drivebarBtn
.iBitmap
= 1; break;
826 case DRIVE_CDROM
: drivebarBtn
.iBitmap
= 3; break;
827 case DRIVE_REMOTE
: drivebarBtn
.iBitmap
= 4; break;
828 case DRIVE_RAMDISK
: drivebarBtn
.iBitmap
= 5; break;
829 default:/*DRIVE_FIXED*/ drivebarBtn
.iBitmap
= 2;
832 SendMessage(_hdrivebar
, TB_INSERTBUTTON
, INT_MAX
, (LPARAM
)&drivebarBtn
);
833 ++drivebarBtn
.idCommand
;
834 ++drivebarBtn
.iString
;
841 int btn_hgt
= HIWORD(SendMessage(_htoolbar
, TB_GETBUTTONSIZE
, 0, 0));
843 REBARBANDINFO rbBand
;
845 rbBand
.cbSize
= sizeof(REBARBANDINFO
);
846 rbBand
.fMask
= RBBIM_TEXT
|RBBIM_STYLE
|RBBIM_CHILD
|RBBIM_CHILDSIZE
|RBBIM_SIZE
;
847 #ifndef RBBS_HIDETITLE // missing in MinGW headers as of 25.02.2004
848 #define RBBS_HIDETITLE 0x400
850 rbBand
.fStyle
= RBBS_CHILDEDGE
|RBBS_GRIPPERALWAYS
|RBBS_HIDETITLE
;
852 rbBand
.lpText
= TEXT("Extras");
853 rbBand
.hwndChild
= _hextrabar
;
854 rbBand
.cxMinChild
= 0;
855 rbBand
.cyMinChild
= btn_hgt
+ 4;
857 SendMessage(_hwndrebar
, RB_INSERTBAND
, (WPARAM
)-1, (LPARAM
)&rbBand
);
859 rbBand
.fStyle
|= RBBS_BREAK
;
860 rbBand
.lpText
= TEXT("Drives");
861 rbBand
.hwndChild
= _hdrivebar
;
862 rbBand
.cxMinChild
= 0;
863 rbBand
.cyMinChild
= btn_hgt
+ 4;
865 SendMessage(_hwndrebar
, RB_INSERTBAND
, (WPARAM
)-1, (LPARAM
)&rbBand
);
870 HWND
MDIMainFrame::Create()
872 HMENU hMenuFrame
= LoadMenu(g_Globals
._hInstance
, MAKEINTRESOURCE(IDM_MDIFRAME
));
874 return Window::Create(WINDOW_CREATOR(MDIMainFrame
), 0,
875 (LPCTSTR
)(int)g_Globals
._hframeClass
, ResString(IDS_TITLE
), WS_OVERLAPPEDWINDOW
,
876 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
877 0/*hwndDesktop*/, hMenuFrame
);
880 HWND
MDIMainFrame::Create(LPCTSTR path
, int mode
)
882 HWND hFrame
= Create();
886 ShowWindow(hFrame
, SW_SHOW
);
888 MDIMainFrame
* pMainFrame
= GET_WINDOW(MDIMainFrame
, hFrame
);
891 pMainFrame
->CreateChild(path
, mode
);
896 HWND
MDIMainFrame::Create(LPCITEMIDLIST pidl
, int mode
)
898 HWND hFrame
= Create();
902 ShowWindow(hFrame
, SW_SHOW
);
904 MDIMainFrame
* pMainFrame
= GET_WINDOW(MDIMainFrame
, hFrame
);
907 pMainFrame
->CreateChild(pidl
, mode
);
913 ChildWindow
* MDIMainFrame::CreateChild(LPCTSTR path
, int mode
)
915 return reinterpret_cast<ChildWindow
*>(SendMessage(_hwnd
, PM_OPEN_WINDOW
, mode
, (LPARAM
)path
));
918 ChildWindow
* MDIMainFrame::CreateChild(LPCITEMIDLIST pidl
, int mode
)
920 return reinterpret_cast<ChildWindow
*>(SendMessage(_hwnd
, PM_OPEN_WINDOW
, mode
|OWM_PIDL
, (LPARAM
)pidl
));
924 BOOL
MDIMainFrame::TranslateMsg(MSG
* pmsg
)
926 if (_hmdiclient
&& TranslateMDISysAccel(_hmdiclient
, pmsg
))
929 return super::TranslateMsg(pmsg
);
932 LRESULT
MDIMainFrame::WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
935 case PM_OPEN_WINDOW
: {
936 CONTEXT("MDIMainFrame PM_OPEN_WINDOW");
938 TCHAR buffer
[MAX_PATH
];
940 ShellPath root_path
= DesktopFolderPath();
943 if (wparam
& OWM_PIDL
) {
944 // take over PIDL from lparam
945 root_path
.assign((LPCITEMIDLIST
)lparam
); // create as "rooted" window
946 FileSysShellPath
fsp(root_path
);
950 LOG(FmtString(TEXT("MDIMainFrame PM_OPEN_WINDOW: path=%s"), path
));
951 lstrcpy(buffer
, path
);
955 // take over path from lparam
956 path
= (LPCTSTR
)lparam
;
957 root_path
= path
; // create as "rooted" window
960 ///@todo read paths and window placements from registry
961 if (!GetCurrentDirectory(MAX_PATH
, buffer
))
967 if (path
&& _tcsstr(path
, TEXT("://"))) { // "http://...", "ftp://", ...
968 OBJ_CONTEXT("create WebChild window", path
);
970 return (LRESULT
)GET_WINDOW(ChildWindow
, create_webchildwindow(WebChildWndInfo(_hmdiclient
, path
)));
972 OBJ_CONTEXT("create ShellChildWndInfo", path
);
974 // Shell Namespace as default view
975 ShellChildWndInfo
create_info(_hmdiclient
, path
, root_path
);
977 create_info
._pos
.showCmd
= wparam
&OWM_SEPARATE
? SW_SHOWNORMAL
: SW_SHOWMAXIMIZED
;
978 create_info
._pos
.rcNormalPosition
.left
= CW_USEDEFAULT
;
979 create_info
._pos
.rcNormalPosition
.top
= CW_USEDEFAULT
;
980 create_info
._pos
.rcNormalPosition
.right
= CW_USEDEFAULT
;
981 create_info
._pos
.rcNormalPosition
.bottom
= CW_USEDEFAULT
;
983 create_info
._open_mode
= wparam
;
985 // FileChildWindow::create(_hmdiclient, create_info);
986 return (LRESULT
)MDIShellBrowserChild::create(create_info
);
988 return TRUE
;} // success
993 if (super::ProcessMessage(nmsg
, wparam
, lparam
, &res
))
996 return DefFrameProc(_hwnd
, _hmdiclient
, nmsg
, wparam
, lparam
);
1003 int MDIMainFrame::Command(int id
, int code
)
1005 CONTEXT("MDIMainFrame::Command()");
1007 HWND hwndClient
= (HWND
) SendMessage(_hmdiclient
, WM_MDIGETACTIVE
, 0, 0);
1010 if (SendMessage(hwndClient
, PM_DISPATCH_COMMAND
, MAKELONG(id
,code
), 0))
1013 if (id
>=ID_DRIVE_FIRST
&& id
<=ID_DRIVE_FIRST
+0xFF) {
1014 TCHAR drv
[_MAX_DRIVE
], path
[MAX_PATH
];
1015 LPCTSTR root
= _drives
;
1017 for(int i
=id
-ID_DRIVE_FIRST
; i
--; root
++)
1021 if (activate_drive_window(root
))
1024 _tsplitpath_s(root
, drv
, COUNTOF(drv
), NULL
, 0, NULL
, 0, NULL
, 0);
1026 if (!SetCurrentDirectory(drv
)) {
1027 display_error(_hwnd
, GetLastError());
1031 GetCurrentDirectory(MAX_PATH
, path
); ///@todo store last directory per drive
1033 FileChildWindow::create(FileChildWndInfo(_hmdiclient
, path
));
1039 case ID_WINDOW_NEW
: {
1040 TCHAR path
[MAX_PATH
];
1042 GetCurrentDirectory(MAX_PATH
, path
);
1044 FileChildWindow::create(FileChildWndInfo(_hmdiclient
, path
));
1047 case ID_WINDOW_CASCADE
:
1048 SendMessage(_hmdiclient
, WM_MDICASCADE
, 0, 0);
1051 case ID_WINDOW_TILE_HORZ
:
1052 SendMessage(_hmdiclient
, WM_MDITILE
, MDITILE_HORIZONTAL
, 0);
1055 case ID_WINDOW_TILE_VERT
:
1056 SendMessage(_hmdiclient
, WM_MDITILE
, MDITILE_VERTICAL
, 0);
1059 case ID_WINDOW_ARRANGE
:
1060 SendMessage(_hmdiclient
, WM_MDIICONARRANGE
, 0, 0);
1063 case ID_VIEW_EXTRA_BAR
:
1064 toggle_child(_hwnd
, id
, _hextrabar
, 1);
1067 case ID_VIEW_DRIVE_BAR
:
1068 toggle_child(_hwnd
, id
, _hdrivebar
, 2);
1072 case ID_DRIVE_UNIX_FS
: {
1073 TCHAR path
[MAX_PATH
];
1074 FileChildWindow
* child
;
1076 getcwd(path
, COUNTOF(path
));
1078 if (activate_child_window(TEXT("unixfs")))
1081 FileChildWindow::create(_hmdiclient
, FileChildWndInfo(path
));
1085 case ID_DRIVE_DESKTOP
: {
1086 TCHAR path
[MAX_PATH
];
1088 if (activate_child_window(TEXT("Desktop")))
1091 GetCurrentDirectory(MAX_PATH
, path
);
1093 MDIShellBrowserChild::create(ShellChildWndInfo(_hmdiclient
, path
, DesktopFolderPath()));
1096 case ID_DRIVE_SHELL_NS
: {
1097 TCHAR path
[MAX_PATH
];
1098 GetCurrentDirectory(MAX_PATH
, path
);
1100 if (activate_child_window(TEXT("Shell")))
1103 FileChildWindow::create(ShellChildWndInfo(_hmdiclient
, path
, DesktopFolderPath()));
1106 case ID_DRIVE_NTOBJ_NS
: {
1107 if (activate_child_window(TEXT("NTOBJ")))
1110 FileChildWindow::create(NtObjChildWndInfo(_hmdiclient
, TEXT("\\")));
1113 case ID_DRIVE_REGISTRY
: {
1114 if (activate_child_window(TEXT("Registry")))
1117 FileChildWindow::create(RegistryChildWndInfo(_hmdiclient
, TEXT("\\")));
1120 case ID_DRIVE_FAT
: {
1122 ///@todo prompt for image file
1124 if (activate_child_window(TEXT("FAT")))
1127 FileChildWindow::create(FATChildWndInfo(_hmdiclient
, TEXT("FAT Image"))); //@@
1132 create_webchildwindow(WebChildWndInfo(_hmdiclient
, TEXT("http://localhost")));
1134 create_webchildwindow(WebChildWndInfo(_hmdiclient
, TEXT("http://www.reactos.com")));
1138 case ID_EXPLORER_FAQ
:
1139 create_webchildwindow(WebChildWndInfo(_hmdiclient
, TEXT("http://www.sky.franken.de/explorer/")));
1143 MainFrameBase::Create(ExplorerCmd());
1146 case IDW_COMMANDBAR
:
1148 TCHAR url
[BUFFER_LEN
];
1151 if (GetWindowText(_haddressedit
, url
, BUFFER_LEN
))
1156 ExecuteCommandbar(dir
);
1160 ///@todo There are even more menu items!
1163 if (super::Command(id
, code
) == 0)
1166 return DefFrameProc(_hwnd
, _hmdiclient
, WM_COMMAND
, MAKELONG(id
,code
), 0);
1173 void MDIMainFrame::frame_get_clientspace(PRECT prect
)
1175 super::frame_get_clientspace(prect
);
1177 if (IsWindowVisible(_hdrivebar
)) {
1178 ClientRect
rt(_hdrivebar
);
1179 prect
->top
+= rt
.bottom
+2;
1183 void MDIMainFrame::resize_frame(int cx
, int cy
)
1186 return; // avoid resizing children when receiving RBN_AUTOSIZE while getting minimized
1188 RECT rect
= {0, 0, cx
, cy
};
1191 int height
= ClientRect(_hwndrebar
).bottom
;
1192 MoveWindow(_hwndrebar
, rect
.left
, rect
.top
, rect
.right
-rect
.left
, height
, TRUE
);
1195 if (IsWindowVisible(_htoolbar
)) {
1196 SendMessage(_htoolbar
, WM_SIZE
, 0, 0);
1197 WindowRect
rt(_htoolbar
);
1198 rect
.top
= rt
.bottom
;
1199 // rect.bottom -= rt.bottom;
1202 if (IsWindowVisible(_hextrabar
)) {
1203 SendMessage(_hextrabar
, WM_SIZE
, 0, 0);
1204 WindowRect
rt(_hextrabar
);
1205 int new_top
= --rect
.top
+ rt
.bottom
;
1206 MoveWindow(_hextrabar
, 0, rect
.top
, rt
.right
, new_top
, TRUE
);
1208 // rect.bottom -= rt.bottom;
1211 if (IsWindowVisible(_hdrivebar
)) {
1212 SendMessage(_hdrivebar
, WM_SIZE
, 0, 0);
1213 WindowRect
rt(_hdrivebar
);
1214 int new_top
= --rect
.top
+ rt
.bottom
;
1215 MoveWindow(_hdrivebar
, 0, rect
.top
, rt
.right
, new_top
, TRUE
);
1217 // rect.bottom -= rt.bottom;
1221 if (IsWindowVisible(_hstatusbar
)) {
1222 int parts
[] = {300, 500};
1224 SendMessage(_hstatusbar
, WM_SIZE
, 0, 0);
1225 SendMessage(_hstatusbar
, SB_SETPARTS
, 2, (LPARAM
)&parts
);
1226 ClientRect
rt(_hstatusbar
);
1227 rect
.bottom
-= rt
.bottom
;
1230 if (IsWindowVisible(_haddressedit
) || IsWindowVisible(_hcommandedit
)) {
1231 ClientRect
rt(_haddressedit
);
1232 rect
.bottom
-= rt
.bottom
;
1234 int mid
= (rect
.right
-rect
.left
) / 2; ///@todo use split bar
1235 SetWindowPos(_haddressedit
, 0, 0, rect
.bottom
, mid
, rt
.bottom
, SWP_NOACTIVATE
|SWP_NOZORDER
);
1236 SetWindowPos(_hcommandedit
, 0, mid
+1, rect
.bottom
, rect
.right
-(mid
+1), rt
.bottom
, SWP_NOACTIVATE
|SWP_NOZORDER
);
1239 if (IsWindowVisible(_hsidebar
)) {
1240 WindowRect
rt(_hsidebar
);
1241 rect
.left
+= rt
.right
-rt
.left
;
1243 SetWindowPos(_hsidebar
, 0, -1, rect
.top
-1, rt
.right
-rt
.left
, rect
.bottom
-rect
.top
+1, SWP_NOACTIVATE
|SWP_NOZORDER
);
1246 MoveWindow(_hmdiclient
, rect
.left
-1, rect
.top
-1, rect
.right
-rect
.left
+2, rect
.bottom
-rect
.top
+1, TRUE
);
1249 bool MDIMainFrame::activate_drive_window(LPCTSTR path
)
1251 TCHAR drv1
[_MAX_DRIVE
], drv2
[_MAX_DRIVE
];
1254 _tsplitpath_s(path
, drv1
, COUNTOF(drv1
), NULL
, 0, NULL
, 0, NULL
, 0);
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);
1261 _tsplitpath_s(child
->get_root()._path
, drv2
, COUNTOF(drv2
), NULL
, 0, NULL
, 0, NULL
, 0);
1263 if (!lstrcmpi(drv2
, drv1
)) {
1264 SendMessage(_hmdiclient
, WM_MDIACTIVATE
, (WPARAM
)child_wnd
, 0);
1266 if (IsMinimized(child_wnd
))
1267 ShowWindow(child_wnd
, SW_SHOWNORMAL
);
1277 bool MDIMainFrame::activate_child_window(LPCTSTR filesys
)
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);
1286 if (!lstrcmpi(child
->get_root()._fs
, filesys
)) {
1287 SendMessage(_hmdiclient
, WM_MDIACTIVATE
, (WPARAM
)child_wnd
, 0);
1289 if (IsMinimized(child_wnd
))
1290 ShowWindow(child_wnd
, SW_SHOWNORMAL
);
1295 ShellBrowser
* shell_child
= (ShellBrowser
*) SendMessage(child_wnd
, PM_GET_SHELLBROWSER_PTR
, 0, 0);
1298 if (!lstrcmpi(shell_child
->get_root()._fs
, filesys
)) {
1299 SendMessage(_hmdiclient
, WM_MDIACTIVATE
, (WPARAM
)child_wnd
, 0);
1301 if (IsMinimized(child_wnd
))
1302 ShowWindow(child_wnd
, SW_SHOWNORMAL
);
1313 bool MDIMainFrame::go_to(LPCTSTR url
, bool new_window
)
1316 HWND hwndClient
= (HWND
) SendMessage(_hmdiclient
, WM_MDIGETACTIVE
, 0, 0);
1319 if (SendMessage(hwndClient
, PM_JUMP_TO_URL
, 0, (LPARAM
)url
))
1323 if (CreateChild(url
))
1326 return super::go_to(url
, new_window
);
1332 SDIMainFrame::SDIMainFrame(HWND hwnd
)
1335 _split_pos
= DEFAULT_SPLIT_POS
;
1336 _last_split
= DEFAULT_SPLIT_POS
;
1338 // create image list for explorer tree view
1341 /* wait for PM_OPEN_WINDOW message before creating a shell view
1342 update_shell_browser();*/
1345 HWND
SDIMainFrame::Create()
1347 HMENU hMenuFrame
= LoadMenu(g_Globals
._hInstance
, MAKEINTRESOURCE(IDM_SDIFRAME
));
1349 return Window::Create(WINDOW_CREATOR(SDIMainFrame
), 0,
1350 (LPCTSTR
)(int)g_Globals
._hframeClass
, ResString(IDS_TITLE
), WS_OVERLAPPEDWINDOW
,
1351 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1352 0/*hwndDesktop*/, hMenuFrame
);
1355 HWND
SDIMainFrame::Create(LPCITEMIDLIST pidl
, int mode
)
1357 HWND hFrame
= Create();
1361 ShowWindow(hFrame
, SW_SHOW
);
1363 SDIMainFrame
* pFrame
= GET_WINDOW(SDIMainFrame
, hFrame
);
1366 pFrame
->jump_to(pidl
, mode
);
1371 HWND
SDIMainFrame::Create(LPCTSTR path
, int mode
)
1373 HWND hFrame
= Create();
1377 ShowWindow(hFrame
, SW_SHOW
);
1379 MDIMainFrame
* pMainFrame
= GET_WINDOW(MDIMainFrame
, hFrame
);
1382 pMainFrame
->CreateChild(path
, mode
);
1387 LRESULT
SDIMainFrame::WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
1391 resize_frame(LOWORD(lparam
), HIWORD(lparam
));
1395 PaintCanvas
canvas(_hwnd
);
1398 ClientRect
rt(_hwnd
);
1399 rt
.left
= _split_pos
-SPLIT_WIDTH
/2;
1400 rt
.right
= _split_pos
+SPLIT_WIDTH
/2+1;
1403 WindowRect
right_rect(_right_hwnd
);
1404 ScreenToClient(_hwnd
, &right_rect
);
1405 rt
.top
= right_rect
.top
;
1406 rt
.bottom
= right_rect
.bottom
;
1409 HBRUSH lastBrush
= SelectBrush(canvas
, GetStockBrush(COLOR_SPLITBAR
));
1410 Rectangle(canvas
, rt
.left
, rt
.top
-1, rt
.right
, rt
.bottom
+1);
1411 SelectObject(canvas
, lastBrush
);
1417 if (LOWORD(lparam
) == HTCLIENT
) {
1420 ScreenToClient(_hwnd
, &pt
);
1422 if (pt
.x
>=_split_pos
-SPLIT_WIDTH
/2 && pt
.x
<_split_pos
+SPLIT_WIDTH
/2+1) {
1423 SetCursor(LoadCursor(0, IDC_SIZEWE
));
1429 case WM_LBUTTONDOWN
:
1431 int x
= GET_X_LPARAM(lparam
);
1433 ClientRect
rt(_hwnd
);
1435 if (x
>=_split_pos
-SPLIT_WIDTH
/2 && x
<_split_pos
+SPLIT_WIDTH
/2+1) {
1436 _last_split
= _split_pos
;
1443 if (GetCapture() == _hwnd
)
1448 if (wparam
== VK_ESCAPE
)
1449 if (GetCapture() == _hwnd
) {
1450 _split_pos
= _last_split
;
1454 SetCursor(LoadCursor(0, IDC_ARROW
));
1459 if (GetCapture() == _hwnd
) {
1460 int x
= GET_X_LPARAM(lparam
);
1462 ClientRect
rt(_hwnd
);
1464 if (x
>=0 && x
<rt
.right
) {
1467 rt
.left
= x
-SPLIT_WIDTH
/2;
1468 rt
.right
= x
+SPLIT_WIDTH
/2+1;
1469 InvalidateRect(_hwnd
, &rt
, FALSE
);
1470 UpdateWindow(_left_hwnd
);
1471 UpdateWindow(_hwnd
);
1472 UpdateWindow(_right_hwnd
);
1477 case PM_OPEN_WINDOW
: {
1478 CONTEXT("SDIMainFrame PM_OPEN_WINDOW");
1480 TCHAR buffer
[MAX_PATH
];
1482 ShellPath root_path
= DesktopFolderPath();
1485 if (wparam
& OWM_PIDL
) {
1486 // take over PIDL from lparam
1487 root_path
.assign((LPCITEMIDLIST
)lparam
); // create as "rooted" window
1488 FileSysShellPath
fsp(root_path
);
1492 LOG(FmtString(TEXT("SDIMainFrame PM_OPEN_WINDOW: path=%s"), path
));
1493 lstrcpy(buffer
, path
);
1497 // take over path from lparam
1498 path
= (LPCTSTR
)lparam
;
1499 root_path
= path
; // create as "rooted" window
1502 ///@todo read paths and window placements from registry
1503 if (!GetCurrentDirectory(MAX_PATH
, buffer
))
1510 jump_to(root_path
, wparam
); //@todo content of 'path' not used any more
1511 return TRUE
;} // success
1514 return super::WndProc(nmsg
, wparam
, lparam
);
1520 int SDIMainFrame::Command(int id
, int code
)
1524 MainFrameBase::Create(ExplorerCmd(_url
, true));
1527 case IDW_COMMANDBAR
:
1529 ExecuteCommandbar(_url
);
1533 return super::Command(id
, code
);
1539 void SDIMainFrame::resize_frame(int cx
, int cy
)
1542 return; // avoid resizing children when receiving RBN_AUTOSIZE while getting minimized
1544 RECT rect
= {0, 0, cx
, cy
};
1547 int height
= ClientRect(_hwndrebar
).bottom
;
1548 MoveWindow(_hwndrebar
, rect
.left
, rect
.top
, rect
.right
-rect
.left
, height
, TRUE
);
1551 if (IsWindowVisible(_htoolbar
)) {
1552 SendMessage(_htoolbar
, WM_SIZE
, 0, 0);
1553 WindowRect
rt(_htoolbar
);
1554 rect
.top
= rt
.bottom
;
1555 // rect.bottom -= rt.bottom;
1559 if (IsWindowVisible(_hstatusbar
)) {
1560 int parts
[] = {300, 500};
1562 SendMessage(_hstatusbar
, WM_SIZE
, 0, 0);
1563 SendMessage(_hstatusbar
, SB_SETPARTS
, 2, (LPARAM
)&parts
);
1564 ClientRect
rt(_hstatusbar
);
1565 rect
.bottom
-= rt
.bottom
;
1568 if (IsWindowVisible(_haddressedit
) || IsWindowVisible(_hcommandedit
)) {
1569 ClientRect
rt(_haddressedit
);
1570 rect
.bottom
-= rt
.bottom
;
1572 int mid
= (rect
.right
-rect
.left
) / 2; ///@todo use split bar
1573 SetWindowPos(_haddressedit
, 0, 0, rect
.bottom
, mid
, rt
.bottom
, SWP_NOACTIVATE
|SWP_NOZORDER
);
1574 SetWindowPos(_hcommandedit
, 0, mid
+1, rect
.bottom
, rect
.right
-(mid
+1), rt
.bottom
, SWP_NOACTIVATE
|SWP_NOZORDER
);
1577 if (IsWindowVisible(_hsidebar
)) {
1578 WindowRect
rt(_hsidebar
);
1579 rect
.left
+= rt
.right
-rt
.left
;
1581 SetWindowPos(_hsidebar
, 0, -1, rect
.top
-1, rt
.right
-rt
.left
, rect
.bottom
-rect
.top
+1, SWP_NOACTIVATE
|SWP_NOZORDER
);
1589 void SDIMainFrame::resize_children()
1591 HDWP hdwp
= BeginDeferWindowPos(2);
1593 int cx
= _clnt_rect
.left
;
1596 cx
= _split_pos
+ SPLIT_WIDTH
/2;
1598 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
);
1605 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
);
1607 EndDeferWindowPos(hdwp
);
1610 void SDIMainFrame::update_clnt_rect()
1612 ClientRect
rect(_hwnd
);
1614 resize_frame(rect
.right
, rect
.bottom
);
1617 void SDIMainFrame::update_shell_browser()
1619 int split_pos
= DEFAULT_SPLIT_POS
;
1621 if (_shellBrowser
.get()) {
1622 split_pos
= _split_pos
;
1623 delete _shellBrowser
.release();
1626 ///@todo use OWM_ROOTED flag
1628 // create explorer treeview
1629 if (_shellpath_info
._open_mode
& OWM_EXPLORE
) {
1631 ClientRect
rect(_hwnd
);
1633 _left_hwnd
= CreateWindowEx(WS_EX_CLIENTEDGE
, WC_TREEVIEW
, NULL
,
1634 WS_CHILD
|WS_TABSTOP
|WS_VISIBLE
|WS_CHILD
|TVS_HASLINES
|TVS_LINESATROOT
|TVS_HASBUTTONS
|TVS_NOTOOLTIPS
|TVS_SHOWSELALWAYS
,
1635 0, rect
.top
, split_pos
-SPLIT_WIDTH
/2, rect
.bottom
-rect
.top
,
1636 _hwnd
, (HMENU
)IDC_FILETREE
, g_Globals
._hInstance
, 0);
1638 // display tree window as long as the shell view is not yet visible
1639 resize_frame(rect
.right
, rect
.bottom
);
1640 MoveWindow(_left_hwnd
, rect
.left
, rect
.top
, rect
.right
-rect
.left
, rect
.bottom
-rect
.top
, TRUE
);
1644 DestroyWindow(_left_hwnd
);
1649 _shellBrowser
= auto_ptr
<ShellBrowser
>(new ShellBrowser(_hwnd
, _left_hwnd
, _right_hwnd
,
1650 _shellpath_info
, _himlSmall
, this, _cm_ifs
));
1652 _shellBrowser
->Init(_hwnd
);
1655 _shellBrowser
->Init(_himlSmall
);
1657 // update _clnt_rect and set size of new created shell view windows
1661 void SDIMainFrame::entry_selected(Entry
* entry
)
1663 if (entry
->_etype
== ET_SHELL
) {
1664 ShellEntry
* shell_entry
= static_cast<ShellEntry
*>(entry
);
1665 IShellFolder
* folder
;
1667 if (shell_entry
->_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
1668 folder
= static_cast<ShellDirectory
*>(shell_entry
)->_folder
;
1670 folder
= shell_entry
->get_parent_folder();
1677 TCHAR path
[MAX_PATH
];
1679 if (shell_entry
->get_path(path
, COUNTOF(path
))) {
1683 url
.printf(TEXT("shell://%s"), path
);
1685 url
.printf(TEXT("file://%s"), path
);
1690 _shellBrowser
->UpdateFolderView(folder
);
1692 // update _clnt_rect and set size of new created shell view windows
1697 void SDIMainFrame::set_url(LPCTSTR url
)
1702 SetWindowText(_haddressedit
, url
); //SendMessage(_hwndFrame, PM_URL_CHANGED, 0, (LPARAM)url);
1706 void SDIMainFrame::jump_to(LPCTSTR path
, int mode
)
1708 if (_shellBrowser.get() && (_shellpath_info._open_mode&~OWM_PIDL)==(mode&~OWM_PIDL)) {
1709 _shellBrowser->jump_to(path);
1711 _shellpath_info._shell_path = path;
1713 _shellpath_info
._open_mode
= mode
;
1714 _shellpath_info
._shell_path
= path
;
1715 _shellpath_info
._root_shell_path
= SpecialFolderPath(CSIDL_DRIVES
, _hwnd
); //@@ path
1717 update_shell_browser();
1721 void SDIMainFrame::jump_to(LPCITEMIDLIST path
, int mode
)
1723 if (_shellBrowser
.get() && (_shellpath_info
._open_mode
&~OWM_PIDL
)==(mode
&~OWM_PIDL
)) {
1724 ShellPath shell_path
= path
;
1726 _shellBrowser
->jump_to(shell_path
);
1728 _shellpath_info
._shell_path
= shell_path
;
1730 _shellpath_info
._open_mode
= mode
;
1731 _shellpath_info
._shell_path
= path
;
1732 _shellpath_info
._root_shell_path
= path
; //@@ MF 02.10.2005 was: SpecialFolderPath(CSIDL_DRIVES, _hwnd);
1734 update_shell_browser();