move from branch
[reactos.git] / reactos / base / applications / ibrowser / mainframe.cpp
1 /*
2 * Copyright 2005 Martin Fuchs
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19
20 //
21 // ROS Internet Web Browser
22 //
23 // mainframe.cpp
24 //
25 // Martin Fuchs, 25.01.2005
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 "ibrowser_intres.h"
37
38
39 HWND MainFrameBase::Create(LPCTSTR url, UINT cmdshow)
40 {
41 HWND hMainFrame;
42
43 hMainFrame = MainFrame::Create();
44 //@@hMainFrame = MainFrame::Create(url);
45
46 if (hMainFrame) {
47 if (url) {
48 static String sPath = url; // copy url to avoid accessing freed memory
49 url = sPath;
50 }
51
52 ShowWindow(hMainFrame, cmdshow);
53 UpdateWindow(hMainFrame);
54
55 // Open the first child window after initializing the application
56 PostMessage(hMainFrame, PM_OPEN_WINDOW, 0, (LPARAM)url);
57 }
58
59 return hMainFrame;
60 }
61
62
63 MainFrameBase::MainFrameBase(HWND hwnd)
64 : super(hwnd),
65 _himl(ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0))
66 {
67 _hMenuFrame = GetMenu(hwnd);
68 _hMenuWindow = GetSubMenu(_hMenuFrame, GetMenuItemCount(_hMenuFrame)-3);
69
70 _menu_info._hMenuView = GetSubMenu(_hMenuFrame, 1);
71
72 _hAccel = LoadAccelerators(g_hInstance, MAKEINTRESOURCE(IDA_IBROWSER));
73
74
75 TBBUTTON toolbarBtns[] = {
76 #ifdef _NO_REBAR
77 {0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
78 #endif
79 {7, ID_GO_BACK, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
80 {8, ID_GO_FORWARD, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
81 {9, ID_GO_UP, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
82 {10, ID_GO_HOME, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
83 {11, ID_GO_SEARCH, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
84 {12, ID_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
85 {13, ID_STOP, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0}
86 };
87
88 _htoolbar = CreateToolbarEx(hwnd,
89 #ifndef _NO_REBAR
90 CCS_NOPARENTALIGN|CCS_NORESIZE|
91 #endif
92 WS_CHILD|WS_VISIBLE|TBSTYLE_FLAT, IDW_TOOLBAR, 2, g_hInstance, IDB_TOOLBAR,
93 toolbarBtns, sizeof(toolbarBtns)/sizeof(TBBUTTON),
94 16, 15, 16, 15, sizeof(TBBUTTON));
95
96 CheckMenuItem(_menu_info._hMenuView, ID_VIEW_TOOL_BAR, MF_BYCOMMAND|MF_CHECKED);
97
98
99 // address bar
100 WindowCanvas canvas(hwnd);
101 RECT rect = {0, 0, 0, 0};
102 DrawText(canvas, TEXT("My"), -1, &rect, DT_SINGLELINE|DT_NOPREFIX|DT_CALCRECT);
103 HFONT hfont = GetStockFont(DEFAULT_GUI_FONT);
104
105 _haddressedit = CreateWindow(TEXT("EDIT"), NULL, WS_CHILD|WS_VISIBLE|WS_BORDER, 0, 0, 0, rect.bottom,
106 hwnd, (HMENU)IDW_ADDRESSBAR, g_hInstance, 0);
107 SetWindowFont(_haddressedit, hfont, FALSE);
108 new EditController(_haddressedit);
109
110 /* CreateStatusWindow does not accept WS_BORDER
111 _hstatusbar = CreateWindowEx(WS_EX_NOPARENTNOTIFY, STATUSCLASSNAME, 0,
112 WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_BORDER|CCS_NODIVIDER, 0,0,0,0,
113 hwnd, (HMENU)IDW_STATUSBAR, g_hInstance, 0);*/
114
115 _hstatusbar = CreateStatusWindow(WS_CHILD|WS_VISIBLE, 0, hwnd, IDW_STATUSBAR);
116 CheckMenuItem(_menu_info._hMenuView, ID_VIEW_STATUSBAR, MF_BYCOMMAND|MF_CHECKED);
117
118 _hsidebar = CreateWindowEx(WS_EX_STATICEDGE, WC_TREEVIEW, TEXT("Sidebar"),
119 WS_CHILD|WS_TABSTOP|WS_BORDER|/*WS_VISIBLE|*/WS_CHILD|TVS_HASLINES|TVS_HASBUTTONS|TVS_SHOWSELALWAYS|TVS_INFOTIP,
120 -1, -1, 200, 0, _hwnd, (HMENU)IDW_SIDEBAR, g_hInstance, 0);
121
122 (void)TreeView_SetImageList(_hsidebar, _himl, TVSIL_NORMAL);
123
124 CheckMenuItem(_menu_info._hMenuView, ID_VIEW_SIDE_BAR, MF_BYCOMMAND|MF_UNCHECKED/*MF_CHECKED*/);
125
126
127 // create rebar window to manage toolbar and address bar
128 #ifndef _NO_REBAR
129 _hwndrebar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL,
130 WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|
131 RBS_VARHEIGHT|RBS_AUTOSIZE|RBS_DBLCLKTOGGLE|
132 CCS_NODIVIDER|CCS_NOPARENTALIGN,
133 0, 0, 0, 0, _hwnd, 0, g_hInstance, 0);
134
135 int btn_hgt = HIWORD(SendMessage(_htoolbar, TB_GETBUTTONSIZE, 0, 0));
136
137 REBARBANDINFO rbBand;
138
139 rbBand.cbSize = sizeof(REBARBANDINFO);
140 rbBand.fMask = RBBIM_TEXT|RBBIM_STYLE|RBBIM_CHILD|RBBIM_CHILDSIZE|RBBIM_SIZE;
141 #ifndef RBBS_HIDETITLE // missing in MinGW headers as of 25.02.2004
142 #define RBBS_HIDETITLE 0x400
143 #endif
144 rbBand.fStyle = RBBS_CHILDEDGE|RBBS_GRIPPERALWAYS|RBBS_HIDETITLE;
145
146 rbBand.cxMinChild = 0;
147 rbBand.cyMinChild = 0;
148 rbBand.cyChild = 0;
149 rbBand.cyMaxChild = 0;
150 rbBand.cyIntegral = btn_hgt;
151
152 TCHAR ToolBarText[] = _T("Toolbar");
153 rbBand.lpText = ToolBarText;
154 rbBand.hwndChild = _htoolbar;
155 rbBand.cxMinChild = 0;
156 rbBand.cyMinChild = btn_hgt + 4;
157 rbBand.cx = 182;
158 SendMessage(_hwndrebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
159
160 TCHAR AddressText[] = _T("Address");
161 rbBand.lpText = AddressText;
162 rbBand.hwndChild = _haddressedit;
163 rbBand.cxMinChild = 0;
164 rbBand.cyMinChild = btn_hgt - 2;
165 rbBand.cx = 284;
166 SendMessage(_hwndrebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
167 #endif
168 }
169
170
171 MainFrameBase::~MainFrameBase()
172 {
173 ImageList_Destroy(_himl);
174
175 //@@if (g_Globals._hMainWnd == _hwnd)
176 PostQuitMessage(0);
177 }
178
179
180 LRESULT MainFrameBase::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
181 {
182 LRESULT res;
183
184 if (ProcessMessage(nmsg, wparam, lparam, &res))
185 return res;
186 else
187 return super::WndProc(nmsg, wparam, lparam);
188 }
189
190 bool MainFrameBase::ProcessMessage(UINT nmsg, WPARAM wparam, LPARAM lparam, LRESULT* pres)
191 {
192 switch(nmsg) {
193 case PM_TRANSLATE_MSG:
194 *pres = TranslateMsg((MSG*)lparam);
195 return true;
196
197 case WM_SHOWWINDOW:
198 if (wparam) // trigger child resizing after window creation - now we can succesfully call IsWindowVisible()
199 resize_frame_client();
200 return false; // goto def;
201
202 case WM_CLOSE:
203 DestroyWindow(_hwnd);
204 //@@ g_Globals._hMainWnd = 0;
205 break;
206
207 case WM_DESTROY:
208 break;
209
210 case WM_SIZE:
211 resize_frame(LOWORD(lparam), HIWORD(lparam));
212 break; // do not pass message to DefFrameProc
213
214 case WM_GETMINMAXINFO: {
215 LPMINMAXINFO lpmmi = (LPMINMAXINFO)lparam;
216
217 lpmmi->ptMaxTrackSize.x <<= 1;/*2*GetSystemMetrics(SM_CXSCREEN) / SM_CXVIRTUALSCREEN */
218 lpmmi->ptMaxTrackSize.y <<= 1;/*2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN */
219 break;}
220
221 case PM_FRM_CALC_CLIENT:
222 frame_get_clientspace((PRECT)lparam);
223 *pres = TRUE;
224 return true;
225
226 case PM_FRM_GET_MENUINFO:
227 *pres = (LPARAM)&_menu_info;
228 return true;
229
230 case PM_GET_CONTROLWINDOW:
231 if (wparam == FCW_STATUS) {
232 *pres = (LRESULT)(HWND)_hstatusbar;
233 return true;
234 }
235 break;
236
237 case PM_SETSTATUSTEXT:
238 SendMessage(_hstatusbar, SB_SETTEXT, wparam, lparam);
239 break;
240
241 case PM_URL_CHANGED:
242 SetWindowText(_haddressedit, (LPCTSTR)lparam);
243 break;
244
245 default:
246 return false;
247 }
248
249 *pres = 0;
250 return true;
251 }
252
253 BOOL MainFrameBase::TranslateMsg(MSG* pmsg)
254 {
255 if (TranslateAccelerator(_hwnd, _hAccel, pmsg))
256 return TRUE;
257
258 return FALSE;
259 }
260
261
262 int MainFrameBase::Command(int id, int code)
263 {
264 CONTEXT("MainFrameBase::Command()");
265
266 switch(id) {
267 case ID_FILE_OPEN:
268 ibrowser_open(_hwnd);
269 break;
270
271 case ID_FILE_EXIT:
272 SendMessage(_hwnd, WM_CLOSE, 0, 0);
273 break;
274
275 case ID_VIEW_TOOL_BAR:
276 toggle_child(_hwnd, id, _htoolbar, 0);
277 break;
278
279 case ID_VIEW_STATUSBAR:
280 toggle_child(_hwnd, id, _hstatusbar);
281 break;
282
283 case ID_VIEW_SIDE_BAR:
284 // lazy initialization
285 if (!TreeView_GetCount(_hsidebar))
286 FillBookmarks();
287
288 toggle_child(_hwnd, id, _hsidebar);
289 break;
290
291 case ID_HELP:
292 WinHelp(_hwnd, TEXT("ibrowser")/*file ibrowser.hlp*/, HELP_INDEX, 0);
293 break;
294
295 case ID_VIEW_FULLSCREEN:
296 CheckMenuItem(_menu_info._hMenuView, id, toggle_fullscreen()?MF_CHECKED:0);
297 break;
298
299 case ID_ABOUT_WINDOWS:
300 ShellAbout(_hwnd, ResString(IDS_TITLE), NULL, 0);
301 break;
302
303 case ID_ABOUT_IBROWSER:
304 ibrowser_about(_hwnd);
305 break;
306
307 case ID_IBROWSER_FAQ:
308 launch_file(_hwnd, TEXT("http://www.sky.franken.de/explorer/"), SW_SHOW);
309 break;
310
311 case IDW_ADDRESSBAR:
312 if (code == 1) {
313 TCHAR url[BUFFER_LEN];
314
315 if (GetWindowText(_haddressedit, url, BUFFER_LEN))
316 go_to(url, false);
317 }
318 break;
319
320 default:
321 return 1; // no command handlers in Window::Command()
322 }
323
324 return 0;
325 }
326
327
328 int MainFrameBase::Notify(int id, NMHDR* pnmh)
329 {
330 switch(pnmh->code) {
331 // resize children windows when the rebar size changes
332 case RBN_AUTOSIZE:
333 resize_frame_client();
334 break;
335
336 case TVN_GETINFOTIP: {
337 NMTVGETINFOTIP* pnmgit = (NMTVGETINFOTIP*)pnmh;
338
339 if (pnmgit->lParam) {
340 const BookmarkNode& node = *(BookmarkNode*)pnmgit->lParam;
341
342 if (node._type == BookmarkNode::BMNT_FOLDER) {
343 // display tooltips for bookmark folders
344 if (!node._pfolder->_description.empty())
345 lstrcpyn(pnmgit->pszText, node._pfolder->_description.c_str(), pnmgit->cchTextMax);
346 } else if (node._type == BookmarkNode::BMNT_BOOKMARK) {
347 // display tooltips for bookmark folders
348 String txt = node._pbookmark->_description;
349
350 if (!node._pbookmark->_url.empty()) {
351 if (!txt.empty())
352 txt += TEXT(" - ");
353
354 txt += node._pbookmark->_url;
355 }
356
357 lstrcpyn(pnmgit->pszText, txt.c_str(), pnmgit->cchTextMax);
358 }
359 }
360 break;}
361
362 case NM_DBLCLK: {
363 HTREEITEM hitem = TreeView_GetSelection(_hsidebar);
364 LPARAM lparam = TreeView_GetItemData(_hsidebar, hitem);
365
366 if (lparam) {
367 const BookmarkNode& node = *(BookmarkNode*)lparam;
368
369 if (node._type == BookmarkNode::BMNT_BOOKMARK) {
370 bool new_window = GetAsyncKeyState(VK_SHIFT)<0;
371
372 go_to(node._pbookmark->_url, new_window);
373 }
374 }
375 break;}
376 }
377
378 return 0;
379 }
380
381
382 void MainFrameBase::resize_frame(int cx, int cy)
383 {
384 if (cy <= 0)
385 return; // avoid resizing children when receiving RBN_AUTOSIZE while getting minimized
386
387 RECT rect = {0, 0, cx, cy};
388
389 if (_hwndrebar) {
390 int height = ClientRect(_hwndrebar).bottom;
391 MoveWindow(_hwndrebar, rect.left, rect.top, rect.right-rect.left, height, TRUE);
392 rect.top += height;
393 } else {
394 if (IsWindowVisible(_htoolbar)) {
395 SendMessage(_htoolbar, WM_SIZE, 0, 0);
396 WindowRect rt(_htoolbar);
397 rect.top = rt.bottom;
398 // rect.bottom -= rt.bottom;
399 }
400 }
401
402 if (IsWindowVisible(_hstatusbar)) {
403 int parts[] = {300, 500};
404
405 SendMessage(_hstatusbar, WM_SIZE, 0, 0);
406 SendMessage(_hstatusbar, SB_SETPARTS, 2, (LPARAM)&parts);
407 ClientRect rt(_hstatusbar);
408 rect.bottom -= rt.bottom;
409 }
410
411 if (IsWindowVisible(_hsidebar)) {
412 WindowRect rt(_hsidebar);
413 rect.left += rt.right-rt.left;
414
415 SetWindowPos(_hsidebar, 0, -1, rect.top-1, rt.right-rt.left, rect.bottom-rect.top+1, SWP_NOACTIVATE|SWP_NOZORDER);
416 }
417 }
418
419 void MainFrameBase::resize_frame_client()
420 {
421 ClientRect rect(_hwnd);
422
423 resize_frame(rect.right, rect.bottom);
424 }
425
426 void MainFrameBase::frame_get_clientspace(PRECT prect)
427 {
428 if (!IsIconic(_hwnd))
429 GetClientRect(_hwnd, prect);
430 else {
431 WINDOWPLACEMENT wp;
432
433 GetWindowPlacement(_hwnd, &wp);
434
435 prect->left = prect->top = 0;
436 prect->right = wp.rcNormalPosition.right-wp.rcNormalPosition.left-
437 2*(GetSystemMetrics(SM_CXSIZEFRAME)+GetSystemMetrics(SM_CXEDGE));
438 prect->bottom = wp.rcNormalPosition.bottom-wp.rcNormalPosition.top-
439 2*(GetSystemMetrics(SM_CYSIZEFRAME)+GetSystemMetrics(SM_CYEDGE))-
440 GetSystemMetrics(SM_CYCAPTION)-GetSystemMetrics(SM_CYMENUSIZE);
441 }
442
443 if (IsWindowVisible(_htoolbar)) {
444 ClientRect rt(_htoolbar);
445 prect->top += rt.bottom+2;
446 }
447
448 if (IsWindowVisible(_hstatusbar)) {
449 ClientRect rt(_hstatusbar);
450 prect->bottom -= rt.bottom;
451 }
452 }
453
454 BOOL MainFrameBase::toggle_fullscreen()
455 {
456 RECT rt;
457
458 if ((_fullscreen._mode=!_fullscreen._mode)) {
459 GetWindowRect(_hwnd, &_fullscreen._orgPos);
460 _fullscreen._wasZoomed = IsZoomed(_hwnd);
461
462 Frame_CalcFrameClient(_hwnd, &rt);
463 ClientToScreen(_hwnd, (LPPOINT)&rt.left);
464 ClientToScreen(_hwnd, (LPPOINT)&rt.right);
465
466 rt.left = _fullscreen._orgPos.left-rt.left;
467 rt.top = _fullscreen._orgPos.top-rt.top;
468 rt.right = GetSystemMetrics(SM_CXSCREEN)+_fullscreen._orgPos.right-rt.right;
469 rt.bottom = GetSystemMetrics(SM_CYSCREEN)+_fullscreen._orgPos.bottom-rt.bottom;
470
471 MoveWindow(_hwnd, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, TRUE);
472 } else {
473 MoveWindow(_hwnd, _fullscreen._orgPos.left, _fullscreen._orgPos.top,
474 _fullscreen._orgPos.right-_fullscreen._orgPos.left,
475 _fullscreen._orgPos.bottom-_fullscreen._orgPos.top, TRUE);
476
477 if (_fullscreen._wasZoomed)
478 ShowWindow(_hwnd, WS_MAXIMIZE);
479 }
480
481 return _fullscreen._mode;
482 }
483
484 void MainFrameBase::fullscreen_move()
485 {
486 RECT rt, pos;
487 GetWindowRect(_hwnd, &pos);
488
489 Frame_CalcFrameClient(_hwnd, &rt);
490 ClientToScreen(_hwnd, (LPPOINT)&rt.left);
491 ClientToScreen(_hwnd, (LPPOINT)&rt.right);
492
493 rt.left = pos.left-rt.left;
494 rt.top = pos.top-rt.top;
495 rt.right = GetSystemMetrics(SM_CXSCREEN)+pos.right-rt.right;
496 rt.bottom = GetSystemMetrics(SM_CYSCREEN)+pos.bottom-rt.bottom;
497
498 MoveWindow(_hwnd, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, TRUE);
499 }
500
501
502 void MainFrameBase::toggle_child(HWND hwnd, UINT cmd, HWND hchild, int band_idx)
503 {
504 BOOL vis = IsWindowVisible(hchild);
505
506 CheckMenuItem(_menu_info._hMenuView, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
507
508 if (band_idx != -1)
509 SendMessage(_hwndrebar, RB_SHOWBAND, band_idx, !vis);
510 else
511 ShowWindow(hchild, vis? SW_HIDE: SW_SHOW);
512
513 if (_fullscreen._mode)
514 fullscreen_move();
515
516 resize_frame_client();
517 }
518
519 void MainFrameBase::FillBookmarks()
520 {
521 /*@@
522 HiddenWindow hide(_hsidebar);
523 WindowCanvas canvas(_hwnd);
524
525 TreeView_DeleteAllItems(_hsidebar);
526
527 g_icon_cache.get_icon(ICID_FAVORITES).add_to_imagelist(_himl, canvas);
528 g_icon_cache.get_icon(ICID_BOOKMARK).add_to_imagelist(_himl, canvas);
529 ImageList_AddAlphaIcon(_himl, SmallIcon(IDI_DOT), GetStockBrush(WHITE_BRUSH), canvas);
530 g_icon_cache.get_icon(ICID_FOLDER).add_to_imagelist(_himl, canvas);
531 g_icon_cache.get_icon(ICID_FOLDER).add_to_imagelist(_himl, canvas);
532
533 TV_INSERTSTRUCT tvi;
534
535 tvi.hParent = TVI_ROOT;
536 tvi.hInsertAfter = TVI_LAST;
537 tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
538 ResString sFavorites(IDS_FAVORITES);
539 tvi.item.pszText = (LPTSTR)sFavorites.c_str();
540 tvi.item.iSelectedImage = tvi.item.iImage = 0;
541
542 HTREEITEM hitem_bookmarks = TreeView_InsertItem(_hsidebar, &tvi);
543
544 g_Globals._favorites.fill_tree(_hsidebar, hitem_bookmarks, _himl, canvas);
545
546 TreeView_Expand(_hsidebar, hitem_bookmarks, TVE_EXPAND);
547 */
548 }
549
550
551 MainFrame::MainFrame(HWND hwnd)
552 : super(hwnd)
553 {
554 _split_pos = DEFAULT_SPLIT_POS;
555 _last_split = DEFAULT_SPLIT_POS;
556 }
557
558 HWND MainFrame::Create()
559 {
560 HMENU hMenuFrame = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_SDIFRAME));
561
562 return Window::Create(WINDOW_CREATOR(MainFrame), 0,
563 (LPCTSTR)(int)g_hframeClass, ResString(IDS_TITLE), WS_OVERLAPPEDWINDOW,
564 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
565 0/*hwndDesktop*/, hMenuFrame);
566 }
567
568 /*@@
569 HWND MainFrame::Create(LPCTSTR url)
570 {
571 HWND hFrame = Create();
572 if (!hFrame)
573 return 0;
574
575 ShowWindow(hFrame, SW_SHOW);
576
577 MainFrame* pFrame = GET_WINDOW(MainFrame, hFrame);
578
579 if (pFrame)
580 pFrame->set_url(url);
581
582 return hFrame;
583 }
584 */
585
586 LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
587 {
588 switch(nmsg) {
589 case WM_SIZE:
590 resize_frame(LOWORD(lparam), HIWORD(lparam));
591 break;
592
593 case WM_PAINT: {
594 PaintCanvas canvas(_hwnd);
595
596 if (_left_hwnd && _right_hwnd) {
597 ClientRect rt(_hwnd);
598 rt.left = _split_pos-SPLIT_WIDTH/2;
599 rt.right = _split_pos+SPLIT_WIDTH/2+1;
600
601 if (_right_hwnd) {
602 WindowRect right_rect(_right_hwnd);
603 ScreenToClient(_hwnd, &right_rect);
604 rt.top = right_rect.top;
605 rt.bottom = right_rect.bottom;
606 }
607
608 HBRUSH lastBrush = SelectBrush(canvas, GetStockBrush(COLOR_SPLITBAR));
609 Rectangle(canvas, rt.left, rt.top-1, rt.right, rt.bottom+1);
610 SelectObject(canvas, lastBrush);
611 }
612 break;}
613
614 case WM_SETCURSOR:
615 if (LOWORD(lparam) == HTCLIENT) {
616 POINT pt;
617 GetCursorPos(&pt);
618 ScreenToClient(_hwnd, &pt);
619
620 if (pt.x>=_split_pos-SPLIT_WIDTH/2 && pt.x<_split_pos+SPLIT_WIDTH/2+1) {
621 SetCursor(LoadCursor(0, IDC_SIZEWE));
622 return TRUE;
623 }
624 }
625 goto def;
626
627 case WM_LBUTTONDOWN: {
628 int x = GET_X_LPARAM(lparam);
629
630 ClientRect rt(_hwnd);
631
632 if (x>=_split_pos-SPLIT_WIDTH/2 && x<_split_pos+SPLIT_WIDTH/2+1) {
633 _last_split = _split_pos;
634 SetCapture(_hwnd);
635 }
636
637 break;}
638
639 case WM_LBUTTONUP:
640 if (GetCapture() == _hwnd)
641 ReleaseCapture();
642 break;
643
644 case WM_KEYDOWN:
645 if (wparam == VK_ESCAPE)
646 if (GetCapture() == _hwnd) {
647 _split_pos = _last_split;
648 resize_children();
649 _last_split = -1;
650 ReleaseCapture();
651 SetCursor(LoadCursor(0, IDC_ARROW));
652 }
653 break;
654
655 case WM_MOUSEMOVE:
656 if (GetCapture() == _hwnd) {
657 int x = LOWORD(lparam);
658
659 ClientRect rt(_hwnd);
660
661 if (x>=0 && x<rt.right) {
662 _split_pos = x;
663 resize_children();
664 rt.left = x-SPLIT_WIDTH/2;
665 rt.right = x+SPLIT_WIDTH/2+1;
666 InvalidateRect(_hwnd, &rt, FALSE);
667 UpdateWindow(_left_hwnd);
668 UpdateWindow(_hwnd);
669 UpdateWindow(_right_hwnd);
670 }
671 }
672 break;
673
674 case PM_OPEN_WINDOW: {CONTEXT("MainFrame PM_OPEN_WINDOW");
675 LPCTSTR url = (LPCTSTR)lparam;
676
677 if (!url || !*url)
678 #ifdef _DEBUG
679 url = TEXT("http://localhost");
680 #else
681 url = TEXT("about:blank");
682 #endif
683
684 if (!_right_hwnd) {
685 _right_hwnd = create_webchildwindow(WebChildWndInfo(_hwnd, url));
686 resize_children();
687 } else
688 set_url(url);
689 return TRUE;} // success
690
691 default: def:
692 return super::WndProc(nmsg, wparam, lparam);
693 }
694
695 return 0;
696 }
697
698 int MainFrame::Command(int id, int code)
699 {
700 if (_right_hwnd)
701 if (SendMessage(_right_hwnd, PM_DISPATCH_COMMAND, MAKELONG(id,code), 0))
702 return 0;
703
704 return super::Command(id, code);
705 }
706
707 void MainFrame::resize_frame(int cx, int cy)
708 {
709 if (cy <= 0)
710 return; // avoid resizing children when receiving RBN_AUTOSIZE while getting minimized
711
712 RECT rect = {0, 0, cx, cy};
713
714 if (_hwndrebar) {
715 int height = ClientRect(_hwndrebar).bottom;
716 MoveWindow(_hwndrebar, rect.left, rect.top, rect.right-rect.left, height, TRUE);
717 rect.top += height;
718 } else {
719 if (IsWindowVisible(_htoolbar)) {
720 SendMessage(_htoolbar, WM_SIZE, 0, 0);
721 WindowRect rt(_htoolbar);
722 rect.top = rt.bottom;
723 // rect.bottom -= rt.bottom;
724 }
725 }
726
727 if (IsWindowVisible(_hstatusbar)) {
728 int parts[] = {300, 500};
729
730 SendMessage(_hstatusbar, WM_SIZE, 0, 0);
731 SendMessage(_hstatusbar, SB_SETPARTS, 2, (LPARAM)&parts);
732 ClientRect rt(_hstatusbar);
733 rect.bottom -= rt.bottom;
734 }
735
736 if (IsWindowVisible(_hsidebar)) {
737 WindowRect rt(_hsidebar);
738 rect.left += rt.right-rt.left;
739
740 SetWindowPos(_hsidebar, 0, -1, rect.top-1, rt.right-rt.left, rect.bottom-rect.top+1, SWP_NOACTIVATE|SWP_NOZORDER);
741 }
742
743 _clnt_rect = rect;
744
745 resize_children();
746 }
747
748 void MainFrame::resize_children()
749 {
750 HDWP hdwp = BeginDeferWindowPos(2);
751
752 int cx = _clnt_rect.left;
753
754 if (_left_hwnd) {
755 cx = _split_pos + SPLIT_WIDTH/2;
756
757 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);
758 } else {
759 //_split_pos = 0;
760 cx = 0;
761 }
762
763 if (_right_hwnd)
764 hdwp = DeferWindowPos(hdwp, _right_hwnd, 0, _clnt_rect.left+cx, _clnt_rect.top, _clnt_rect.right-cx, _clnt_rect.bottom-_clnt_rect.top, SWP_NOZORDER|SWP_NOACTIVATE);
765
766 EndDeferWindowPos(hdwp);
767 }
768
769 void MainFrame::update_clnt_rect()
770 {
771 ClientRect rect(_hwnd);
772
773 resize_frame(rect.right, rect.bottom);
774 }
775
776 void MainFrame::set_url(LPCTSTR url)
777 {
778 if (_url != url) {
779 _url = url;
780
781 SetWindowText(_haddressedit, url); //SendMessage(_hwndFrame, PM_URL_CHANGED, 0, (LPARAM)url);
782 }
783 }
784
785 bool MainFrame::go_to(LPCTSTR url, bool new_window)
786 {
787 if (_right_hwnd) {
788 SendMessage(_right_hwnd, PM_JUMP_TO_URL, 0, (LPARAM)url);
789 return true;
790 }
791
792 return false;
793 }