2 * Copyright 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
21 // ROS Internet Web Browser
25 // Martin Fuchs, 24.01.2005
31 #include "ibrowser_intres.h"
33 #include <locale.h> // for setlocale()
36 #include <io.h> // for dup2()
37 #include <fcntl.h> // for _O_RDONLY
43 HINSTANCE g_hInstance
;
44 IconCache g_icon_cache
;
49 void ExplorerGlobals::read_persistent()
51 // read configuration file
52 _cfg_dir.printf(TEXT("%s\\ReactOS"), (LPCTSTR)SpecialFolderFSPath(CSIDL_APPDATA,0));
53 _cfg_path.printf(TEXT("%s\\ros-ibrowser-cfg.xml"), _cfg_dir.c_str());
55 if (!_cfg.read(_cfg_path)) {
56 if (_cfg._last_error != XML_ERROR_NO_ELEMENTS)
57 MessageBox(g_Globals._hwndDesktop, String(_cfg._last_error_msg.c_str()),
58 TEXT("ROS Explorer - reading user settings"), MB_OK);
60 _cfg.read(TEXT("ibrowser-cfg-template.xml"));
64 _favorites_path.printf(TEXT("%s\\ros-ibrowser-bookmarks.xml"), _cfg_dir.c_str());
66 if (!_favorites.read(_favorites_path)) {
67 _favorites.import_IE_favorites(0);
68 _favorites.write(_favorites_path);
72 void ExplorerGlobals::write_persistent()
74 // write configuration file
75 RecursiveCreateDirectory(_cfg_dir);
77 _cfg.write(_cfg_path);
78 _favorites.write(_favorites_path);
82 XMLPos ExplorerGlobals::get_cfg()
84 XMLPos cfg_pos(&_cfg);
86 cfg_pos.smart_create("ibrowser-cfg");
91 XMLPos ExplorerGlobals::get_cfg(const char* path)
93 XMLPos cfg_pos(&_cfg);
95 cfg_pos.smart_create("ibrowser-cfg");
96 cfg_pos.create_relative(path);
110 Icon::Icon(ICON_ID id
, UINT nid
)
113 _hicon(SmallIcon(nid
))
117 Icon::Icon(ICON_TYPE itype
, int id
, HICON hIcon
)
124 Icon::Icon(ICON_TYPE itype
, int id
, int sys_idx
)
131 void Icon::draw(HDC hdc
, int x
, int y
, int cx
, int cy
, COLORREF bk_color
, HBRUSH bk_brush
) const
133 if (_itype
== IT_SYSCACHE
)
134 ImageList_DrawEx(g_icon_cache
.get_sys_imagelist(), _sys_idx
, hdc
, x
, y
, cx
, cy
, bk_color
, CLR_DEFAULT
, ILD_NORMAL
);
136 DrawIconEx(hdc
, x
, y
, _hicon
, cx
, cy
, 0, bk_brush
, DI_NORMAL
);
139 HBITMAP
Icon::create_bitmap(COLORREF bk_color
, HBRUSH hbrBkgnd
, HDC hdc_wnd
) const
141 if (_itype
== IT_SYSCACHE
) {
142 HIMAGELIST himl
= g_icon_cache
.get_sys_imagelist();
145 ImageList_GetIconSize(himl
, &cx
, &cy
);
147 HBITMAP hbmp
= CreateCompatibleBitmap(hdc_wnd
, cx
, cy
);
148 HDC hdc
= CreateCompatibleDC(hdc_wnd
);
149 HBITMAP hbmp_old
= SelectBitmap(hdc
, hbmp
);
150 ImageList_DrawEx(himl
, _sys_idx
, hdc
, 0, 0, cx
, cy
, bk_color
, CLR_DEFAULT
, ILD_NORMAL
);
151 SelectBitmap(hdc
, hbmp_old
);
156 return create_bitmap_from_icon(_hicon
, hbrBkgnd
, hdc_wnd
);
160 int Icon::add_to_imagelist(HIMAGELIST himl
, HDC hdc_wnd
, COLORREF bk_color
, HBRUSH bk_brush
) const
164 if (_itype
== IT_SYSCACHE
) {
165 HIMAGELIST himl
= g_icon_cache
.get_sys_imagelist();
168 ImageList_GetIconSize(himl
, &cx
, &cy
);
170 HBITMAP hbmp
= CreateCompatibleBitmap(hdc_wnd
, cx
, cy
);
171 HDC hdc
= CreateCompatibleDC(hdc_wnd
);
172 HBITMAP hbmp_old
= SelectBitmap(hdc
, hbmp
);
173 ImageList_DrawEx(himl
, _sys_idx
, hdc
, 0, 0, cx
, cy
, bk_color
, CLR_DEFAULT
, ILD_NORMAL
);
174 SelectBitmap(hdc
, hbmp_old
);
177 ret
= ImageList_Add(himl
, hbmp
, 0);
181 ret
= ImageList_AddAlphaIcon(himl
, _hicon
, bk_brush
, hdc_wnd
);
186 HBITMAP
create_bitmap_from_icon(HICON hIcon
, HBRUSH hbrush_bkgnd
, HDC hdc_wnd
)
188 int cx
= GetSystemMetrics(SM_CXSMICON
);
189 int cy
= GetSystemMetrics(SM_CYSMICON
);
190 HBITMAP hbmp
= CreateCompatibleBitmap(hdc_wnd
, cx
, cy
);
193 BitmapSelection
sel(canvas
, hbmp
);
195 RECT rect
= {0, 0, cx
, cy
};
196 FillRect(canvas
, &rect
, hbrush_bkgnd
);
198 DrawIconEx(canvas
, 0, 0, hIcon
, cx
, cy
, 0, hbrush_bkgnd
, DI_NORMAL
);
203 int ImageList_AddAlphaIcon(HIMAGELIST himl
, HICON hIcon
, HBRUSH hbrush_bkgnd
, HDC hdc_wnd
)
205 HBITMAP hbmp
= create_bitmap_from_icon(hIcon
, hbrush_bkgnd
, hdc_wnd
);
207 int ret
= ImageList_Add(himl
, hbmp
, 0);
215 int IconCache::s_next_id
= ICID_DYNAMIC
;
218 void IconCache::init()
220 _icons
[ICID_NONE
] = Icon(IT_STATIC
, ICID_NONE
, (HICON
)0);
222 _icons
[ICID_IBROWSER
] = Icon(ICID_IBROWSER
, IDI_IBROWSER
);
223 _icons
[ICID_BOOKMARK
] = Icon(ICID_BOOKMARK
, IDI_DOT_TRANS
);
227 const Icon
& IconCache::extract(const String
& path
)
229 PathMap::iterator found
= _pathMap
.find(path
);
231 if (found
!= _pathMap
.end())
232 return _icons
[found
->second
];
236 #if 1 // use system image list
237 HIMAGELIST himlSys
= (HIMAGELIST
) SHGetFileInfo(path
, 0, &sfi
, sizeof(sfi
), SHGFI_SYSICONINDEX
|SHGFI_SMALLICON
);
242 const Icon
& icon
= add(sfi
.iIcon
/*, IT_SYSCACHE*/);
244 if (SHGetFileInfo(path
, 0, &sfi
, sizeof(sfi
), SHGFI_ICON
|SHGFI_SMALLICON
)) {
245 const Icon
& icon
= add(sfi
.hIcon
, IT_CACHED
);
248 ///@todo limit cache size
249 _pathMap
[path
] = icon
;
253 return _icons
[ICID_NONE
];
256 const Icon
& IconCache::extract(LPCTSTR path
, int idx
)
258 CachePair
key(path
, idx
);
260 #ifndef __WINE__ ///@todo _tcslwr() for Wine
261 _tcslwr((LPTSTR
)key
.first
.c_str());
264 PathIdxMap::iterator found
= _pathIdxMap
.find(key
);
266 if (found
!= _pathIdxMap
.end())
267 return _icons
[found
->second
];
271 if ((int)ExtractIconEx(path
, idx
, NULL
, &hIcon
, 1) > 0) {
272 const Icon
& icon
= add(hIcon
, IT_CACHED
);
274 _pathIdxMap
[key
] = icon
;
279 ///@todo retreive "http://.../favicon.ico" format icons
281 return _icons
[ICID_NONE
];
286 const Icon
& IconCache::add(HICON hIcon
, ICON_TYPE type
)
288 int id
= ++s_next_id
;
290 return _icons
[id
] = Icon(type
, id
, hIcon
);
293 const Icon
& IconCache::add(int sys_idx
/*, ICON_TYPE type=IT_SYSCACHE*/)
295 int id
= ++s_next_id
;
297 return _icons
[id
] = SysCacheIcon(id
, sys_idx
);
300 const Icon
& IconCache::get_icon(int id
)
305 void IconCache::free_icon(int icon_id
)
307 IconMap::iterator found
= _icons
.find(icon_id
);
309 if (found
!= _icons
.end()) {
310 Icon
& icon
= found
->second
;
318 ResString::ResString(UINT nid
)
320 TCHAR buffer
[BUFFER_LEN
];
322 int len
= LoadString(g_hInstance
, nid
, buffer
, sizeof(buffer
)/sizeof(TCHAR
));
324 super::assign(buffer
, len
);
328 ResIcon::ResIcon(UINT nid
)
330 _hicon
= LoadIcon(g_hInstance
, MAKEINTRESOURCE(nid
));
333 SmallIcon::SmallIcon(UINT nid
)
335 _hicon
= (HICON
)LoadImage(g_hInstance
, MAKEINTRESOURCE(nid
), IMAGE_ICON
, GetSystemMetrics(SM_CXSMICON
), GetSystemMetrics(SM_CYSMICON
), LR_SHARED
);
338 ResIconEx::ResIconEx(UINT nid
, int w
, int h
)
340 _hicon
= (HICON
)LoadImage(g_hInstance
, MAKEINTRESOURCE(nid
), IMAGE_ICON
, w
, h
, LR_SHARED
);
344 void SetWindowIcon(HWND hwnd
, UINT nid
)
346 HICON hIcon
= ResIcon(nid
);
347 (void)Window_SetIcon(hwnd
, ICON_BIG
, hIcon
);
349 HICON hIconSmall
= SmallIcon(nid
);
350 (void)Window_SetIcon(hwnd
, ICON_SMALL
, hIconSmall
);
354 ResBitmap::ResBitmap(UINT nid
)
356 _hBmp
= LoadBitmap(g_hInstance
, MAKEINTRESOURCE(nid
));
360 void ibrowser_show_frame(int cmdshow
, LPTSTR lpCmdLine
)
362 MainFrameBase::Create(lpCmdLine
, cmdshow
);
366 PopupMenu::PopupMenu(UINT nid
)
368 HMENU hMenu
= LoadMenu(g_hInstance
, MAKEINTRESOURCE(nid
));
369 _hmenu
= GetSubMenu(hMenu
, 0);
374 struct ExplorerAboutDlg
: public
376 OwnerDrawParent
<Dialog
>
379 typedef CtlColorParent
<
380 OwnerDrawParent
<Dialog
>
383 ExplorerAboutDlg(HWND hwnd
)
386 SetWindowIcon(hwnd
, IDI_REACTOS
);
388 new FlatButton(hwnd
, IDOK
);
390 _hfont
= CreateFont(20, 0, 0, 0, FW_BOLD
, TRUE
, 0, 0, 0, 0, 0, 0, 0, TEXT("Sans Serif"));
391 new ColorStatic(hwnd
, IDC_ROS_IBROWSER
, RGB(32,32,128), 0, _hfont
);
393 new HyperlinkCtrl(hwnd
, IDC_WWW
);
395 FmtString
ver_txt(ResString(IDS_IBROWSER_VERSION_STR
), (LPCTSTR
)ResString(IDS_VERSION_STR
));
396 SetWindowText(GetDlgItem(hwnd
, IDC_VERSION_TXT
), ver_txt
);
399 HWND hwnd_winver = GetDlgItem(hwnd, IDC_WIN_VERSION);
400 SetWindowText(hwnd_winver, get_windows_version_str());
401 SetWindowFont(hwnd_winver, GetStockFont(DEFAULT_GUI_FONT), FALSE);
409 DeleteObject(_hfont
);
416 void ibrowser_about(HWND hwndParent
)
418 Dialog::DoModal(IDD_ABOUT_IBROWSER
, WINDOW_CREATOR(ExplorerAboutDlg
), hwndParent
);
420 void ibrowser_open(HWND hwndParent
)
423 RUNFILEDLG RunFileDlg
;
424 OSVERSIONINFO versionInfo
;
427 char szTitle
[40] = "Open";
428 char szText
[256] = "Type the Internet Address of a document or folder and IBrowser will open it for you.";
430 hShell32
= LoadLibrary(_T("SHELL32.DLL"));
431 RunFileDlg
= (RUNFILEDLG
)(FARPROC
)GetProcAddress(hShell32
, (char*)((long)0x3D));
433 /* Show "Run..." dialog */
436 versionInfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
437 GetVersionEx(&versionInfo
);
439 if (versionInfo
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
441 MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, szTitle
, -1, wTitle
, 40);
442 MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, szText
, -1, wText
, 256);
443 RunFileDlg(hwndParent
, 0, NULL
, (LPCSTR
)wTitle
, (LPCSTR
)wText
, RFF_CALCDIRECTORY
);
446 RunFileDlg(hwndParent
, 0, NULL
, szTitle
, szText
, RFF_CALCDIRECTORY
);
449 FreeLibrary(hShell32
);
452 static void InitInstance(HINSTANCE hInstance
)
454 CONTEXT("InitInstance");
456 // register frame window class
457 g_hframeClass
= IconWindowClass(CLASSNAME_FRAME
,IDI_IBROWSER
);
459 // register child window class
460 WindowClass(CLASSNAME_CHILDWND
, CS_CLASSDC
|CS_VREDRAW
).Register();
464 int ibrowser_main(HINSTANCE hInstance
, LPTSTR lpCmdLine
, int cmdshow
)
466 CONTEXT("ibrowser_main");
468 // initialize Common Controls library
469 CommonControlInit usingCmnCtrl
;
472 InitInstance(hInstance
);
473 } catch(COMException
& e
) {
474 HandleException(e
, GetDesktopWindow());
478 if (cmdshow
!= SW_HIDE
) {
479 /* // don't maximize if being called from the ROS desktop
480 if (cmdshow == SW_SHOWNORMAL)
481 ///@todo read window placement from registry
482 cmdshow = SW_MAXIMIZE;
485 ibrowser_show_frame(cmdshow
, lpCmdLine
);
488 return Window::MessageLoop();
492 // MinGW does not provide a Unicode startup routine, so we have to implement an own.
493 #if defined(__MINGW32__) && defined(UNICODE)
495 #define _tWinMain wWinMain
496 int WINAPI
wWinMain(HINSTANCE
, HINSTANCE
, LPWSTR
, int);
498 int main(int argc
, char* argv
[])
502 STARTUPINFO startupinfo
;
503 int nShowCmd
= SW_SHOWNORMAL
;
505 GetStartupInfo(&startupinfo
);
507 if (startupinfo
.dwFlags
& STARTF_USESHOWWINDOW
)
508 nShowCmd
= startupinfo
.wShowWindow
;
510 LPWSTR cmdline
= GetCommandLineW();
512 while(*cmdline
&& !_istspace(*cmdline
))
515 while(_istspace(*cmdline
))
518 return wWinMain(GetModuleHandle(NULL
), 0, cmdline
, nShowCmd
);
521 #endif // __MINGW && UNICODE
524 int WINAPI
_tWinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPTSTR lpCmdLine
, int nShowCmd
)
526 CONTEXT("WinMain()");
528 g_hInstance
= hInstance
;
530 // initialize COM and OLE before creating the desktop window
533 // init common controls library
534 CommonControlInit usingCmnCtrl
;
536 //@@ g_Globals.read_persistent();
538 /**TODO fix command line handling */
539 if (*lpCmdLine
=='"' && lpCmdLine
[_tcslen(lpCmdLine
)-1]=='"') {
541 lpCmdLine
[_tcslen(lpCmdLine
)-1] = '\0';
544 int ret
= ibrowser_main(hInstance
, lpCmdLine
, nShowCmd
);
546 // write configuration file
547 //@@ g_Globals.write_persistent();