update for HEAD-2003091401
[reactos.git] / subsys / system / explorer / Seashell / SeaShellExt / UIFrameWnd.cpp
1 //*******************************************************************************
2 // COPYRIGHT NOTES
3 // ---------------
4 // You may use this source code, compile or redistribute it as part of your application 
5 // for free. You cannot redistribute it as a part of a software development 
6 // library without the agreement of the author. If the sources are 
7 // distributed along with the application, you should leave the original 
8 // copyright notes in the source code without any changes.
9 // This code can be used WITHOUT ANY WARRANTIES at your own risk.
10 // 
11 // For the latest updates to this code, check this site:
12 // http://www.masmex.com 
13 // after Sept 2000
14 // 
15 // Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
16 //*******************************************************************************
17
18 #include "stdafx.h"
19 #include "UIFrameWnd.h"
20 #include "UIApp.h"
21 #include "UIres.h"
22 #include "UIMessages.h"
23 #include "WindowPlacement.h"
24 #include "IEShellTreeView.h"
25 #include "IEShellListView.h"
26
27 #ifdef _DEBUG
28 #define new DEBUG_NEW
29 #undef THIS_FILE
30 static char THIS_FILE[] = __FILE__;
31 #endif
32
33 static UINT nMsgMouseWheel =
34    (((::GetVersion() & 0x80000000) && LOBYTE(LOWORD(::GetVersion()) == 4)) ||
35          (!(::GetVersion() & 0x80000000) && LOBYTE(LOWORD(::GetVersion()) == 3)))
36          ? ::RegisterWindowMessage(MSH_MOUSEWHEEL) : 0;
37
38 LPCTSTR CUIFrameWnd::szMainFrame = _T("MainFrame");
39
40 IMPLEMENT_DYNAMIC(CUIFrameWnd, CFrameWnd)
41
42 CUIFrameWnd::CUIFrameWnd() : m_IDToolbar(0),m_pwndCoolBar(NULL)
43 {
44         m_bReportCtrl = false;
45 }
46
47 CUIFrameWnd::~CUIFrameWnd()
48 {
49         delete m_pwndCoolBar;
50 }
51
52 void CUIFrameWnd::RestoreWindow(UINT nCmdShow) 
53 {
54 // Load window placement from profile
55         CWindowPlacement wp;
56         if (!wp.Restore(CUIFrameWnd::szMainFrame, this))
57         {
58                 ShowWindow(nCmdShow);
59         }
60 }
61
62 CUIStatusBar &CUIFrameWnd::GetStatusBar()
63 {
64         return m_wndStatusBar;
65 }
66
67 CReallyCoolBar &CUIFrameWnd::GetCoolBar()
68 {
69         ASSERT(m_pwndCoolBar);
70         return *m_pwndCoolBar;
71 }
72
73 void CUIFrameWnd::CreateCoolBar()
74 {
75         if (m_pwndCoolBar == NULL)
76                 m_pwndCoolBar = new CReallyCoolBar;
77 }
78
79 CCoolMenuManager &CUIFrameWnd::GetMenuManager()
80 {
81         return m_menuManager;
82 }
83
84 BEGIN_MESSAGE_MAP(CUIFrameWnd, CFrameWnd)
85         //{{AFX_MSG_MAP(CUIFrameWnd)
86         ON_WM_INITMENUPOPUP()
87         ON_WM_MENUSELECT()
88         ON_WM_CREATE()
89         ON_WM_CLOSE()
90         ON_WM_MOUSEWHEEL()
91         //}}AFX_MSG_MAP
92         ON_REGISTERED_MESSAGE(nMsgMouseWheel, OnRegisteredMouseWheel)
93         ON_MESSAGE(WM_APP_CB_IE_SET_EDIT_TEXT,OnCBIESetEditText)
94         ON_MESSAGE(WM_APP_CB_IE_POPULATE,OnCBIEPopulate)
95         ON_MESSAGE(WM_APP_CB_IE_SEL_CHANGE,OnCBIESelChange)
96         ON_MESSAGE(WM_APP_CB_IE_HIT_ENTER,OnCBIEHitEnter)
97 END_MESSAGE_MAP()
98
99 /////////////////////////////////////////////////////////////////////////////
100 // CUIFrameWnd message handlers
101
102 BOOL CUIFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
103 {
104         // TODO: Modify the Window class or styles here by modifying
105         //  the CREATESTRUCT cs
106         CWinApp *pApp = AfxGetApp();
107         if (pApp->IsKindOf(RUNTIME_CLASS(CUIApp)))
108         {
109                 if (((CUIApp*)pApp)->IsMyClassRegistered())
110                 {
111                         cs.lpszClass = ((CUIApp*)pApp)->GetMyClass();
112                         TRACE(_T("Setting to window class %s in CUIFrameWnd\n"),cs.lpszClass);
113                 }
114         }
115         if (cs.lpszClass == NULL)
116         {
117                 cs.lpszClass = AfxRegisterWndClass(
118                                           CS_DBLCLKS,                       
119                                           NULL,                             
120                                           NULL,                             
121                                           NULL); 
122                 ASSERT(cs.lpszClass);
123         }
124         CWindowPlacement wp;
125         if (wp.GetProfileWP(szMainFrame)) 
126         {
127                 CRect rc(wp.rcNormalPosition);
128                 cs.x = rc.left;
129                 cs.y = rc.top;
130                 cs.cx = rc.Width();
131                 cs.cy = rc.Height();
132         }
133         return CFrameWnd::PreCreateWindow(cs);
134 }
135
136 void CUIFrameWnd::OnClose() 
137 {
138         // TODO: Add your message handler code here and/or call default
139         CWindowPlacement wp;    
140         wp.Save(szMainFrame,this);
141         
142         CFrameWnd::OnClose();
143 }
144
145 void CUIFrameWnd::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) 
146 {
147         CFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
148         // store width of first pane and its style
149         if (GetStatusBar().m_nStatusPane1Width == -1 && GetStatusBar().m_bMenuSelect)
150         {
151                 UINT nStatusPane1Style;
152                 GetStatusBar().GetPaneInfo(0, GetStatusBar().m_nStatusPane1ID, 
153                         nStatusPane1Style, GetStatusBar().m_nStatusPane1Width);
154                 GetStatusBar().SetPaneInfo(0, GetStatusBar().m_nStatusPane1ID, 
155                         SBPS_NOBORDERS|SBPS_STRETCH, 16384);
156         }
157 }
158
159
160 int CUIFrameWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
161 {
162         if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
163                 return -1;
164         // if not tool bar set no point in continuing
165         ASSERT(m_IDToolbar > 0);
166         if (m_IDToolbar == 0)
167                 return 0;
168         
169         if (!GetStatusBar().Create(this))
170         {
171                 TRACE0("Failed to create status bar\n");
172                 return -1;      // fail to create
173         }
174         GetStatusBar().AddPane(ID_SEPARATOR,TRUE);
175         GetStatusBar().SetPanes(FALSE);
176
177         CreateCoolBar();
178         ASSERT(m_pwndCoolBar);
179         if (m_pwndCoolBar == NULL)
180                 return -1;
181         CReallyCoolBar& cb = GetCoolBar();
182         ASSERT(m_IDToolbar > 0);
183         cb.SetToolBarID(m_IDToolbar);
184         VERIFY(cb.Create(this,
185                 WS_CHILD|WS_VISIBLE|WS_BORDER|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|
186                         RBS_TOOLTIPS|RBS_BANDBORDERS|RBS_VARHEIGHT));
187
188         cb.SetColors(GetSysColor(COLOR_BTNTEXT),GetSysColor(COLOR_3DFACE));
189         
190         // install/load cool menus
191         GetMenuManager().Install(this);
192         GetMenuManager().LoadToolbar(m_IDToolbar);
193         if (cb.IsKindOf(RUNTIME_CLASS(CWebBrowserCoolBar)))
194                 GetMenuManager().LoadToolbar(IDB_HOTTOOLBAR);
195
196         if (m_bReportCtrl)
197         {
198                 if (!m_wndFieldChooser.Create(this, IDD_FIELDCHOOSER,
199                         CBRS_LEFT|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_HIDE_INPLACE, ID_VIEW_FIELDCHOOSER))
200                         return -1;              // fail to create
201
202                 EnableDocking(CBRS_ALIGN_ANY);
203
204                 m_wndFieldChooser.EnableDocking(0);
205                 m_wndFieldChooser.SetWindowText(_T("Field Chooser"));
206
207                 FloatControlBar(&m_wndFieldChooser, CPoint(100, GetSystemMetrics(SM_CYSCREEN) / 3));
208                 ShowControlBar(&m_wndFieldChooser, FALSE, FALSE);
209         }       
210         return 0;
211 }
212
213 void CUIFrameWnd::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
214 {
215         CFrameWnd::OnMenuSelect(nItemID, nFlags, hSysMenu);
216
217         // Restore first pane of the statusbar?
218         if (nFlags == 0xFFFF && hSysMenu == 0 && GetStatusBar().m_nStatusPane1Width != -1)
219         {
220                 GetStatusBar().m_bMenuSelect = FALSE;
221                 GetStatusBar().SetPaneInfo(0, GetStatusBar().m_nStatusPane1ID, GetStatusBar().m_nStatusPane1Style, GetStatusBar().m_nStatusPane1Width);
222                 GetStatusBar().m_nStatusPane1Width = -1;   // Set it to illegal value
223         }
224         else 
225         {
226                 GetStatusBar().m_bMenuSelect = TRUE;
227         }
228 }
229
230 void CUIFrameWnd::GetMessageString( UINT nID, CString& rMessage ) const
231 {
232         CFrameWnd::GetMessageString(nID,rMessage);
233         CUIFrameWnd *pThis = const_cast<CUIFrameWnd*>(this);
234         if (pThis->GetStatusBar().IsPanes())
235                 pThis->GetStatusBar().SetPaneText(0,rMessage);
236 }
237
238 BOOL CUIFrameWnd::PreTranslateMessage(MSG* pMsg)
239 {
240         return m_pwndCoolBar && m_pwndCoolBar->m_wndMenuBar.TranslateFrameMessage(pMsg) ?
241                 TRUE : CFrameWnd::PreTranslateMessage(pMsg);
242 }
243
244 ////////////////////////////////////////////////////////////////
245 // CReallyCoolBar
246 //
247 IMPLEMENT_DYNAMIC(CReallyCoolBar, CCoolBar)
248 IMPLEMENT_DYNAMIC(CWebBrowserCoolBar, CCoolBar)
249
250 ////////////////
251 // This is the virtual function you have to override to add bands
252 //
253 BOOL CReallyCoolBar::OnCreateBands()
254 {
255         //////////////////
256         // Create menu bar
257         CMenuBar& mb = m_wndMenuBar;
258
259         VERIFY(mb.Create(this, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|
260                 CBRS_TOOLTIPS|CBRS_SIZE_DYNAMIC|CBRS_FLYBY|CBRS_ORIENT_HORZ));
261         mb.ModifyStyle(0, TBSTYLE_TRANSPARENT);
262
263         // Load doc or main menu. Only required since this app flips
264         // between coolbar/toolbars.
265         CFrameWnd *pParent = GetParentFrame();
266         CFrameWnd* pFrame = pParent->GetActiveFrame();
267         ASSERT(m_IDToolbar > 0);
268         mb.LoadMenu(m_IDToolbar);
269
270         CRect rc;
271         mb.GetItemRect(0, &rc);
272         CSize szMenu = mb.CalcDynamicLayout(-1, LM_HORZ); // get min horz size
273
274         // create menu bar band.
275         CSize szMin;
276         szMin = CSize( szMenu.cx, rc.Height());
277         if (!InsertBand(&mb, szMin, 0x7ff))
278                 return FALSE;
279
280         //////////////////
281         // Create tool bar
282         CFlatToolBar& tb = m_wndToolBar;
283         VERIFY(tb.Create(this,
284                 WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|
285                         CBRS_TOOLTIPS|CBRS_SIZE_DYNAMIC|CBRS_FLYBY|CBRS_ORIENT_HORZ));
286         VERIFY(tb.LoadToolBar(m_IDToolbar)); 
287         // use transparent so coolbar bitmap will show through
288         tb.ModifyStyle(0, TBSTYLE_TRANSPARENT);
289
290         // Get minimum size of toolbar, which is basically size of one button
291         CSize szHorz = tb.CalcDynamicLayout(-1, LM_HORZ); // get min horz size
292         tb.GetItemRect(0, &rc);
293         szMin = rc.Size(); // CSize( szHorz.cx, rc.Height()); 
294
295         // create toolbar band. Use largest size possible
296         if (!InsertBand(&tb, szMin, 0x7fff, NULL, -1, TRUE))
297                 return FALSE;
298
299         return TRUE; // OK
300 }
301
302 void CReallyCoolBar::SetToolBarID(UINT IDToolbar)
303 {
304         m_IDToolbar = IDToolbar;
305 }
306
307 BOOL CWebBrowserCoolBar::OnCreateBands()
308 {
309         CReallyCoolBar::OnCreateBands();
310
311         CFlatToolBar& bb = m_wndBrowserBar;
312         VERIFY(bb.Create(this,
313                 WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|
314                         CBRS_TOOLTIPS|CBRS_SIZE_DYNAMIC|CBRS_FLYBY|CBRS_ORIENT_HORZ));
315         CImageList img;
316         CString str;
317 //      bb.GetToolBarCtrl().SetButtonWidth(50, 150);
318         bb.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);
319         img.Create(IDB_HOTTOOLBAR, 22, 0, RGB(255, 0, 255));
320         bb.GetToolBarCtrl().SetHotImageList(&img);
321         img.Detach();
322         img.Create(IDB_COLDTOOLBAR, 22, 0, RGB(255, 0, 255));
323         bb.GetToolBarCtrl().SetImageList(&img);
324         img.Detach();
325         bb.ModifyStyle(0, TBSTYLE_FLAT | TBSTYLE_TRANSPARENT);
326         bb.SetButtons(NULL, 7);
327         // use transparent so coolbar bitmap will show through
328         bb.ModifyStyle(0, TBSTYLE_TRANSPARENT);
329
330         // set up each toolbar button
331 /*      str.LoadString(IDS_BROWSER_GO_BACK);
332         bb.SetButtonText(0, str);
333         str.LoadString(IDS_BROWSER_GO_FORWARD);
334         bb.SetButtonText(1, str);
335         str.LoadString(IDS_BROWSER_STOP);
336         bb.SetButtonText(2, str);
337         str.LoadString(IDS_BROWSER_REFRESH);
338         bb.SetButtonText(3, str);
339         str.LoadString(IDS_BROWSER_GO_HOME);
340         bb.SetButtonText(4, str);
341         str.LoadString(IDS_BROWSER_SEARCH);
342         bb.SetButtonText(5, str);
343         str.LoadString(IDS_BROWSER_FAVORITES);
344         bb.SetButtonText(6, str);
345 */
346         bb.SetButtonInfo(0, ID_BROWSER_GO_BACK, TBSTYLE_BUTTON, 0);
347         bb.SetButtonInfo(1, ID_BROWSER_GO_FORWARD, TBSTYLE_BUTTON, 1);
348         bb.SetButtonInfo(2, ID_BROWSER_STOP, TBSTYLE_BUTTON, 2);
349         bb.SetButtonInfo(3, ID_BROWSER_REFRESH, TBSTYLE_BUTTON, 3);
350         bb.SetButtonInfo(4, ID_BROWSER_GO_HOME, TBSTYLE_BUTTON, 4);
351         bb.SetButtonInfo(5, ID_BROWSER_SEARCH, TBSTYLE_BUTTON, 5);
352         bb.SetButtonInfo(6, ID_BROWSER_FAVORITES, TBSTYLE_BUTTON, 6);
353
354
355         CRect rectToolBar;
356         CRect rc;
357         // set up toolbar button sizes
358         bb.GetItemRect(0, &rectToolBar);
359 //      bb.SetSizes(rectToolBar.Size(), CSize(30,20));
360
361         // Get minimum size of toolbar, which is basically size of one button
362         CSize szHorz = bb.CalcDynamicLayout(-1, LM_HORZ); // get min horz size
363         bb.GetItemRect(0, &rc);
364         CSize szMin = rc.Size(); // CSize( szHorz.cx, rc.Height()); 
365
366         // create toolbar band. Use largest size possible
367         if (!InsertBand(&bb, szMin, 0x7fff, NULL, -1, TRUE))
368                 return FALSE;
369
370         //////////////////
371         // Create combo box and fill with data
372
373         CRect rcCombo(0,0,600,200);
374         m_wndCombo.Create(WS_VISIBLE|WS_CHILD|WS_VSCROLL|CBS_DROPDOWN|
375                 WS_CLIPCHILDREN|WS_CLIPSIBLINGS, rcCombo, this, IDC_CB_IE_ADDRESS);
376         m_wndCombo.SetFont(GetFont());
377
378         CSize szMinCombo = m_wndBrowserBar.CalcDynamicLayout(-1, LM_HORZDOCK);        // get min horz size
379         if (!InsertBand(&m_wndCombo, szMinCombo, 0x7fff, _T("Address")))
380                 return FALSE;
381
382         return TRUE;
383 }
384
385 // changed from MFC to use WindowFromPoint instead of GetFocus
386 LRESULT CUIFrameWnd::OnRegisteredMouseWheel(WPARAM wParam, LPARAM lParam)
387 {
388         // convert from MSH_MOUSEWHEEL to WM_MOUSEWHEEL
389         TRACE(_T("CUFrameWnd registered mouse wheel message\n"));
390 //      return CFrameWnd::OnRegisteredMouseWheel(wParam,lParam);
391
392         WORD keyState = 0;
393         keyState |= (::GetKeyState(VK_CONTROL) < 0) ? MK_CONTROL : 0;
394         keyState |= (::GetKeyState(VK_SHIFT) < 0) ? MK_SHIFT : 0;
395
396         LRESULT lResult;
397         CPoint point;
398         ::GetCursorPos(&point);
399         HWND hwFocus = ::WindowFromPoint(point);
400 //      HWND hwFocus = ::GetFocus();
401         const HWND hwDesktop = ::GetDesktopWindow();
402
403         if (hwFocus == NULL)
404                 lResult = SendMessage(WM_MOUSEWHEEL, (wParam << 16) | keyState, lParam);
405         else
406         {
407                 do {
408                         lParam = ::SendMessage(hwFocus, WM_MOUSEWHEEL,
409                                 (wParam << 16) | keyState, lParam);
410                         hwFocus = ::GetParent(hwFocus);
411                 }
412                 while (lParam == 0 && hwFocus != NULL && hwFocus != hwDesktop);
413         }
414         return lResult;
415
416 }
417
418 BOOL CUIFrameWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
419 {
420         CFrameWnd::OnMouseWheel(nFlags,zDelta,pt); 
421         // TODO: Add your message handler code here and/or call default
422         TRACE(_T("CUIFrameWnd mouse wheel message\n"));
423         return TRUE;
424 }
425
426 LRESULT CUIFrameWnd::OnCBIEPopulate(WPARAM wParam,LPARAM lParam)
427 {
428         TRACE(_T("Received ComboBox populate message in CUIFrameWnd\n"));
429         if (m_pwndCoolBar && m_pwndCoolBar->IsKindOf(RUNTIME_CLASS(CWebBrowserCoolBar)))
430         {
431                 TRACE(_T("Sending to ShellComboBox...\n"));
432                 ((CWebBrowserCoolBar*)m_pwndCoolBar)->GetComboBox().SendMessage(WM_APP_CB_IE_POPULATE,wParam,lParam);
433         }
434         return 1L;
435 }
436
437 LRESULT CUIFrameWnd::OnCBIEHitEnter(WPARAM wParam,LPARAM lParam)
438 {
439         if (lParam == NULL)
440                 return 0L;
441         if (m_pwndCoolBar && m_pwndCoolBar->IsKindOf(RUNTIME_CLASS(CWebBrowserCoolBar)))
442         {
443                 CWinApp *pApp = AfxGetApp();
444                 CUIApp *pUIApp=NULL;
445                 if (pApp->IsKindOf(RUNTIME_CLASS(CUIApp)))
446                         pUIApp = (CUIApp*)pApp;
447                 if (pUIApp)
448                 {
449                         CView *pView = NULL;
450                         pView = pUIApp->GetView(RUNTIME_CLASS(CIEShellTreeView));
451                         if (pView)
452                         {
453                                 LRESULT lResult = 0;
454                                 if (wParam == 0)
455                                         lResult = ((CIEShellTreeView*)pView)->GetShellTreeCtrl().SendMessage(WM_APP_CB_IE_HIT_ENTER,wParam,lParam);
456                                 if (lResult == 0)
457                                 {
458                                         pView = pUIApp->GetView(RUNTIME_CLASS(CIEShellListView));
459                                         if (pView)
460                                                 pView->SendMessage(WM_APP_CB_IE_HIT_ENTER,wParam,lParam);
461                                 }
462                         }
463                 }
464         }
465         return 1L;      
466 }
467
468 LRESULT CUIFrameWnd::OnCBIESelChange(WPARAM wParam,LPARAM lParam)
469 {
470         if (m_pwndCoolBar && m_pwndCoolBar->IsKindOf(RUNTIME_CLASS(CWebBrowserCoolBar)))
471         {
472                 CWinApp *pApp = AfxGetApp();
473                 CUIApp *pUIApp=NULL;
474                 if (pApp->IsKindOf(RUNTIME_CLASS(CUIApp)))
475                         pUIApp = (CUIApp*)pApp;
476                 if (pUIApp)
477                 {
478                         CView *pView = NULL;
479                         if (wParam)
480                         {
481                                 pView = pUIApp->GetView(RUNTIME_CLASS(CIEShellTreeView));
482                                 if (pView)
483                                         ((CIEShellTreeView*)pView)->GetShellTreeCtrl().SendMessage(WM_APP_CB_IE_SEL_CHANGE,wParam,lParam);
484                         }
485                         else
486                         {
487                                 pView = pUIApp->GetView(RUNTIME_CLASS(CIEShellListView));
488                                 if (pView)
489                                         pView->SendMessage(WM_APP_CB_IE_SEL_CHANGE,wParam,lParam);
490                         }
491                 }
492         }
493         return 1L;
494 }
495
496 LRESULT CUIFrameWnd::OnCBIESetEditText(WPARAM wParam,LPARAM lParam)
497 {
498         if (m_pwndCoolBar && m_pwndCoolBar->IsKindOf(RUNTIME_CLASS(CWebBrowserCoolBar)))
499         {
500                 if (wParam)
501                         ((CWebBrowserCoolBar*)m_pwndCoolBar)->GetComboBox().GetEditCtrl()->SetWindowText((LPCTSTR)wParam);
502         }
503         return 1L;
504 }
505
506
507 ////////////////////////////////////////////////////////////////
508 // CToolBarComboBox
509 //
510
511 BEGIN_MESSAGE_MAP(CToolBarComboBox, CIEShellComboBox)
512 END_MESSAGE_MAP()
513
514 //////////////////