first draft of SDI browser application derived from ROS Explorer

svn path=/trunk/; revision=13302
This commit is contained in:
Martin Fuchs 2005-01-26 00:12:33 +00:00
parent b55653e57c
commit 0cf4124706
37 changed files with 12385 additions and 0 deletions

View file

@ -0,0 +1,47 @@
#
# ROS Internet Web Browser
#
# Makefile
#
PATH_TO_TOP := ../../..
TARGET_TYPE := program
TARGET_APPTYPE := windows
TARGET_NAME := ibrowser
TARGET_INSTALLDIR := .
TARGET_CFLAGS := \
-D__USE_W32API -DWIN32 -D_ROS_ \
-D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500 \
-DUNICODE -fexceptions -Wall
TARGET_CPPFLAGS := $(TARGET_CFLAGS)
TARGET_RCFLAGS := -D__USE_W32API -DWIN32 -D_ROS_ -D__WINDRES__
TARGET_SDKLIBS := gdi32.a comctl32.a ole32.a oleaut32.a shell32.a expat.a
TARGET_GCCLIBS := stdc++ uuid
TARGET_OBJECTS := \
ibrowser.o \
mainframe.o \
webchild.o \
favorites.o \
utility/utility.o \
utility/window.o \
utility/xmlstorage.o
TARGET_CPPAPP := yes
TARGET_PCH := precomp.h
DEP_OBJECTS := $(TARGET_OBJECTS)
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
include $(TOOLS_PATH)/depend.mk

View file

@ -0,0 +1,67 @@
#
# ROS Internet Web Browser
#
# Makefile.MinGW
#
CC = gcc
CXX = g++
LINK = g++
CFLAGS = -DWIN32 -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500 -fexceptions -Wall -I.
RCFLAGS = -DWIN32 -D__WINDRES__
LFLAGS = -Wl,--subsystem,windows
ifdef DEBUG
CFLAGS += -D_DEBUG -g
RCFLAGS += -D_DEBUG
LFLAGS += -g
else
CFLAGS += -DNDEBUG -Os
RCFLAGS += -DNDEBUG
LFLAGS += -s
endif
ifndef UNICODE
UNICODE = 1
endif
ifeq ($(UNICODE),1)
CFLAGS += -DUNICODE
# LFLAGS+= -Wl,--entry,_wWinMain@16
RCFLAGS += -DUNICODE
endif
CXXFLAGS = $(CFLAGS)
EXEC_SUFFIX = .exe
RES_SUFFIX = .coff
VPATH = utility
PROGRAM = ibrowser
TARGET = $(PROGRAM)$(EXEC_SUFFIX)
OBJECTS = \
utility.o \
window.o \
ibrowser.o \
webchild.o \
mainframe.o \
favorites.o \
xmlstorage.o
LIBS = gdi32 comctl32 shell32 ole32 uuid oleaut32
all: $(TARGET)
$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) libexpat.dll
$(LINK) $(LFLAGS) -o $@ $^ $(addprefix -l,$(LIBS)) $(addprefix -l,$(DELAYIMPORTS))
ibrowser$(RES_SUFFIX): $(PROGRAM)_intres.rc res/*.bmp res/*.ico
windres $(RCFLAGS) -o $@ $(PROGRAM)_intres.rc
clean:
rm -f $(TARGET) $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) \
desktop/*.o dialogs/*.o shell/*.o taskbar/*.o utility/*.o

View file

@ -0,0 +1,72 @@
#
# ROS Internet Web Browser
#
# Makefile.PCH
#
# MinGW Makefile with precompiled header support
#
CC = gcc
CXX = g++
LINK = g++
CFLAGS = -DWIN32 -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500 -fexceptions -Wall -I.
RCFLAGS = -DWIN32 -D__WINDRES__
LFLAGS = -Wl,--subsystem,windows
ifdef DEBUG
CFLAGS += -D_DEBUG -g
RCFLAGS += -D_DEBUG
LFLAGS += -g
else
CFLAGS += -DNDEBUG -Os -march=pentium4
RCFLAGS += -DNDEBUG
LFLAGS += -s
endif
ifndef UNICODE
UNICODE = 1
endif
ifeq ($(UNICODE),1)
CFLAGS += -DUNICODE
# LFLAGS+= -Wl,--entry,_wWinMain@16
RCFLAGS += -DUNICODE
endif
CXXFLAGS = $(CFLAGS)
EXEC_SUFFIX = .exe
RES_SUFFIX = .coff
VPATH = utility
PROGRAM = ibrowser
TARGET = $(PROGRAM)$(EXEC_SUFFIX)
OBJECTS = \
utility.o \
window.o \
ibrowser.o \
webchild.o \
mainframe.o \
favorites.o \
xmlstorage.o
LIBS = gdi32 comctl32 shell32 ole32 oleaut32 uuid
all: precomp.h.gch $(TARGET)
precomp.h.gch: *.h utility/*.h
$(CXX) $(CFLAGS) precomp.h
$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) libexpat.dll
$(LINK) $(LFLAGS) -o $@ $^ $(addprefix -l,$(LIBS)) $(addprefix -l,$(DELAYIMPORTS))
ibrowser$(RES_SUFFIX): $(PROGRAM)_intres.rc res/*.bmp res/*.ico
windres $(RCFLAGS) -o $@ $(PROGRAM)_intres.rc
clean:
rm -f $(TARGET) $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) precomp.h.gch \
utility/*.o

View file

@ -0,0 +1,22 @@
Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
and Clark Cooper
Copyright (c) 2001, 2002, 2003 Expat maintainers.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,494 @@
/*
* Copyright 2004 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// Explorer and Desktop clone
//
// favorites.cpp
//
// Martin Fuchs, 04.04.2004
//
#include "precomp.h"
String DecodeURLString(const char* s)
{
TCHAR buffer[BUFFER_LEN];
LPTSTR o = buffer;
for(const char* p=s; *p; ++p)
if (*p == '%') {
if (!strncmp(p+1, "20", 2)) {
*o++ = ' ';
p += 2;
} else
*o++ = *p;
} else
*o++ = *p;
return String(buffer, o-buffer);
}
/// read .URL file
bool Bookmark::read_url(LPCTSTR path)
{
char line[BUFFER_LEN];
tifstream in(path);
while(in.good()) {
in.getline(line, BUFFER_LEN);
const char* p = line;
while(isspace(*p))
++p;
const char* keyword = p;
const char* eq = strchr(p, '=');
if (eq) {
const char* cont = eq + 1;
while(isspace(*cont))
++cont;
if (!strnicmp(keyword, "URL", 3))
_url = DecodeURLString(cont);
else if (!strnicmp(keyword, "IconFile", 8))
_icon_path = DecodeURLString(cont);
}
}
return true;
}
/// convert XBEL bookmark node
bool Bookmark::read(const_XMLPos& pos)
{
_url = pos.get("href").c_str();
if (pos.go_down("title")) {
_name = pos->get_content();
pos.back();
}
if (pos.go_down("desc")) {
_description = pos->get_content();
pos.back();
}
if (pos.go_down("info")) {
const_XMLChildrenFilter metadata(pos, "metadata");
for(const_XMLChildrenFilter::const_iterator it=metadata.begin(); it!=metadata.end(); ++it) {
const XMLNode& node = **it;
const_XMLPos sub_pos(&node);
if (node.get("owner") == "ros-explorer") {
if (sub_pos.go_down("icon")) {
_icon_path = sub_pos.get("path").c_str();
_icon_idx = XS_toi(sub_pos.get("index"));
sub_pos.back(); // </icon>
}
}
}
pos.back(); // </metadata>
pos.back(); // </info>
}
return !_url.empty(); // _url is mandatory.
}
/// write XBEL bookmark node
void Bookmark::write(XMLPos& pos) const
{
pos.create("bookmark");
pos["href"] = _url.c_str();
if (!_name.empty()) {
pos.create("title");
pos->set_content(_name);
pos.back();
}
if (!_description.empty()) {
pos.create("desc");
pos->set_content(_description);
pos.back();
}
if (!_icon_path.empty()) {
pos.create("info");
pos.create("metadata");
pos["owner"] = "ros-explorer";
pos.create("icon");
pos["path"] = _icon_path.c_str();
pos["index"].printf(XS_TEXT("%d"), _icon_idx);
pos.back(); // </icon>
pos.back(); // </metadata>
pos.back(); // </info>
}
pos.back();
}
/// read bookmark folder from XBEL formated XML tree
void BookmarkFolder::read(const_XMLPos& pos)
{
if (pos.go_down("title")) {
_name = pos->get_content();
pos.back();
}
if (pos.go_down("desc")) {
_description = pos->get_content();
pos.back();
}
_bookmarks.read(pos);
}
/// write bookmark folder content from XBEL formated XML tree
void BookmarkFolder::write(XMLPos& pos) const
{
pos.create("folder");
if (!_name.empty()) {
pos.create("title");
pos->set_content(_name);
pos.back();
}
if (!_description.empty()) {
pos.create("desc");
pos->set_content(_description);
pos.back();
}
_bookmarks.write(pos);
}
BookmarkNode::BookmarkNode()
: _type(BMNT_NONE)
{
_pbookmark = NULL;
}
BookmarkNode::BookmarkNode(const Bookmark& bm)
: _type(BMNT_BOOKMARK)
{
_pbookmark = new Bookmark(bm);
}
BookmarkNode::BookmarkNode(const BookmarkFolder& bmf)
: _type(BMNT_FOLDER)
{
_pfolder = new BookmarkFolder(bmf);
}
BookmarkNode::BookmarkNode(const BookmarkNode& other)
: _type(other._type)
{
if (other._type == BMNT_BOOKMARK)
_pbookmark = new Bookmark(*other._pbookmark);
else if (other._type == BMNT_FOLDER)
_pfolder = new BookmarkFolder(*other._pfolder);
else
_pbookmark = NULL;
}
BookmarkNode::~BookmarkNode()
{
if (_type == BMNT_BOOKMARK)
delete _pbookmark;
else if (_type == BMNT_FOLDER)
delete _pfolder;
}
BookmarkNode& BookmarkNode::operator=(const Bookmark& bm)
{
clear();
_pbookmark = new Bookmark(bm);
return *this;
}
BookmarkNode& BookmarkNode::operator=(const BookmarkFolder& bmf)
{
clear();
_pfolder = new BookmarkFolder(bmf);
return *this;
}
BookmarkNode& BookmarkNode::operator=(const BookmarkNode& other)
{
clear();
_type = other._type;
if (other._type == BMNT_BOOKMARK)
_pbookmark = new Bookmark(*other._pbookmark);
else if (other._type == BMNT_FOLDER)
_pfolder = new BookmarkFolder(*other._pfolder);
return *this;
}
void BookmarkNode::clear()
{
if (_type == BMNT_BOOKMARK) {
delete _pbookmark;
_pbookmark = NULL;
}
else if (_type == BMNT_FOLDER) {
delete _pfolder;
_pfolder = NULL;
}
_type = BMNT_NONE;
}
/// read bookmark list from XBEL formated XML tree
void BookmarkList::read(const_XMLPos& pos)
{
const XMLNode::Children& children = pos->get_children();
for(XMLNode::Children::const_iterator it=children.begin(); it!=children.end(); ++it) {
const XMLNode& node = **it;
const_XMLPos sub_pos(&node);
if (node == "folder") {
BookmarkFolder folder;
folder.read(sub_pos);
push_back(folder);
} else if (node == "bookmark") {
Bookmark bookmark;
if (bookmark.read(sub_pos))
push_back(bookmark);
}
}
}
/// write bookmark list into XBEL formated XML tree
void BookmarkList::write(XMLPos& pos) const
{
for(const_iterator it=begin(); it!=end(); ++it) {
const BookmarkNode& node = *it;
if (node._type == BookmarkNode::BMNT_FOLDER) {
const BookmarkFolder& folder = *node._pfolder;
folder.write(pos);
pos.back();
} else if (node._type == BookmarkNode::BMNT_BOOKMARK) {
const Bookmark& bookmark = *node._pbookmark;
if (!bookmark._url.empty())
bookmark.write(pos);
}
}
}
/// fill treeview control with bookmark tree content
void BookmarkList::fill_tree(HWND hwnd, HTREEITEM parent, HIMAGELIST himagelist, HDC hdc_wnd) const
{
TV_INSERTSTRUCT tvi;
tvi.hParent = parent;
tvi.hInsertAfter = TVI_LAST;
TV_ITEM& tv = tvi.item;
tv.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
for(const_iterator it=begin(); it!=end(); ++it) {
const BookmarkNode& node = *it;
tv.lParam = (LPARAM)&node;
if (node._type == BookmarkNode::BMNT_FOLDER) {
const BookmarkFolder& folder = *node._pfolder;
tv.pszText = (LPTSTR)folder._name.c_str();
tv.iImage = 3; // folder
tv.iSelectedImage = 4; // open folder
HTREEITEM hitem = TreeView_InsertItem(hwnd, &tvi);
folder._bookmarks.fill_tree(hwnd, hitem, himagelist, hdc_wnd);
} else if (node._type == BookmarkNode::BMNT_BOOKMARK) {
const Bookmark& bookmark = *node._pbookmark;
tv.pszText = (LPTSTR)bookmark._name.c_str();
tv.iImage = 1; // bookmark
tv.iSelectedImage = 2; // selected bookmark
if (!bookmark._icon_path.empty()) {
const Icon& icon = g_icon_cache.extract(bookmark._icon_path, bookmark._icon_idx);
if ((ICON_ID)icon != ICID_NONE)
tv.iImage = tv.iSelectedImage = icon.add_to_imagelist(himagelist, hdc_wnd);
}
TreeView_InsertItem(hwnd, &tvi);
}
}
}
/*@@
/// import Internet Explorer bookmarks from Favorites folder into bookmark list
void BookmarkList::import_IE_favorites(ShellDirectory& dir, HWND hwnd)
{
TCHAR path[MAX_PATH], ext[_MAX_EXT];
dir.smart_scan(SORT_NAME, SCAN_FILESYSTEM);
for(Entry*entry=dir._down; entry; entry=entry->_next) {
if (entry->_shell_attribs & SFGAO_HIDDEN) // ignore files like "desktop.ini"
continue;
String name;
if (entry->_etype == ET_SHELL)
name = dir._folder.get_name(static_cast<ShellEntry*>(entry)->_pidl);
else
name = entry->_display_name;
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
BookmarkFolder new_folder;
new_folder._name = DecodeXMLString(name);
if (entry->_etype == ET_SHELL) {
ShellDirectory new_dir(dir._folder, static_cast<ShellEntry*>(entry)->_pidl, hwnd);
new_folder._bookmarks.import_IE_favorites(new_dir, hwnd);
} else {
entry->get_path(path);
ShellDirectory new_dir(GetDesktopFolder(), path, hwnd);
new_folder._bookmarks.import_IE_favorites(new_dir, hwnd);
}
push_back(new_folder);
} else {
Bookmark bookmark;
bookmark._name = DecodeXMLString(name);
entry->get_path(path);
_tsplitpath(path, NULL, NULL, NULL, ext);
if (!_tcsicmp(ext, TEXT(".url"))) {
bookmark.read_url(path);
push_back(bookmark);
} else {
///@todo read shell links
//assert(0);
}
}
}
}
*/
/// read XBEL bookmark file
bool Favorites::read(LPCTSTR path)
{
XMLDoc xbel;
if (!xbel.read(path))
if (xbel._last_error == XML_ERROR_NO_ELEMENTS)
return false;
else
MessageBox(0/*@@g_Globals._hwndDesktop*/, String(xbel._last_error_msg.c_str()),
TEXT("ROS Explorer - reading bookmark file"), MB_OK);
const_XMLPos pos(&xbel);
if (!pos.go_down("xbel"))
return false;
super::read(pos);
pos.back();
return true;
}
/// write XBEL bookmark file
void Favorites::write(LPCTSTR path) const
{
XMLDoc xbel;
XMLPos pos(&xbel);
pos.create("xbel");
super::write(pos);
pos.back();
xbel.write(path, XMLNode::FORMAT_SMART, XMLHeader("1.0", "UTF-8", "<!DOCTYPE xbel"
" PUBLIC \"+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML\"\n"
" \"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd\">"));
}
/*@@
/// import Internet Explorer bookmarks from Favorites folder
bool Favorites::import_IE_favorites(HWND hwnd)
{
WaitCursor wait;
StartMenuShellDirs dirs;
try {
dirs.push_back(ShellDirectory(GetDesktopFolder(), SpecialFolderPath(CSIDL_COMMON_FAVORITES, hwnd), hwnd));
dirs.push_back(ShellDirectory(GetDesktopFolder(), SpecialFolderPath(CSIDL_FAVORITES, hwnd), hwnd));
} catch(COMException&) {
}
for(StartMenuShellDirs::iterator it=dirs.begin(); it!=dirs.end(); ++it) {
StartMenuDirectory& smd = *it;
ShellDirectory& dir = smd._dir;
try {
super::import_IE_favorites(dir, hwnd);
} catch(COMException&) {
}
}
return true;
}
*/

View file

@ -0,0 +1,104 @@
/*
* Copyright 2004 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// Explorer and Desktop clone
//
// favorites.h
//
// Martin Fuchs, 04.04.2004
//
extern String DecodeURLString(const char* s);
struct Bookmark
{
Bookmark() : _icon_idx(0) {}
String _name;
String _description;
String _url;
String _icon_path;
int _icon_idx;
bool read_url(LPCTSTR path);
bool read(const_XMLPos& pos);
void write(XMLPos& pos) const;
};
struct BookmarkFolder;
struct BookmarkNode
{
BookmarkNode();
BookmarkNode(const Bookmark& bm);
BookmarkNode(const BookmarkFolder& bmf);
BookmarkNode(const BookmarkNode& other);
~BookmarkNode();
BookmarkNode& operator=(const Bookmark& bm);
BookmarkNode& operator=(const BookmarkFolder& bmf);
BookmarkNode& operator=(const BookmarkNode& other);
void clear();
enum BOOKMARKNODE_TYPE {
BMNT_NONE, BMNT_BOOKMARK, BMNT_FOLDER
};
BOOKMARKNODE_TYPE _type;
union {
Bookmark* _pbookmark;
BookmarkFolder* _pfolder;
};
};
struct BookmarkList : public list<BookmarkNode>
{
void import_IE_favorites(struct ShellDirectory& dir, HWND hwnd);
void read(const_XMLPos& pos);
void write(XMLPos& pos) const;
void fill_tree(HWND hwnd, HTREEITEM parent, HIMAGELIST, HDC hdc_wnd) const;
};
struct BookmarkFolder
{
String _name;
String _description;
BookmarkList _bookmarks;
void read(const_XMLPos& pos);
void write(XMLPos& pos) const;
};
struct Favorites : public BookmarkList
{
typedef BookmarkList super;
bool read(LPCTSTR path);
void write(LPCTSTR path) const;
bool import_IE_favorites(HWND hwnd);
};

View file

@ -0,0 +1,517 @@
/*
* Copyright 2005 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// ROS Internet Web Browser
//
// ibrowser.cpp
//
// Martin Fuchs, 24.01.2005
//
#include "precomp.h"
#include "ibrowser_intres.h"
#include <locale.h> // for setlocale()
#ifndef __WINE__
#include <io.h> // for dup2()
#include <fcntl.h> // for _O_RDONLY
#endif
// globals
HINSTANCE g_hInstance;
IconCache g_icon_cache;
ATOM g_hframeClass;
/*@@
void ExplorerGlobals::read_persistent()
{
// read configuration file
_cfg_dir.printf(TEXT("%s\\ReactOS"), (LPCTSTR)SpecialFolderFSPath(CSIDL_APPDATA,0));
_cfg_path.printf(TEXT("%s\\ros-ibrowser-cfg.xml"), _cfg_dir.c_str());
if (!_cfg.read(_cfg_path)) {
if (_cfg._last_error != XML_ERROR_NO_ELEMENTS)
MessageBox(g_Globals._hwndDesktop, String(_cfg._last_error_msg.c_str()),
TEXT("ROS Explorer - reading user settings"), MB_OK);
_cfg.read(TEXT("ibrowser-cfg-template.xml"));
}
// read bookmarks
_favorites_path.printf(TEXT("%s\\ros-ibrowser-bookmarks.xml"), _cfg_dir.c_str());
if (!_favorites.read(_favorites_path)) {
_favorites.import_IE_favorites(0);
_favorites.write(_favorites_path);
}
}
void ExplorerGlobals::write_persistent()
{
// write configuration file
RecursiveCreateDirectory(_cfg_dir);
_cfg.write(_cfg_path);
_favorites.write(_favorites_path);
}
XMLPos ExplorerGlobals::get_cfg()
{
XMLPos cfg_pos(&_cfg);
cfg_pos.smart_create("ibrowser-cfg");
return cfg_pos;
}
XMLPos ExplorerGlobals::get_cfg(const char* path)
{
XMLPos cfg_pos(&_cfg);
cfg_pos.smart_create("ibrowser-cfg");
cfg_pos.create_relative(path);
return cfg_pos;
}
*/
Icon::Icon()
: _id(ICID_UNKNOWN),
_itype(IT_STATIC),
_hicon(0)
{
}
Icon::Icon(ICON_ID id, UINT nid)
: _id(id),
_itype(IT_STATIC),
_hicon(SmallIcon(nid))
{
}
Icon::Icon(ICON_TYPE itype, int id, HICON hIcon)
: _id((ICON_ID)id),
_itype(itype),
_hicon(hIcon)
{
}
Icon::Icon(ICON_TYPE itype, int id, int sys_idx)
: _id((ICON_ID)id),
_itype(itype),
_sys_idx(sys_idx)
{
}
void Icon::draw(HDC hdc, int x, int y, int cx, int cy, COLORREF bk_color, HBRUSH bk_brush) const
{
if (_itype == IT_SYSCACHE)
ImageList_DrawEx(g_icon_cache.get_sys_imagelist(), _sys_idx, hdc, x, y, cx, cy, bk_color, CLR_DEFAULT, ILD_NORMAL);
else
DrawIconEx(hdc, x, y, _hicon, cx, cy, 0, bk_brush, DI_NORMAL);
}
HBITMAP Icon::create_bitmap(COLORREF bk_color, HBRUSH hbrBkgnd, HDC hdc_wnd) const
{
if (_itype == IT_SYSCACHE) {
HIMAGELIST himl = g_icon_cache.get_sys_imagelist();
int cx, cy;
ImageList_GetIconSize(himl, &cx, &cy);
HBITMAP hbmp = CreateCompatibleBitmap(hdc_wnd, cx, cy);
HDC hdc = CreateCompatibleDC(hdc_wnd);
HBITMAP hbmp_old = SelectBitmap(hdc, hbmp);
ImageList_DrawEx(himl, _sys_idx, hdc, 0, 0, cx, cy, bk_color, CLR_DEFAULT, ILD_NORMAL);
SelectBitmap(hdc, hbmp_old);
DeleteDC(hdc);
return hbmp;
} else
return create_bitmap_from_icon(_hicon, hbrBkgnd, hdc_wnd);
}
int Icon::add_to_imagelist(HIMAGELIST himl, HDC hdc_wnd, COLORREF bk_color, HBRUSH bk_brush) const
{
int ret;
if (_itype == IT_SYSCACHE) {
HIMAGELIST himl = g_icon_cache.get_sys_imagelist();
int cx, cy;
ImageList_GetIconSize(himl, &cx, &cy);
HBITMAP hbmp = CreateCompatibleBitmap(hdc_wnd, cx, cy);
HDC hdc = CreateCompatibleDC(hdc_wnd);
HBITMAP hbmp_old = SelectBitmap(hdc, hbmp);
ImageList_DrawEx(himl, _sys_idx, hdc, 0, 0, cx, cy, bk_color, CLR_DEFAULT, ILD_NORMAL);
SelectBitmap(hdc, hbmp_old);
DeleteDC(hdc);
ret = ImageList_Add(himl, hbmp, 0);
DeleteObject(hbmp);
} else
ret = ImageList_AddAlphaIcon(himl, _hicon, bk_brush, hdc_wnd);
return ret;
}
HBITMAP create_bitmap_from_icon(HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd)
{
int cx = GetSystemMetrics(SM_CXSMICON);
int cy = GetSystemMetrics(SM_CYSMICON);
HBITMAP hbmp = CreateCompatibleBitmap(hdc_wnd, cx, cy);
MemCanvas canvas;
BitmapSelection sel(canvas, hbmp);
RECT rect = {0, 0, cx, cy};
FillRect(canvas, &rect, hbrush_bkgnd);
DrawIconEx(canvas, 0, 0, hIcon, cx, cy, 0, hbrush_bkgnd, DI_NORMAL);
return hbmp;
}
int ImageList_AddAlphaIcon(HIMAGELIST himl, HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd)
{
HBITMAP hbmp = create_bitmap_from_icon(hIcon, hbrush_bkgnd, hdc_wnd);
int ret = ImageList_Add(himl, hbmp, 0);
DeleteObject(hbmp);
return ret;
}
int IconCache::s_next_id = ICID_DYNAMIC;
void IconCache::init()
{
_icons[ICID_NONE] = Icon(IT_STATIC, ICID_NONE, (HICON)0);
_icons[ICID_IBROWSER] = Icon(ICID_IBROWSER, IDI_IBROWSER);
_icons[ICID_BOOKMARK] = Icon(ICID_BOOKMARK, IDI_DOT_TRANS);
}
const Icon& IconCache::extract(const String& path)
{
PathMap::iterator found = _pathMap.find(path);
if (found != _pathMap.end())
return _icons[found->second];
SHFILEINFO sfi;
#if 1 // use system image list
HIMAGELIST himlSys = (HIMAGELIST) SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
if (himlSys) {
_himlSys = himlSys;
const Icon& icon = add(sfi.iIcon/*, IT_SYSCACHE*/);
#else
if (SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_ICON|SHGFI_SMALLICON)) {
const Icon& icon = add(sfi.hIcon, IT_CACHED);
#endif
///@todo limit cache size
_pathMap[path] = icon;
return icon;
} else
return _icons[ICID_NONE];
}
const Icon& IconCache::extract(LPCTSTR path, int idx)
{
CachePair key(path, idx);
#ifndef __WINE__ ///@todo _tcslwr() for Wine
_tcslwr((LPTSTR)key.first.c_str());
#endif
PathIdxMap::iterator found = _pathIdxMap.find(key);
if (found != _pathIdxMap.end())
return _icons[found->second];
HICON hIcon;
if ((int)ExtractIconEx(path, idx, NULL, &hIcon, 1) > 0) {
const Icon& icon = add(hIcon, IT_CACHED);
_pathIdxMap[key] = icon;
return icon;
} else {
///@todo retreive "http://.../favicon.ico" format icons
return _icons[ICID_NONE];
}
}
const Icon& IconCache::add(HICON hIcon, ICON_TYPE type)
{
int id = ++s_next_id;
return _icons[id] = Icon(type, id, hIcon);
}
const Icon& IconCache::add(int sys_idx/*, ICON_TYPE type=IT_SYSCACHE*/)
{
int id = ++s_next_id;
return _icons[id] = SysCacheIcon(id, sys_idx);
}
const Icon& IconCache::get_icon(int id)
{
return _icons[id];
}
void IconCache::free_icon(int icon_id)
{
IconMap::iterator found = _icons.find(icon_id);
if (found != _icons.end()) {
Icon& icon = found->second;
if (icon.destroy())
_icons.erase(found);
}
}
ResString::ResString(UINT nid)
{
TCHAR buffer[BUFFER_LEN];
int len = LoadString(g_hInstance, nid, buffer, sizeof(buffer)/sizeof(TCHAR));
super::assign(buffer, len);
}
ResIcon::ResIcon(UINT nid)
{
_hicon = LoadIcon(g_hInstance, MAKEINTRESOURCE(nid));
}
SmallIcon::SmallIcon(UINT nid)
{
_hicon = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(nid), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED);
}
ResIconEx::ResIconEx(UINT nid, int w, int h)
{
_hicon = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(nid), IMAGE_ICON, w, h, LR_SHARED);
}
void SetWindowIcon(HWND hwnd, UINT nid)
{
HICON hIcon = ResIcon(nid);
Window_SetIcon(hwnd, ICON_BIG, hIcon);
HICON hIconSmall = SmallIcon(nid);
Window_SetIcon(hwnd, ICON_SMALL, hIconSmall);
}
ResBitmap::ResBitmap(UINT nid)
{
_hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(nid));
}
void ibrowser_show_frame(int cmdshow, LPTSTR lpCmdLine)
{
MainFrameBase::Create(lpCmdLine, cmdshow);
}
PopupMenu::PopupMenu(UINT nid)
{
HMENU hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(nid));
_hmenu = GetSubMenu(hMenu, 0);
}
/// "About Explorer" Dialog
struct ExplorerAboutDlg : public
CtlColorParent<
OwnerDrawParent<Dialog>
>
{
typedef CtlColorParent<
OwnerDrawParent<Dialog>
> super;
ExplorerAboutDlg(HWND hwnd)
: super(hwnd)
{
SetWindowIcon(hwnd, IDI_REACTOS);
new FlatButton(hwnd, IDOK);
_hfont = CreateFont(20, 0, 0, 0, FW_BOLD, TRUE, 0, 0, 0, 0, 0, 0, 0, TEXT("Sans Serif"));
new ColorStatic(hwnd, IDC_ROS_IBROWSER, RGB(32,32,128), 0, _hfont);
new HyperlinkCtrl(hwnd, IDC_WWW);
FmtString ver_txt(ResString(IDS_IBROWSER_VERSION_STR), (LPCTSTR)ResString(IDS_VERSION_STR));
SetWindowText(GetDlgItem(hwnd, IDC_VERSION_TXT), ver_txt);
/*@@
HWND hwnd_winver = GetDlgItem(hwnd, IDC_WIN_VERSION);
SetWindowText(hwnd_winver, get_windows_version_str());
SetWindowFont(hwnd_winver, GetStockFont(DEFAULT_GUI_FONT), FALSE);
*/
CenterWindow(hwnd);
}
~ExplorerAboutDlg()
{
DeleteObject(_hfont);
}
protected:
HFONT _hfont;
};
void ibrowser_about(HWND hwndParent)
{
Dialog::DoModal(IDD_ABOUT_IBROWSER, WINDOW_CREATOR(ExplorerAboutDlg), hwndParent);
}
static void InitInstance(HINSTANCE hInstance)
{
CONTEXT("InitInstance");
// register frame window class
g_hframeClass = IconWindowClass(CLASSNAME_FRAME,IDI_IBROWSER);
// register child window class
WindowClass(CLASSNAME_CHILDWND, CS_CLASSDC|CS_VREDRAW).Register();
}
int ibrowser_main(HINSTANCE hInstance, LPTSTR lpCmdLine, int cmdshow)
{
CONTEXT("ibrowser_main");
// initialize Common Controls library
CommonControlInit usingCmnCtrl;
try {
InitInstance(hInstance);
} catch(COMException& e) {
HandleException(e, GetDesktopWindow());
return -1;
}
if (cmdshow != SW_HIDE) {
/* // don't maximize if being called from the ROS desktop
if (cmdshow == SW_SHOWNORMAL)
///@todo read window placement from registry
cmdshow = SW_MAXIMIZE;
*/
ibrowser_show_frame(cmdshow, lpCmdLine);
}
return Window::MessageLoop();
}
// MinGW does not provide a Unicode startup routine, so we have to implement an own.
#if defined(__MINGW32__) && defined(UNICODE)
#define _tWinMain wWinMain
int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
int main(int argc, char* argv[])
{
CONTEXT("main");
STARTUPINFO startupinfo;
int nShowCmd = SW_SHOWNORMAL;
GetStartupInfo(&startupinfo);
if (startupinfo.dwFlags & STARTF_USESHOWWINDOW)
nShowCmd = startupinfo.wShowWindow;
LPWSTR cmdline = GetCommandLineW();
while(*cmdline && !_istspace(*cmdline))
++cmdline;
return wWinMain(GetModuleHandle(NULL), 0, cmdline, nShowCmd);
}
#endif // __MINGW && UNICODE
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
{
CONTEXT("WinMain()");
g_hInstance = hInstance;
// initialize COM and OLE before creating the desktop window
OleInit usingCOM;
// init common controls library
CommonControlInit usingCmnCtrl;
//@@ g_Globals.read_persistent();
/**TODO fix command line handling */
if (*lpCmdLine=='"' && lpCmdLine[_tcslen(lpCmdLine)-1]=='"') {
++lpCmdLine;
lpCmdLine[_tcslen(lpCmdLine)-1] = '\0';
}
int ret = ibrowser_main(hInstance, lpCmdLine, nShowCmd);
// write configuration file
//@@ g_Globals.write_persistent();
return ret;
}

View file

@ -0,0 +1,305 @@
# Microsoft Developer Studio Project File - Name="ibrowser" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=IBROWSER - WIN32 DEBUG
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ibrowser.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ibrowser.mak" CFG="IBROWSER - WIN32 DEBUG"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ibrowser - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "ibrowser - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "ibrowser - Win32 Debug Release" (based on "Win32 (x86) Console Application")
!MESSAGE "ibrowser - Win32 Unicode Release" (based on "Win32 (x86) Console Application")
!MESSAGE "ibrowser - Win32 Unicode Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "ibrowser - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O1 /D "NDEBUG" /D "WIN32" /D _WIN32_IE=0x0600 /D _WIN32_WINNT=0x0501 /Yu"precomp.h" /FD /c
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 gdi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /machine:I386 /libpath:"Release"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "ibrowser - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D _WIN32_IE=0x0600 /D _WIN32_WINNT=0x0501 /FR /Yu"precomp.h" /FD /GZ /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib gdi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /libpath:"Debug"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "ibrowser - Win32 Debug Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "DRelease"
# PROP BASE Intermediate_Dir "DRelease"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "DRelease"
# PROP Intermediate_Dir "DRelease"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_ROS_" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D _WIN32_IE=0x0600 /D _WIN32_WINNT=0x0501 /FR /Yu"precomp.h" /FD /c
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 gdi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "ibrowser - Win32 Unicode Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "URelease"
# PROP BASE Intermediate_Dir "URelease"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "URelease"
# PROP Intermediate_Dir "URelease"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /D "NDEBUG" /D "UNICODE" /D "WIN32" /D _WIN32_IE=0x0600 /D _WIN32_WINNT=0x0501 /Yu"precomp.h" /FD /c
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 gdi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /machine:I386 /libpath:"Release"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "ibrowser - Win32 Unicode Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "UDebug"
# PROP BASE Intermediate_Dir "UDebug"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "UDebug"
# PROP Intermediate_Dir "UDebug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /FR /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "UNICODE" /D "WIN32" /D _WIN32_IE=0x0600 /D _WIN32_WINNT=0x0501 /FR /Yu"precomp.h" /FD /GZ /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 gdi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /libpath:"Debug"
# SUBTRACT LINK32 /pdb:none
!ENDIF
# Begin Target
# Name "ibrowser - Win32 Release"
# Name "ibrowser - Win32 Debug"
# Name "ibrowser - Win32 Debug Release"
# Name "ibrowser - Win32 Unicode Release"
# Name "ibrowser - Win32 Unicode Debug"
# Begin Group "utility"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\utility\comutil.h
# End Source File
# Begin Source File
SOURCE=.\utility\expat.h
# End Source File
# Begin Source File
SOURCE=.\utility\utility.cpp
# End Source File
# Begin Source File
SOURCE=.\utility\utility.h
# End Source File
# Begin Source File
SOURCE=.\utility\window.cpp
# End Source File
# Begin Source File
SOURCE=.\utility\window.h
# End Source File
# Begin Source File
SOURCE=.\utility\xmlstorage.cpp
# End Source File
# Begin Source File
SOURCE=.\utility\xmlstorage.h
# End Source File
# End Group
# Begin Group "resources"
# PROP Default_Filter "bmp,ico"
# Begin Source File
SOURCE=.\res\dot.ico
# End Source File
# Begin Source File
SOURCE=.\res\dot_red.ico
# End Source File
# Begin Source File
SOURCE=.\res\dot_trans.ico
# End Source File
# Begin Source File
SOURCE=.\res\favorites.ico
# End Source File
# Begin Source File
SOURCE=.\res\ibrowser.ico
# End Source File
# Begin Source File
SOURCE=.\ibrowser_intres.h
# End Source File
# Begin Source File
SOURCE=.\ibrowser_intres.rc
# End Source File
# Begin Source File
SOURCE=.\res\iexplore.ico
# End Source File
# Begin Source File
SOURCE=.\res\network.ico
# End Source File
# Begin Source File
SOURCE=.\res\reactos.ico
# End Source File
# Begin Source File
SOURCE=.\res\toolbar.bmp
# End Source File
# End Group
# Begin Group "main"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\favorites.cpp
# End Source File
# Begin Source File
SOURCE=.\favorites.h
# End Source File
# Begin Source File
SOURCE=.\ibrowser.cpp
# End Source File
# Begin Source File
SOURCE=.\ibrowser.h
# End Source File
# Begin Source File
SOURCE=.\mainframe.cpp
# End Source File
# Begin Source File
SOURCE=.\mainframe.h
# End Source File
# Begin Source File
SOURCE=.\precomp.cpp
# ADD CPP /Yc"precomp.h"
# End Source File
# Begin Source File
SOURCE=.\precomp.h
# End Source File
# Begin Source File
SOURCE=.\webchild.cpp
# End Source File
# Begin Source File
SOURCE=.\webchild.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\readme.txt
# End Source File
# End Target
# End Project

View file

@ -0,0 +1,41 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "ibrowser"=.\ibrowser.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "make_ibrowser"=.\make_ibrowser.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View file

@ -0,0 +1,216 @@
/*
* Copyright 2005 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// ROS Internet Web Browser
//
// ibrowser.h
//
// Martin Fuchs, 25.01.2005
//
#include "utility/window.h"
#define IDW_STATUSBAR 0x100
#define IDW_TOOLBAR 0x101
#define IDW_EXTRABAR 0x102
#define IDW_ADDRESSBAR 0x104
#define IDW_SIDEBAR 0x106
#define IDW_FIRST_CHILD 0xC000 /*0x200*/
#define PM_GET_FILEWND_PTR (WM_APP+0x05)
#define PM_GET_SHELLBROWSER_PTR (WM_APP+0x06)
#define PM_GET_CONTROLWINDOW (WM_APP+0x16)
#define PM_RESIZE_CHILDREN (WM_APP+0x17)
#define PM_GET_WIDTH (WM_APP+0x18)
#define PM_REFRESH (WM_APP+0x1B)
#define PM_REFRESH_CONFIG (WM_APP+0x1C)
#define CLASSNAME_FRAME TEXT("IBrowserFrameWClass")
#define CLASSNAME_CHILDWND TEXT("IBrowserChildWClass")
#include "mainframe.h"
/// convenient loading of string resources
struct ResString : public String
{
ResString(UINT nid);
};
/// convenient loading of standard (32x32) icon resources
struct ResIcon
{
ResIcon(UINT nid);
operator HICON() const {return _hicon;}
protected:
HICON _hicon;
};
/// convenient loading of small (16x16) icon resources
struct SmallIcon
{
SmallIcon(UINT nid);
operator HICON() const {return _hicon;}
protected:
HICON _hicon;
};
/// convenient loading of icon resources with specified sizes
struct ResIconEx
{
ResIconEx(UINT nid, int w, int h);
operator HICON() const {return _hicon;}
protected:
HICON _hicon;
};
/// set big and small icons out of the resources for a window
extern void SetWindowIcon(HWND hwnd, UINT nid);
/// convenient loading of bitmap resources
struct ResBitmap
{
ResBitmap(UINT nid);
~ResBitmap() {DeleteObject(_hBmp);}
operator HBITMAP() const {return _hBmp;}
protected:
HBITMAP _hBmp;
};
enum ICON_TYPE {
IT_STATIC,
IT_CACHED,
IT_DYNAMIC,
IT_SYSCACHE
};
enum ICON_ID {
ICID_UNKNOWN,
ICID_NONE,
ICID_IBROWSER,
ICID_BOOKMARK,
ICID_DYNAMIC
};
struct Icon {
Icon();
Icon(ICON_ID id, UINT nid);
Icon(ICON_TYPE itype, int id, HICON hIcon);
Icon(ICON_TYPE itype, int id, int sys_idx);
operator ICON_ID() const {return _id;}
void draw(HDC hdc, int x, int y, int cx, int cy, COLORREF bk_color, HBRUSH bk_brush) const;
HBITMAP create_bitmap(COLORREF bk_color, HBRUSH hbrBkgnd, HDC hdc_wnd) const;
int add_to_imagelist(HIMAGELIST himl, HDC hdc_wnd, COLORREF bk_color=GetSysColor(COLOR_WINDOW), HBRUSH bk_brush=GetSysColorBrush(COLOR_WINDOW)) const;
int get_sysiml_idx() const {return _itype==IT_SYSCACHE? _sys_idx: -1;}
bool destroy() {if (_itype == IT_DYNAMIC) {DestroyIcon(_hicon); return true;} else return false;}
protected:
ICON_ID _id;
ICON_TYPE _itype;
HICON _hicon;
int _sys_idx;
};
struct SysCacheIcon : public Icon {
SysCacheIcon(int id, int sys_idx)
: Icon(IT_SYSCACHE, id, sys_idx) {}
};
struct IconCache {
IconCache() : _himlSys(0) {}
void init();
const Icon& extract(const String& path);
const Icon& extract(LPCTSTR path, int idx);
const Icon& extract(IExtractIcon* pExtract, LPCTSTR path, int idx);
const Icon& add(HICON hIcon, ICON_TYPE type=IT_DYNAMIC);
const Icon& add(int sys_idx/*, ICON_TYPE type=IT_SYSCACHE*/);
const Icon& get_icon(int icon_id);
HIMAGELIST get_sys_imagelist() const {return _himlSys;}
void free_icon(int icon_id);
protected:
static int s_next_id;
typedef map<int, Icon> IconMap;
IconMap _icons;
typedef map<String, ICON_ID> PathMap;
PathMap _pathMap;
typedef pair<String, int> CachePair;
typedef map<CachePair, ICON_ID> PathIdxMap;
PathIdxMap _pathIdxMap;
HIMAGELIST _himlSys;
};
/// create a bitmap from an icon
extern HBITMAP create_bitmap_from_icon(HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd);
/// add icon with alpha channel to imagelist using the specified background color
extern int ImageList_AddAlphaIcon(HIMAGELIST himl, HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd);
#include "utility/xmlstorage.h"
using namespace XMLStorage;
#include "favorites.h"
// globals
extern HINSTANCE g_hInstance;
extern IconCache g_icon_cache;
extern ATOM g_hframeClass;
// display explorer "About" dialog
extern void ibrowser_about(HWND hwndParent);

View file

@ -0,0 +1,24 @@
/* $Id: ibrowser.rc 12752 2005-01-03 11:25:40Z mf $ */
#include <defines.h>
#include "ibrowser_intres.rc"
#define REACTOS_STR_FILE_DESCRIPTION "ROS Internet Web Browser\0"
#define REACTOS_STR_INTERNAL_NAME "ibrowser\0"
#define REACTOS_STR_ORIGINAL_FILENAME "ibrowser.exe\0"
#include <reactos/version.rc>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#define IDS_VERSION_STR 5000
#define IDS_IBROWSER_VERSION_STR 5001
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
BEGIN
IDS_VERSION_STR REACTOS_STR_PRODUCT_VERSION
IDS_IBROWSER_VERSION_STR "ReactOS %s Web Browser"
END

View file

@ -0,0 +1,51 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by ibrowser_intres.rc
//
#define IDS_TITLE 1
#define IDS_EMPTY 13
#define IDS_ABOUT_IBROWSER 27
#define IDI_REACTOS 100
#define IDB_TOOLBAR 103
#define IDA_IBROWSER 104
#define IDM_SDIFRAME 113
#define IDD_ABOUT_IBROWSER 135
#define IDI_FAVORITES 140
#define IDI_DOT 163
#define IDI_DOT_TRANS 164
#define IDI_DOT_RED 165
#define IDI_IBROWSER 169
#define ID_VIEW_STATUSBAR 503
#define ID_VIEW_TOOL_BAR 508
#define ID_VIEW_SIDE_BAR 510
#define IDC_ROS_IBROWSER 1000
#define IDC_WWW 1012
#define IDC_VERSION_TXT 1029
#define IDC_WIN_VERSION 1030
#define ID_REFRESH 1704
#define IDS_VERSION_STR 5000
#define IDS_IBROWSER_VERSION_STR 5001
#define ID_IBROWSER_FAQ 10002
#define ID_VIEW_FULLSCREEN 0x8004
#define ID_ABOUT_WINDOWS 40002
#define ID_ABOUT_IBROWSER 40003
#define ID_GO_BACK 40005
#define ID_GO_FORWARD 40006
#define ID_GO_HOME 40007
#define ID_GO_SEARCH 40008
#define ID_GO_UP 40009
#define ID_STOP 40010
#define ID_FILE_EXIT 0xE141
#define ID_HELP 0xE146
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 170
#define _APS_NEXT_COMMAND_VALUE 40024
#define _APS_NEXT_CONTROL_VALUE 1033
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View file

@ -0,0 +1,398 @@
//Microsoft Developer Studio generated resource script.
//
#include "ibrowser_intres.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include <windows.h>
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Romanian resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ROM)
#ifdef _WIN32
LANGUAGE LANG_ROMANIAN, SUBLANG_DEFAULT
#pragma code_page(1250)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDM_SDIFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&Fiºier"
BEGIN
MENUITEM "&Ieºire", ID_FILE_EXIT
END
POPUP "&Prezentare"
BEGIN
MENUITEM "&Bara cu instrumente", ID_VIEW_TOOL_BAR
MENUITEM "&Side Bar", ID_VIEW_SIDE_BAR, GRAYED
MENUITEM "&Bara de stare", ID_VIEW_STATUSBAR
MENUITEM SEPARATOR
MENUITEM "&Resetare\tF5", ID_REFRESH
MENUITEM "F&ull Screen\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
END
POPUP "&Ajutor"
BEGIN
MENUITEM "Explorer &FAQ...", ID_IBROWSER_FAQ
MENUITEM "&Despre Explorer...", ID_ABOUT_IBROWSER
MENUITEM "Despre &OS...", ID_ABOUT_WINDOWS
END
END
#endif // Romanian resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Neutral resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
#ifdef _WIN32
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_TOOLBAR BITMAP DISCARDABLE "res/toolbar.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDA_IBROWSER ACCELERATORS DISCARDABLE
BEGIN
"X", ID_FILE_EXIT, VIRTKEY, ALT, NOINVERT
"S", ID_VIEW_FULLSCREEN, VIRTKEY, SHIFT, CONTROL,
NOINVERT
END
#endif // Neutral resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// German (Germany) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
#ifdef _WIN32
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDM_SDIFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&Datei"
BEGIN
MENUITEM "&Beenden", ID_FILE_EXIT
END
POPUP "&Ansicht"
BEGIN
MENUITEM "&Toolbar", ID_VIEW_TOOL_BAR
MENUITEM "S&ide Bar", ID_VIEW_SIDE_BAR, GRAYED
MENUITEM "&Status Bar", ID_VIEW_STATUSBAR
MENUITEM SEPARATOR
MENUITEM "&Aktualisieren\tF5", ID_REFRESH
MENUITEM "&Vollbild\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
END
POPUP "&Hilfe"
BEGIN
MENUITEM "Explorer &FAQ...", ID_IBROWSER_FAQ
MENUITEM "&About Explorer...", ID_ABOUT_IBROWSER
MENUITEM "About &OS...", ID_ABOUT_WINDOWS
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUT_IBROWSER DIALOG DISCARDABLE 0, 0, 199, 106
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About ReactOS Web Browser"
FONT 10, "MS Sans Serif"
BEGIN
LTEXT "ReactOS Web Browser",IDC_ROS_IBROWSER,91,13,104,11
LTEXT "V 0.9",IDC_VERSION_TXT,91,27,104,8
LTEXT "(c) 2005 Martin Fuchs",IDC_STATIC,91,42,104,8
LTEXT "",IDC_WIN_VERSION,91,58,98,22
LTEXT "http://www.sky.franken.de/explorer/",IDC_WWW,17,84,129,
8
CONTROL "&OK",IDOK,"Button",BS_OWNERDRAW | BS_FLAT | WS_GROUP,
154,90,38,12
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_ABOUT_IBROWSER, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 192
TOPMARGIN, 7
BOTTOMMARGIN, 102
END
END
#endif // APSTUDIO_INVOKED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"ibrowser_intres.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include <windows.h>\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"#ifndef _ROS_\r\n"
"LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL\r\n"
"STRINGTABLE DISCARDABLE \r\n"
"BEGIN\r\n"
"IDS_VERSION_STR """"\r\n"
"#ifdef UNICODE\r\n"
"IDS_IBROWSER_VERSION_STR ""ROS Explorer%0s""\r\n"
"#else\r\n"
"IDS_IBROWSER_VERSION_STR ""ROS Explorer Ansi%0s""\r\n"
"#endif\r\n"
"END\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_REACTOS ICON DISCARDABLE "res/reactos.ico"
IDI_FAVORITES ICON DISCARDABLE "res/favorites.ico"
IDI_DOT ICON DISCARDABLE "res/dot.ico"
IDI_DOT_TRANS ICON DISCARDABLE "res/dot_trans.ico"
IDI_DOT_RED ICON DISCARDABLE "res/dot_red.ico"
IDI_IBROWSER ICON DISCARDABLE "res\\ibrowser.ico"
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_TITLE "Reactos Internet Web Browser"
IDS_EMPTY "(Empty)"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_ABOUT_IBROWSER "&Über..."
END
#endif // German (Germany) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDM_SDIFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", ID_FILE_EXIT
END
POPUP "&View"
BEGIN
MENUITEM "&Toolbar", ID_VIEW_TOOL_BAR
MENUITEM "S&ide Bar", ID_VIEW_SIDE_BAR, GRAYED
MENUITEM "&Status Bar", ID_VIEW_STATUSBAR
MENUITEM SEPARATOR
MENUITEM "&Refresh\tF5", ID_REFRESH
MENUITEM "F&ull Screen\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
END
POPUP "&Help"
BEGIN
MENUITEM "Explorer &FAQ...", ID_IBROWSER_FAQ
MENUITEM "&About Explorer...", ID_ABOUT_IBROWSER
MENUITEM "About &OS...", ID_ABOUT_WINDOWS
END
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_TITLE "Reactos Internet Web Browser"
IDS_EMPTY "(Empty)"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_ABOUT_IBROWSER "&About..."
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Spanish (Castilian) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESP)
#ifdef _WIN32
LANGUAGE LANG_SPANISH, SUBLANG_SPANISH
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDM_SDIFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&Archivo"
BEGIN
MENUITEM "S&alir", ID_FILE_EXIT
END
POPUP "&Ver"
BEGIN
MENUITEM "&Barra de Herramientas", ID_VIEW_TOOL_BAR
MENUITEM "Barra &Lateral", ID_VIEW_SIDE_BAR, GRAYED
MENUITEM "Barra de &Estado", ID_VIEW_STATUSBAR
MENUITEM SEPARATOR
MENUITEM "&Actualizar\tF5", ID_REFRESH
MENUITEM "P&antalla Completa\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
END
POPUP "&Ayuda"
BEGIN
MENUITEM "Explorer &FAQ...", ID_IBROWSER_FAQ
MENUITEM "&Acerca de Explorer...", ID_ABOUT_IBROWSER
MENUITEM "Acerca de &OS...", ID_ABOUT_WINDOWS
END
END
#endif // Spanish (Castilian) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// French (France) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
#ifdef _WIN32
LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDM_SDIFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&Fichier"
BEGIN
MENUITEM "&Fermer", ID_FILE_EXIT
END
POPUP "&Affichage"
BEGIN
MENUITEM "Barre d'&outils", ID_VIEW_TOOL_BAR
MENUITEM "&Side Bar", ID_VIEW_SIDE_BAR, GRAYED
MENUITEM "Barre d'&état", ID_VIEW_STATUSBAR
MENUITEM SEPARATOR
MENUITEM "&Refresh\tF5", ID_REFRESH
MENUITEM "F&ull Screen\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
END
POPUP "A&ide"
BEGIN
MENUITEM "&FAQ Explorateur...", ID_IBROWSER_FAQ
MENUITEM "A propos de l'&explorateur...", ID_ABOUT_WINDOWS
MENUITEM "A propos de l'&OS...", ID_ABOUT_IBROWSER
END
END
#endif // French (France) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#ifndef _ROS_
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
BEGIN
IDS_VERSION_STR ""
#ifdef UNICODE
IDS_IBROWSER_VERSION_STR "ROS Explorer%0s"
#else
IDS_IBROWSER_VERSION_STR "ROS Explorer Ansi%0s"
#endif
END
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View file

@ -0,0 +1,796 @@
/*
* Copyright 2005 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// ROS Internet Web Browser
//
// mainframe.cpp
//
// Martin Fuchs, 25.01.2005
//
#include "precomp.h"
/* We can't include webchild.h here - otherwise MinGW produces errors like: "multiple definition of `QACONTAINERFLAGS'"
#include "webchild.h"
*/
extern HWND create_webchildwindow(const WebChildWndInfo& info);
#include "ibrowser_intres.h"
HWND MainFrameBase::Create(LPCTSTR url, UINT cmdshow)
{
HWND hMainFrame;
hMainFrame = MainFrame::Create();
//@@hMainFrame = MainFrame::Create(url);
if (hMainFrame) {
String sPath;
if (url) {
sPath = url; // copy url to avoid accessing freed memory
url = sPath;
}
ShowWindow(hMainFrame, cmdshow);
UpdateWindow(hMainFrame);
// Open the first child window after initializing the application
PostMessage(hMainFrame, PM_OPEN_WINDOW, 0, (LPARAM)url);
}
return hMainFrame;
}
MainFrameBase::MainFrameBase(HWND hwnd)
: super(hwnd),
_himl(ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0))
{
_hMenuFrame = GetMenu(hwnd);
_hMenuWindow = GetSubMenu(_hMenuFrame, GetMenuItemCount(_hMenuFrame)-3);
_menu_info._hMenuView = GetSubMenu(_hMenuFrame, 1);
_hAccel = LoadAccelerators(g_hInstance, MAKEINTRESOURCE(IDA_IBROWSER));
TBBUTTON toolbarBtns[] = {
#ifdef _NO_REBAR
{0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
#endif
{7, ID_GO_BACK, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{8, ID_GO_FORWARD, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{9, ID_GO_UP, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{10, ID_GO_HOME, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{11, ID_GO_SEARCH, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{12, ID_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{13, ID_STOP, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0}
};
_htoolbar = CreateToolbarEx(hwnd,
#ifndef _NO_REBAR
CCS_NOPARENTALIGN|CCS_NORESIZE|
#endif
WS_CHILD|WS_VISIBLE, IDW_TOOLBAR, 2, g_hInstance, IDB_TOOLBAR,
toolbarBtns, sizeof(toolbarBtns)/sizeof(TBBUTTON),
16, 15, 16, 15, sizeof(TBBUTTON));
CheckMenuItem(_menu_info._hMenuView, ID_VIEW_TOOL_BAR, MF_BYCOMMAND|MF_CHECKED);
// address bar
WindowCanvas canvas(hwnd);
RECT rect = {0, 0, 0, 0};
DrawText(canvas, TEXT("My"), -1, &rect, DT_SINGLELINE|DT_NOPREFIX|DT_CALCRECT);
HFONT hfont = GetStockFont(DEFAULT_GUI_FONT);
_haddressedit = CreateWindow(TEXT("EDIT"), NULL, WS_CHILD|WS_VISIBLE, 0, 0, 0, rect.bottom,
hwnd, (HMENU)IDW_ADDRESSBAR, g_hInstance, 0);
SetWindowFont(_haddressedit, hfont, FALSE);
new EditController(_haddressedit);
/* CreateStatusWindow does not accept WS_BORDER
_hstatusbar = CreateWindowEx(WS_EX_NOPARENTNOTIFY, STATUSCLASSNAME, 0,
WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_BORDER|CCS_NODIVIDER, 0,0,0,0,
hwnd, (HMENU)IDW_STATUSBAR, g_hInstance, 0);*/
_hstatusbar = CreateStatusWindow(WS_CHILD|WS_VISIBLE, 0, hwnd, IDW_STATUSBAR);
CheckMenuItem(_menu_info._hMenuView, ID_VIEW_STATUSBAR, MF_BYCOMMAND|MF_CHECKED);
_hsidebar = CreateWindowEx(WS_EX_STATICEDGE, WC_TREEVIEW, TEXT("Sidebar"),
WS_CHILD|WS_TABSTOP|WS_BORDER|/*WS_VISIBLE|*/WS_CHILD|TVS_HASLINES|TVS_HASBUTTONS|TVS_SHOWSELALWAYS|TVS_INFOTIP,
-1, -1, 200, 0, _hwnd, (HMENU)IDW_SIDEBAR, g_hInstance, 0);
TreeView_SetImageList(_hsidebar, _himl, TVSIL_NORMAL);
CheckMenuItem(_menu_info._hMenuView, ID_VIEW_SIDE_BAR, MF_BYCOMMAND|MF_UNCHECKED/*MF_CHECKED*/);
// create rebar window to manage toolbar and drivebar
#ifndef _NO_REBAR
_hwndrebar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL,
WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|
RBS_VARHEIGHT|RBS_AUTOSIZE|RBS_DBLCLKTOGGLE|
CCS_NODIVIDER|CCS_NOPARENTALIGN,
0, 0, 0, 0, _hwnd, 0, g_hInstance, 0);
int btn_hgt = HIWORD(SendMessage(_htoolbar, TB_GETBUTTONSIZE, 0, 0));
REBARBANDINFO rbBand;
rbBand.cbSize = sizeof(REBARBANDINFO);
rbBand.fMask = RBBIM_TEXT|RBBIM_STYLE|RBBIM_CHILD|RBBIM_CHILDSIZE|RBBIM_SIZE;
#ifndef RBBS_HIDETITLE // missing in MinGW headers as of 25.02.2004
#define RBBS_HIDETITLE 0x400
#endif
rbBand.fStyle = RBBS_CHILDEDGE|RBBS_GRIPPERALWAYS|RBBS_HIDETITLE;
rbBand.cxMinChild = 0;
rbBand.cyMinChild = 0;
rbBand.cyChild = 0;
rbBand.cyMaxChild = 0;
rbBand.cyIntegral = btn_hgt;
rbBand.lpText = NULL;//TEXT("Toolbar");
rbBand.hwndChild = _htoolbar;
rbBand.cxMinChild = 0;
rbBand.cyMinChild = btn_hgt + 4;
rbBand.cx = 284;
SendMessage(_hwndrebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
#endif
}
MainFrameBase::~MainFrameBase()
{
ImageList_Destroy(_himl);
//@@if (g_Globals._hMainWnd == _hwnd)
PostQuitMessage(0);
}
LRESULT MainFrameBase::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{
LRESULT res;
if (ProcessMessage(nmsg, wparam, lparam, &res))
return res;
else
return super::WndProc(nmsg, wparam, lparam);
}
bool MainFrameBase::ProcessMessage(UINT nmsg, WPARAM wparam, LPARAM lparam, LRESULT* pres)
{
switch(nmsg) {
case PM_TRANSLATE_MSG:
*pres = TranslateMsg((MSG*)lparam);
return true;
case WM_SHOWWINDOW:
if (wparam) // trigger child resizing after window creation - now we can succesfully call IsWindowVisible()
resize_frame_client();
return false; // goto def;
case WM_CLOSE:
DestroyWindow(_hwnd);
//@@ g_Globals._hMainWnd = 0;
break;
case WM_DESTROY:
break;
case WM_SIZE:
resize_frame(LOWORD(lparam), HIWORD(lparam));
break; // do not pass message to DefFrameProc
case WM_GETMINMAXINFO: {
LPMINMAXINFO lpmmi = (LPMINMAXINFO)lparam;
lpmmi->ptMaxTrackSize.x <<= 1;/*2*GetSystemMetrics(SM_CXSCREEN) / SM_CXVIRTUALSCREEN */
lpmmi->ptMaxTrackSize.y <<= 1;/*2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN */
break;}
case PM_FRM_CALC_CLIENT:
frame_get_clientspace((PRECT)lparam);
*pres = TRUE;
return true;
case PM_FRM_GET_MENUINFO:
*pres = (LPARAM)&_menu_info;
return true;
case PM_GET_CONTROLWINDOW:
if (wparam == FCW_STATUS) {
*pres = (LRESULT)(HWND)_hstatusbar;
return true;
}
break;
case PM_SETSTATUSTEXT:
SendMessage(_hstatusbar, SB_SETTEXT, 0, lparam);
break;
case PM_URL_CHANGED:
SetWindowText(_haddressedit, (LPCTSTR)lparam);
break;
default:
return false;
}
*pres = 0;
return true;
}
BOOL MainFrameBase::TranslateMsg(MSG* pmsg)
{
if (TranslateAccelerator(_hwnd, _hAccel, pmsg))
return TRUE;
return FALSE;
}
int MainFrameBase::Command(int id, int code)
{
CONTEXT("MainFrameBase::Command()");
switch(id) {
case ID_FILE_EXIT:
SendMessage(_hwnd, WM_CLOSE, 0, 0);
break;
case ID_VIEW_TOOL_BAR:
toggle_child(_hwnd, id, _htoolbar, 0);
break;
case ID_VIEW_STATUSBAR:
toggle_child(_hwnd, id, _hstatusbar);
break;
case ID_VIEW_SIDE_BAR:
// lazy initialization
if (!TreeView_GetCount(_hsidebar))
FillBookmarks();
toggle_child(_hwnd, id, _hsidebar);
break;
case ID_HELP:
WinHelp(_hwnd, TEXT("ibrowser")/*file ibrowser.hlp*/, HELP_INDEX, 0);
break;
case ID_VIEW_FULLSCREEN:
CheckMenuItem(_menu_info._hMenuView, id, toggle_fullscreen()?MF_CHECKED:0);
break;
case ID_ABOUT_WINDOWS:
ShellAbout(_hwnd, ResString(IDS_TITLE), NULL, 0);
break;
case ID_ABOUT_IBROWSER:
ibrowser_about(_hwnd);
break;
case ID_IBROWSER_FAQ:
launch_file(_hwnd, TEXT("http://www.sky.franken.de/explorer/"), SW_SHOW);
break;
case IDW_ADDRESSBAR:
if (code == 1) {
TCHAR url[BUFFER_LEN];
if (GetWindowText(_haddressedit, url, BUFFER_LEN))
go_to(url, false);
}
break;
default:
return 1; // no command handlers in Window::Command()
}
return 0;
}
int MainFrameBase::Notify(int id, NMHDR* pnmh)
{
switch(pnmh->code) {
// resize children windows when the rebar size changes
case RBN_AUTOSIZE:
resize_frame_client();
break;
case TVN_GETINFOTIP: {
NMTVGETINFOTIP* pnmgit = (NMTVGETINFOTIP*)pnmh;
if (pnmgit->lParam) {
const BookmarkNode& node = *(BookmarkNode*)pnmgit->lParam;
if (node._type == BookmarkNode::BMNT_FOLDER) {
// display tooltips for bookmark folders
if (!node._pfolder->_description.empty())
lstrcpyn(pnmgit->pszText, node._pfolder->_description.c_str(), pnmgit->cchTextMax);
} else if (node._type == BookmarkNode::BMNT_BOOKMARK) {
// display tooltips for bookmark folders
String txt = node._pbookmark->_description;
if (!node._pbookmark->_url.empty()) {
if (!txt.empty())
txt += TEXT(" - ");
txt += node._pbookmark->_url;
}
lstrcpyn(pnmgit->pszText, txt.c_str(), pnmgit->cchTextMax);
}
}
break;}
case NM_DBLCLK: {
HTREEITEM hitem = TreeView_GetSelection(_hsidebar);
LPARAM lparam = TreeView_GetItemData(_hsidebar, hitem);
if (lparam) {
const BookmarkNode& node = *(BookmarkNode*)lparam;
if (node._type == BookmarkNode::BMNT_BOOKMARK) {
bool new_window = GetAsyncKeyState(VK_SHIFT)<0;
go_to(node._pbookmark->_url, new_window);
}
}
break;}
}
return 0;
}
void MainFrameBase::resize_frame(int cx, int cy)
{
if (cy <= 0)
return; // avoid resizing children when receiving RBN_AUTOSIZE while getting minimized
RECT rect = {0, 0, cx, cy};
if (_hwndrebar) {
int height = ClientRect(_hwndrebar).bottom;
MoveWindow(_hwndrebar, rect.left, rect.top, rect.right-rect.left, height, TRUE);
rect.top += height;
} else {
if (IsWindowVisible(_htoolbar)) {
SendMessage(_htoolbar, WM_SIZE, 0, 0);
WindowRect rt(_htoolbar);
rect.top = rt.bottom;
// rect.bottom -= rt.bottom;
}
}
if (IsWindowVisible(_hstatusbar)) {
int parts[] = {300, 500};
SendMessage(_hstatusbar, WM_SIZE, 0, 0);
SendMessage(_hstatusbar, SB_SETPARTS, 2, (LPARAM)&parts);
ClientRect rt(_hstatusbar);
rect.bottom -= rt.bottom;
}
if (IsWindowVisible(_haddressedit)) {
ClientRect rt(_haddressedit);
rect.bottom -= rt.bottom;
SetWindowPos(_haddressedit, 0, 0, rect.bottom, rect.right-rect.left, rt.bottom, SWP_NOACTIVATE|SWP_NOZORDER);
}
if (IsWindowVisible(_hsidebar)) {
WindowRect rt(_hsidebar);
rect.left += rt.right-rt.left;
SetWindowPos(_hsidebar, 0, -1, rect.top-1, rt.right-rt.left, rect.bottom-rect.top+1, SWP_NOACTIVATE|SWP_NOZORDER);
}
}
void MainFrameBase::resize_frame_client()
{
ClientRect rect(_hwnd);
resize_frame(rect.right, rect.bottom);
}
void MainFrameBase::frame_get_clientspace(PRECT prect)
{
if (!IsIconic(_hwnd))
GetClientRect(_hwnd, prect);
else {
WINDOWPLACEMENT wp;
GetWindowPlacement(_hwnd, &wp);
prect->left = prect->top = 0;
prect->right = wp.rcNormalPosition.right-wp.rcNormalPosition.left-
2*(GetSystemMetrics(SM_CXSIZEFRAME)+GetSystemMetrics(SM_CXEDGE));
prect->bottom = wp.rcNormalPosition.bottom-wp.rcNormalPosition.top-
2*(GetSystemMetrics(SM_CYSIZEFRAME)+GetSystemMetrics(SM_CYEDGE))-
GetSystemMetrics(SM_CYCAPTION)-GetSystemMetrics(SM_CYMENUSIZE);
}
if (IsWindowVisible(_htoolbar)) {
ClientRect rt(_htoolbar);
prect->top += rt.bottom+2;
}
if (IsWindowVisible(_hstatusbar)) {
ClientRect rt(_hstatusbar);
prect->bottom -= rt.bottom;
}
}
BOOL MainFrameBase::toggle_fullscreen()
{
RECT rt;
if ((_fullscreen._mode=!_fullscreen._mode)) {
GetWindowRect(_hwnd, &_fullscreen._orgPos);
_fullscreen._wasZoomed = IsZoomed(_hwnd);
Frame_CalcFrameClient(_hwnd, &rt);
ClientToScreen(_hwnd, (LPPOINT)&rt.left);
ClientToScreen(_hwnd, (LPPOINT)&rt.right);
rt.left = _fullscreen._orgPos.left-rt.left;
rt.top = _fullscreen._orgPos.top-rt.top;
rt.right = GetSystemMetrics(SM_CXSCREEN)+_fullscreen._orgPos.right-rt.right;
rt.bottom = GetSystemMetrics(SM_CYSCREEN)+_fullscreen._orgPos.bottom-rt.bottom;
MoveWindow(_hwnd, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, TRUE);
} else {
MoveWindow(_hwnd, _fullscreen._orgPos.left, _fullscreen._orgPos.top,
_fullscreen._orgPos.right-_fullscreen._orgPos.left,
_fullscreen._orgPos.bottom-_fullscreen._orgPos.top, TRUE);
if (_fullscreen._wasZoomed)
ShowWindow(_hwnd, WS_MAXIMIZE);
}
return _fullscreen._mode;
}
void MainFrameBase::fullscreen_move()
{
RECT rt, pos;
GetWindowRect(_hwnd, &pos);
Frame_CalcFrameClient(_hwnd, &rt);
ClientToScreen(_hwnd, (LPPOINT)&rt.left);
ClientToScreen(_hwnd, (LPPOINT)&rt.right);
rt.left = pos.left-rt.left;
rt.top = pos.top-rt.top;
rt.right = GetSystemMetrics(SM_CXSCREEN)+pos.right-rt.right;
rt.bottom = GetSystemMetrics(SM_CYSCREEN)+pos.bottom-rt.bottom;
MoveWindow(_hwnd, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, TRUE);
}
void MainFrameBase::toggle_child(HWND hwnd, UINT cmd, HWND hchild, int band_idx)
{
BOOL vis = IsWindowVisible(hchild);
CheckMenuItem(_menu_info._hMenuView, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
if (band_idx != -1)
SendMessage(_hwndrebar, RB_SHOWBAND, band_idx, !vis);
else
ShowWindow(hchild, vis? SW_HIDE: SW_SHOW);
if (_fullscreen._mode)
fullscreen_move();
resize_frame_client();
}
void MainFrameBase::FillBookmarks()
{
/*@@
HiddenWindow hide(_hsidebar);
WindowCanvas canvas(_hwnd);
TreeView_DeleteAllItems(_hsidebar);
g_icon_cache.get_icon(ICID_FAVORITES).add_to_imagelist(_himl, canvas);
g_icon_cache.get_icon(ICID_BOOKMARK).add_to_imagelist(_himl, canvas);
ImageList_AddAlphaIcon(_himl, SmallIcon(IDI_DOT), GetStockBrush(WHITE_BRUSH), canvas);
g_icon_cache.get_icon(ICID_FOLDER).add_to_imagelist(_himl, canvas);
g_icon_cache.get_icon(ICID_FOLDER).add_to_imagelist(_himl, canvas);
TV_INSERTSTRUCT tvi;
tvi.hParent = TVI_ROOT;
tvi.hInsertAfter = TVI_LAST;
tvi.item.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
ResString sFavorites(IDS_FAVORITES);
tvi.item.pszText = (LPTSTR)sFavorites.c_str();
tvi.item.iSelectedImage = tvi.item.iImage = 0;
HTREEITEM hitem_bookmarks = TreeView_InsertItem(_hsidebar, &tvi);
g_Globals._favorites.fill_tree(_hsidebar, hitem_bookmarks, _himl, canvas);
TreeView_Expand(_hsidebar, hitem_bookmarks, TVE_EXPAND);
*/
}
MainFrame::MainFrame(HWND hwnd)
: super(hwnd)
{
_split_pos = DEFAULT_SPLIT_POS;
_last_split = DEFAULT_SPLIT_POS;
}
HWND MainFrame::Create()
{
HMENU hMenuFrame = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_SDIFRAME));
return Window::Create(WINDOW_CREATOR(MainFrame), 0,
(LPCTSTR)(int)g_hframeClass, ResString(IDS_TITLE), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
0/*hwndDesktop*/, hMenuFrame);
}
/*@@
HWND MainFrame::Create(LPCTSTR url)
{
HWND hFrame = Create();
if (!hFrame)
return 0;
ShowWindow(hFrame, SW_SHOW);
MainFrame* pFrame = GET_WINDOW(MainFrame, hFrame);
if (pFrame)
pFrame->set_url(url);
return hFrame;
}
*/
LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{
switch(nmsg) {
case WM_SIZE:
resize_frame(LOWORD(lparam), HIWORD(lparam));
break;
case WM_PAINT: {
PaintCanvas canvas(_hwnd);
if (_left_hwnd && _right_hwnd) {
ClientRect rt(_hwnd);
rt.left = _split_pos-SPLIT_WIDTH/2;
rt.right = _split_pos+SPLIT_WIDTH/2+1;
if (_right_hwnd) {
WindowRect right_rect(_right_hwnd);
ScreenToClient(_hwnd, &right_rect);
rt.top = right_rect.top;
rt.bottom = right_rect.bottom;
}
HBRUSH lastBrush = SelectBrush(canvas, GetStockBrush(COLOR_SPLITBAR));
Rectangle(canvas, rt.left, rt.top-1, rt.right, rt.bottom+1);
SelectObject(canvas, lastBrush);
}
break;}
case WM_SETCURSOR:
if (LOWORD(lparam) == HTCLIENT) {
POINT pt;
GetCursorPos(&pt);
ScreenToClient(_hwnd, &pt);
if (pt.x>=_split_pos-SPLIT_WIDTH/2 && pt.x<_split_pos+SPLIT_WIDTH/2+1) {
SetCursor(LoadCursor(0, IDC_SIZEWE));
return TRUE;
}
}
goto def;
case WM_LBUTTONDOWN: {
int x = GET_X_LPARAM(lparam);
ClientRect rt(_hwnd);
if (x>=_split_pos-SPLIT_WIDTH/2 && x<_split_pos+SPLIT_WIDTH/2+1) {
_last_split = _split_pos;
SetCapture(_hwnd);
}
break;}
case WM_LBUTTONUP:
if (GetCapture() == _hwnd)
ReleaseCapture();
break;
case WM_KEYDOWN:
if (wparam == VK_ESCAPE)
if (GetCapture() == _hwnd) {
_split_pos = _last_split;
resize_children();
_last_split = -1;
ReleaseCapture();
SetCursor(LoadCursor(0, IDC_ARROW));
}
break;
case WM_MOUSEMOVE:
if (GetCapture() == _hwnd) {
int x = LOWORD(lparam);
ClientRect rt(_hwnd);
if (x>=0 && x<rt.right) {
_split_pos = x;
resize_children();
rt.left = x-SPLIT_WIDTH/2;
rt.right = x+SPLIT_WIDTH/2+1;
InvalidateRect(_hwnd, &rt, FALSE);
UpdateWindow(_left_hwnd);
UpdateWindow(_hwnd);
UpdateWindow(_right_hwnd);
}
}
break;
case PM_OPEN_WINDOW: {CONTEXT("MainFrame PM_OPEN_WINDOW");
LPCTSTR url = (LPCTSTR)lparam;
if (!url || !*url)
#ifdef _DEBUG
url = _T("http://localhost");
#else
url = _T("about:blank");
#endif
if (!_right_hwnd) {
_right_hwnd = create_webchildwindow(WebChildWndInfo(_hwnd, url));
resize_children();
} else
set_url(url);
return TRUE;} // success
default: def:
return super::WndProc(nmsg, wparam, lparam);
}
return 0;
}
int MainFrame::Command(int id, int code)
{
if (_right_hwnd)
if (SendMessage(_right_hwnd, PM_DISPATCH_COMMAND, MAKELONG(id,code), 0))
return 0;
return super::Command(id, code);
}
void MainFrame::resize_frame(int cx, int cy)
{
if (cy <= 0)
return; // avoid resizing children when receiving RBN_AUTOSIZE while getting minimized
RECT rect = {0, 0, cx, cy};
if (_hwndrebar) {
int height = ClientRect(_hwndrebar).bottom;
MoveWindow(_hwndrebar, rect.left, rect.top, rect.right-rect.left, height, TRUE);
rect.top += height;
} else {
if (IsWindowVisible(_htoolbar)) {
SendMessage(_htoolbar, WM_SIZE, 0, 0);
WindowRect rt(_htoolbar);
rect.top = rt.bottom;
// rect.bottom -= rt.bottom;
}
}
if (IsWindowVisible(_hstatusbar)) {
int parts[] = {300, 500};
SendMessage(_hstatusbar, WM_SIZE, 0, 0);
SendMessage(_hstatusbar, SB_SETPARTS, 2, (LPARAM)&parts);
ClientRect rt(_hstatusbar);
rect.bottom -= rt.bottom;
}
if (IsWindowVisible(_haddressedit)) {
ClientRect rt(_haddressedit);
rect.bottom -= rt.bottom;
SetWindowPos(_haddressedit, 0, 0, rect.bottom, rect.right-rect.left, rt.bottom, SWP_NOACTIVATE|SWP_NOZORDER);
}
if (IsWindowVisible(_hsidebar)) {
WindowRect rt(_hsidebar);
rect.left += rt.right-rt.left;
SetWindowPos(_hsidebar, 0, -1, rect.top-1, rt.right-rt.left, rect.bottom-rect.top+1, SWP_NOACTIVATE|SWP_NOZORDER);
}
_clnt_rect = rect;
resize_children();
}
void MainFrame::resize_children()
{
HDWP hdwp = BeginDeferWindowPos(2);
int cx = _clnt_rect.left;
if (_left_hwnd) {
cx = _split_pos + SPLIT_WIDTH/2;
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);
} else {
//_split_pos = 0;
cx = 0;
}
if (_right_hwnd)
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);
EndDeferWindowPos(hdwp);
}
void MainFrame::update_clnt_rect()
{
ClientRect rect(_hwnd);
resize_frame(rect.right, rect.bottom);
}
void MainFrame::set_url(LPCTSTR url)
{
if (_url != url) {
_url = url;
SetWindowText(_haddressedit, url); //SendMessage(_hwndFrame, PM_URL_CHANGED, 0, (LPARAM)url);
}
}
bool MainFrame::go_to(LPCTSTR url, bool new_window)
{
if (_right_hwnd) {
SendMessage(_right_hwnd, PM_JUMP_TO_URL, 0, (LPARAM)url);
return true;
}
return false;
}

View file

@ -0,0 +1,125 @@
/*
* Copyright 2005 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// ROS Internet Web Browser
//
// mainframe.h
//
// Martin Fuchs, 25.01.2005
//
#define PM_OPEN_WINDOW (WM_APP+0x07)
/// Explorer frame window base class
struct MainFrameBase : public PreTranslateWindow
{
typedef PreTranslateWindow super;
MainFrameBase(HWND hwnd);
~MainFrameBase();
static HWND Create(LPCTSTR url, UINT cmdshow=SW_SHOWNORMAL);
WindowHandle _hwndrebar;
WindowHandle _htoolbar;
WindowHandle _hstatusbar;
WindowHandle _haddressedit;
WindowHandle _hsidebar;
HIMAGELIST _himl;
HMENU _hMenuFrame;
HMENU _hMenuWindow;
MenuInfo _menu_info;
protected:
FullScreenParameters _fullscreen;
HACCEL _hAccel;
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
bool ProcessMessage(UINT nmsg, WPARAM wparam, LPARAM lparam, LRESULT* pres);
int Command(int id, int code);
int Notify(int id, NMHDR* pnmh);
virtual BOOL TranslateMsg(MSG* pmsg);
void toggle_child(HWND hwnd, UINT cmd, HWND hchild, int band_idx=-1);
void resize_frame_client();
virtual void resize_frame(int cx, int cy);
virtual void frame_get_clientspace(PRECT prect);
BOOL toggle_fullscreen();
void fullscreen_move();
void FillBookmarks();
virtual bool go_to(LPCTSTR url, bool new_window) {return false;}
};
struct MainFrame : public MainFrameBase
{
typedef MainFrameBase super;
MainFrame(HWND hwnd);
static HWND Create();
//@@static HWND Create(LPCTSTR url);
protected:
WindowHandle _left_hwnd;
WindowHandle _right_hwnd;
int _split_pos;
int _last_split;
RECT _clnt_rect;
String _url;
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
int Command(int id, int code);
void resize_frame(int cx, int cy);
void resize_children();
void update_clnt_rect();
void set_url(LPCTSTR url);
virtual bool go_to(LPCTSTR url, bool new_window);
};
struct WebChildWndInfo : public ChildWndInfo
{
WebChildWndInfo(HWND hwndFrame, LPCTSTR url)
: ChildWndInfo(hwndFrame),
_url(url)
{
}
String _url;
};

View file

@ -0,0 +1,176 @@
# Microsoft Developer Studio Project File - Name="make_ibrowser" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) External Target" 0x0106
CFG=make_ibrowser - Win32 bjam
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "make_ibrowser.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "make_ibrowser.mak" CFG="make_ibrowser - Win32 bjam"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "make_ibrowser - Win32 Release" (based on "Win32 (x86) External Target")
!MESSAGE "make_ibrowser - Win32 Debug" (based on "Win32 (x86) External Target")
!MESSAGE "make_ibrowser - Win32 Unicode Debug" (based on "Win32 (x86) External Target")
!MESSAGE "make_ibrowser - Win32 Unicode Release" (based on "Win32 (x86) External Target")
!MESSAGE "make_ibrowser - Win32 bjam" (based on "Win32 (x86) External Target")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
!IF "$(CFG)" == "make_ibrowser - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Cmd_Line "NMAKE /f make_ibrowser.mak"
# PROP BASE Rebuild_Opt "/a"
# PROP BASE Target_File "make_ibrowser.exe"
# PROP BASE Bsc_Name "make_ibrowser.bsc"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.PCH UNICODE=0"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "ibrowser.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
!ELSEIF "$(CFG)" == "make_ibrowser - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Cmd_Line "NMAKE /f make_ibrowser.mak"
# PROP BASE Rebuild_Opt "/a"
# PROP BASE Target_File "make_ibrowser.exe"
# PROP BASE Bsc_Name "make_ibrowser.bsc"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.PCH UNICODE=0 DEBUG=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "ibrowser.exe"
# PROP Bsc_Name "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW UNICODE=0 DEBUG=1"
# PROP Target_Dir ""
!ELSEIF "$(CFG)" == "make_ibrowser - Win32 Unicode Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "UDebug"
# PROP BASE Intermediate_Dir "UDebug"
# PROP BASE Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW UNICODE=1 DEBUG=1"
# PROP BASE Rebuild_Opt "clean all"
# PROP BASE Target_File "ibrowser.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "UDebug"
# PROP Intermediate_Dir "UDebug"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW UNICODE=1 DEBUG=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "ibrowser.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
!ELSEIF "$(CFG)" == "make_ibrowser - Win32 Unicode Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "URelease"
# PROP BASE Intermediate_Dir "URelease"
# PROP BASE Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW UNICODE=1"
# PROP BASE Rebuild_Opt "clean all"
# PROP BASE Target_File "ibrowser.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "URelease"
# PROP Intermediate_Dir "URelease"
# PROP Cmd_Line "msdevfilt -gcc make -f Makefile.PCH UNICODE=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "ibrowser.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
!ELSEIF "$(CFG)" == "make_ibrowser - Win32 bjam"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW DEBUG=1"
# PROP BASE Rebuild_Opt "clean all"
# PROP BASE Target_File "ibrowser.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" bjam"
# PROP Rebuild_Opt "clean&bjam release"
# PROP Target_File "ibrowser.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
!ENDIF
# Begin Target
# Name "make_ibrowser - Win32 Release"
# Name "make_ibrowser - Win32 Debug"
# Name "make_ibrowser - Win32 Unicode Debug"
# Name "make_ibrowser - Win32 Unicode Release"
# Name "make_ibrowser - Win32 bjam"
!IF "$(CFG)" == "make_ibrowser - Win32 Release"
!ELSEIF "$(CFG)" == "make_ibrowser - Win32 Debug"
!ELSEIF "$(CFG)" == "make_ibrowser - Win32 Unicode Debug"
!ELSEIF "$(CFG)" == "make_ibrowser - Win32 Unicode Release"
!ELSEIF "$(CFG)" == "make_ibrowser - Win32 bjam"
!ENDIF
# Begin Source File
SOURCE=.\Jamfile
# End Source File
# Begin Source File
SOURCE=.\Makefile
# End Source File
# Begin Source File
SOURCE=.\Makefile.MinGW
# End Source File
# Begin Source File
SOURCE=.\Makefile.PCH
# End Source File
# End Target
# End Project

View file

@ -0,0 +1,28 @@
/*
* Copyright 2005 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// ROS Internet Web Browser - precompiled header support
//
// precomp.h
//
// Martin Fuchs, 25.01.2005
//
#include "precomp.h"

View file

@ -0,0 +1,32 @@
/*
* Copyright 2005 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// ROS Internet Web Browser - precompiled header support
//
// precomp.h
//
// Martin Fuchs, 25.01.2005
//
#include "utility/utility.h"
#include "utility/comutil.h"
#include "ibrowser.h"

View file

@ -0,0 +1,9 @@
IBrowser is a Web Browser User Interface similar derived from ROS Explorer.
It encapsulates the Mozilla or MS Web Browser Control.
For more information about ReactOS Explorer please look at the FAQ web page:
http://www.sky.franken.de/explorer/

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1,321 @@
/*
* Copyright 2005 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// ROS Internet Web Browser
//
// comutil.h
//
// C++ wrapper classes for COM interfaces
//
// Martin Fuchs, 25.01.2005
//
// windows shell headers
#include <shellapi.h>
#include <shlobj.h>
/*@@
#if _MSC_VER>=1300 // VS.Net
#include <comdefsp.h>
using namespace _com_util;
#endif
*/
#ifndef _INC_COMUTIL // is comutil.h of MS headers not available?
#ifndef _NO_COMUTIL
#define _NO_COMUTIL
#endif
#endif
// Exception Handling
#ifndef _NO_COMUTIL
#define COMExceptionBase _com_error
#else
/// COM ExceptionBase class as replacement for _com_error
struct COMExceptionBase
{
COMExceptionBase(HRESULT hr)
: _hr(hr)
{
}
HRESULT Error() const
{
return _hr;
}
LPCTSTR ErrorMessage() const
{
if (_msg.empty()) {
LPTSTR pBuf;
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
0, _hr, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (LPTSTR)&pBuf, 0, NULL)) {
_msg = pBuf;
LocalFree(pBuf);
} else {
TCHAR buffer[128];
_stprintf(buffer, TEXT("unknown Exception: 0x%08lX"), _hr);
_msg = buffer;
}
}
return _msg;
}
protected:
HRESULT _hr;
mutable String _msg;
};
#endif
/// Exception with context information
struct COMException : public COMExceptionBase
{
typedef COMExceptionBase super;
COMException(HRESULT hr)
: super(hr),
_context(CURRENT_CONTEXT),
_file(NULL), _line(0)
{
LOG(toString());
LOG(CURRENT_CONTEXT.getStackTrace());
}
COMException(HRESULT hr, const char* file, int line)
: super(hr),
_context(CURRENT_CONTEXT),
_file(file), _line(line)
{
LOG(toString());
LOG(CURRENT_CONTEXT.getStackTrace());
}
COMException(HRESULT hr, const String& obj)
: super(hr),
_context(CURRENT_CONTEXT),
_file(NULL), _line(0)
{
LOG(toString());
LOG(CURRENT_CONTEXT.getStackTrace());
}
COMException(HRESULT hr, const String& obj, const char* file, int line)
: super(hr),
_context(CURRENT_CONTEXT),
_file(file), _line(line)
{
LOG(toString());
LOG(CURRENT_CONTEXT.getStackTrace());
}
String toString() const;
Context _context;
const char* _file;
int _line;
};
#define THROW_EXCEPTION(hr) throw COMException(hr, __FILE__, __LINE__)
#define CHECKERROR(hr) ((void)(FAILED(hr)? THROW_EXCEPTION(hr): 0))
#ifdef _NO_COMUTIL
inline void CheckError(HRESULT hr)
{
if (FAILED(hr))
throw COMException(hr);
}
#endif
/// COM Initialisation
struct ComInit
{
ComInit()
{
CHECKERROR(CoInitialize(0));
}
#if (_WIN32_WINNT>=0x0400) || defined(_WIN32_DCOM)
ComInit(DWORD flag)
{
CHECKERROR(CoInitializeEx(0, flag));
}
#endif
~ComInit()
{
CoUninitialize();
}
};
/// OLE initialisation for drag drop support
struct OleInit
{
OleInit()
{
CHECKERROR(OleInitialize(0));
}
~OleInit()
{
OleUninitialize();
}
};
/// Exception Handler for COM exceptions
extern void HandleException(COMException& e, HWND hwnd);
/// wrapper class for COM interface pointers
template<typename T> struct SIfacePtr
{
SIfacePtr()
: _p(0)
{
}
SIfacePtr(T* p)
: _p(p)
{
if (p)
p->AddRef();
}
SIfacePtr(IUnknown* unknown, REFIID riid)
{
CHECKERROR(unknown->QueryInterface(riid, (LPVOID*)&_p));
}
~SIfacePtr()
{
Free();
}
T* operator->()
{
return _p;
}
const T* operator->() const
{
return _p;
}
/* not GCC compatible
operator const T*() const
{
return _p;
} */
operator T*()
{
return _p;
}
T** operator&()
{
return &_p;
}
bool empty() const //NOTE: GCC seems not to work correctly when defining operator bool() AND operator T*() at one time
{
return !_p;
}
SIfacePtr& operator=(T* p)
{
Free();
if (p) {
p->AddRef();
_p = p;
}
return *this;
}
void operator=(SIfacePtr const& o)
{
T* h = _p;
if (o._p)
o._p->AddRef();
_p = o._p;
if (h)
h->Release();
}
HRESULT CreateInstance(REFIID clsid, REFIID riid)
{
return CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, riid, (LPVOID*)&_p);
}
template<typename I> HRESULT QueryInterface(REFIID riid, I* p)
{
return _p->QueryInterface(riid, (LPVOID*)p);
}
T* get()
{
return _p;
}
void Free()
{
T* h = _p;
_p = NULL;
if (h)
h->Release();
}
protected:
SIfacePtr(const SIfacePtr& o)
: _p(o._p)
{
if (_p)
_p->AddRef();
}
T* _p;
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,419 @@
/*
* Copyright 2003, 2004, 2005 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// Explorer clone
//
// utility.cpp
//
// Martin Fuchs, 23.07.2003
//
#include "precomp.h"
//#include <shellapi.h>
#include <time.h>
#include <sstream>
DWORD WINAPI Thread::ThreadProc(void* para)
{
Thread* pThis = (Thread*) para;
int ret = pThis->Run();
pThis->_alive = false;
return ret;
}
void CenterWindow(HWND hwnd)
{
RECT rt, prt;
GetWindowRect(hwnd, &rt);
DWORD style;
HWND owner = 0;
for(HWND wh=hwnd; (wh=GetWindow(wh,GW_OWNER))!=0; )
if (((style=GetWindowStyle(wh))&WS_VISIBLE) && !(style&WS_MINIMIZE))
{owner=wh; break;}
if (owner)
GetWindowRect(owner, &prt);
else
SystemParametersInfo(SPI_GETWORKAREA, 0, &prt, 0); //@@ GetDesktopWindow() wäre auch hilfreich.
SetWindowPos(hwnd, 0, (prt.left+prt.right+rt.left-rt.right)/2,
(prt.top+prt.bottom+rt.top-rt.bottom)/2, 0,0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
MoveVisible(hwnd);
}
void MoveVisible(HWND hwnd)
{
RECT rc;
GetWindowRect(hwnd, &rc);
int left=rc.left, top=rc.top;
int xmax = GetSystemMetrics(SM_CXSCREEN);
int ymax = GetSystemMetrics(SM_CYSCREEN);
if (rc.left < 0)
rc.left = 0;
else if (rc.right > xmax)
if ((rc.left-=rc.right-xmax) < 0)
rc.left = 0;
if (rc.top < 0)
rc.top = 0;
else if (rc.bottom > ymax)
if ((rc.top-=rc.bottom-ymax) < 0)
rc.top = 0;
if (rc.left!=left || rc.top!=top)
SetWindowPos(hwnd, 0, rc.left,rc.top, 0,0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
}
void display_error(HWND hwnd, DWORD error) //@@ CONTEXT mit ausgeben -> display_error(HWND hwnd, const Exception& e)
{
PTSTR msg;
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
0, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PTSTR)&msg, 0, NULL)) {
LOG(FmtString(TEXT("display_error(%#x): %s"), error, msg));
SetLastError(0);
MessageBox(hwnd, msg, TEXT("ROS Explorer"), MB_OK);
if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)
MessageBox(0, msg, TEXT("ROS Explorer"), MB_OK);
} else {
LOG(FmtString(TEXT("Unknown Error %#x"), error));
FmtString msg(TEXT("Unknown Error %#x"), error);
SetLastError(0);
MessageBox(hwnd, msg, TEXT("ROS Explorer"), MB_OK);
if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)
MessageBox(0, msg, TEXT("ROS Explorer"), MB_OK);
}
LocalFree(msg);
}
Context Context::s_main("-NO-CONTEXT-");
Context* Context::s_current = &Context::s_main;
String Context::toString() const
{
String str = _ctx;
if (!_obj.empty())
str.appendf(TEXT("\nObject: %s"), (LPCTSTR)_obj);
return str;
}
String Context::getStackTrace() const
{
ostringstream str;
str << "Context Trace:\n";
for(const Context*p=this; p && p!=&s_main; p=p->_last) {
str << "- " << p->_ctx;
if (!p->_obj.empty())
str << " obj=" << ANS(p->_obj);
str << '\n';
}
return str.str();
}
BOOL time_to_filetime(const time_t* t, FILETIME* ftime)
{
struct tm* tm = gmtime(t);
SYSTEMTIME stime;
if (!tm)
return FALSE;
stime.wYear = tm->tm_year+1900;
stime.wMonth = tm->tm_mon+1;
stime.wDayOfWeek = (WORD)-1;
stime.wDay = tm->tm_mday;
stime.wHour = tm->tm_hour;
stime.wMinute = tm->tm_min;
stime.wSecond = tm->tm_sec;
stime.wMilliseconds = 0;
return SystemTimeToFileTime(&stime, ftime);
}
BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow, LPCTSTR parameters)
{
CONTEXT("launch_file()");
HINSTANCE hinst = ShellExecute(hwnd, NULL/*operation*/, cmd, parameters, NULL/*dir*/, nCmdShow);
if ((int)hinst <= 32) {
display_error(hwnd, GetLastError());
return FALSE;
}
return TRUE;
}
#ifdef UNICODE
BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow, LPCSTR parameters)
{
HINSTANCE hinst = ShellExecuteA(hwnd, NULL/*operation*/, cmd, parameters, NULL/*dir*/, nCmdShow);
if ((int)hinst <= 32) {
display_error(hwnd, GetLastError());
return FALSE;
}
return TRUE;
}
#endif
/* search for already running instance */
static int g_foundPrevInstance = 0;
static BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lparam)
{
TCHAR cls[128];
GetClassName(hwnd, cls, 128);
if (!lstrcmp(cls, (LPCTSTR)lparam)) {
g_foundPrevInstance++;
return FALSE;
}
return TRUE;
}
/* search for window of given class name to allow only one running instance */
int find_window_class(LPCTSTR classname)
{
EnumWindows(EnumWndProc, (LPARAM)classname);
if (g_foundPrevInstance)
return 1;
return 0;
}
typedef void (WINAPI*RUNDLLPROC)(HWND hwnd, HINSTANCE hinst, LPCTSTR cmdline, DWORD nCmdShow);
BOOL RunDLL(HWND hwnd, LPCTSTR dllname, LPCSTR procname, LPCTSTR cmdline, UINT nCmdShow)
{
HMODULE hmod = LoadLibrary(dllname);
if (!hmod)
return FALSE;
/*TODO
<Windows NT/2000>
It is possible to create a Unicode version of the function.
Rundll32 first tries to find a function named EntryPointW.
If it cannot find this function, it tries EntryPointA, then EntryPoint.
To create a DLL that supports ANSI on Windows 95/98/Me and Unicode otherwise,
export two functions: EntryPointW and EntryPoint.
*/
RUNDLLPROC proc = (RUNDLLPROC)GetProcAddress(hmod, procname);
if (!proc) {
FreeLibrary(hmod);
return FALSE;
}
proc(hwnd, hmod, cmdline, nCmdShow);
FreeLibrary(hmod);
return TRUE;
}
BOOL launch_cpanel(HWND hwnd, LPCTSTR applet)
{
//launch_file(_hwnd, applet, SW_SHOWNORMAL); // This would be enough, but we want the fastest solution.
//launch_file(_hwnd, TEXT("rundll32.exe /d shell32.dll,Control_RunDLL ")+applet, SW_SHOWNORMAL);
return RunDLL(hwnd, TEXT("shell32"), "Control_RunDLL", applet, SW_SHOWNORMAL);
}
BOOL RecursiveCreateDirectory(LPCTSTR path_in)
{
TCHAR path[MAX_PATH], hole_path[MAX_PATH];
_tcscpy(hole_path, path_in);
int drv_len = 0;
LPCTSTR d;
for(d=hole_path; *d && *d!='/' && *d!='\\'; ++d) {
++drv_len;
if (*d == ':')
break;
}
LPTSTR dir = hole_path + drv_len;
int l;
LPTSTR p = hole_path + (l=_tcslen(hole_path));
while(--p>=hole_path && (*p=='/' || *p=='\\'))
*p = '\0';
WIN32_FIND_DATA w32fd;
HANDLE hFind = FindFirstFile(hole_path, &w32fd);
if (hFind == INVALID_HANDLE_VALUE) {
_tcsncpy(path, hole_path, drv_len);
int i = drv_len;
for(p=dir; *p=='/'||*p=='\\'; p++)
path[i++] = *p++;
for(; i<l; i++) {
memcpy(path, hole_path, i*sizeof(TCHAR));
for(; hole_path[i] && hole_path[i]!='/' && hole_path[i]!='\\'; i++)
path[i] = hole_path[i];
path[i] = '\0';
hFind = FindFirstFile(path, &w32fd);
if (hFind != INVALID_HANDLE_VALUE)
FindClose(hFind);
else {
LOG(FmtString(TEXT("CreateDirectory(\"%s\")"), path));
if (!CreateDirectory(path, 0))
return FALSE;
}
}
} else
FindClose(hFind);
return TRUE;
}
BOOL exists_path(LPCTSTR path)
{
WIN32_FIND_DATA fd;
HANDLE hfind = FindFirstFile(path, &fd);
if (hfind != INVALID_HANDLE_VALUE) {
FindClose(hfind);
return TRUE;
} else
return FALSE;
}
bool SplitFileSysURL(LPCTSTR url, String& dir_out, String& fname_out)
{
if (!_tcsnicmp(url, TEXT("file://"), 7)) {
url += 7;
// remove third slash in front of drive characters
if (*url == '/')
++url;
}
if (exists_path(url)) {
TCHAR path[_MAX_PATH];
// convert slashes to back slashes
GetFullPathName(url, _MAX_PATH, path, NULL);
if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY)
fname_out.erase();
else {
TCHAR drv[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
_tsplitpath(path, drv, dir, fname, ext);
_stprintf(path, TEXT("%s%s"), drv, dir);
fname_out.printf(TEXT("%s%s"), fname, ext);
}
dir_out = path;
return true;
} else
return false;
}
/// Exception Handler for COM exceptions
void HandleException(COMException& e, HWND hwnd)
{
String msg = e.toString();
SetLastError(0);
if (hwnd && !IsWindowVisible(hwnd))
hwnd = 0;
MessageBox(hwnd, msg, TEXT("ShellClasses Exception"), MB_ICONHAND|MB_OK);
// If displaying the error message box _with_ parent was not successfull, display it now without a parent window.
if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)
MessageBox(0, msg, TEXT("ShellClasses Exception"), MB_ICONHAND|MB_OK);
}
String COMException::toString() const
{
TCHAR msg[4*BUFFER_LEN];
LPTSTR p = msg;
p += _stprintf(p, TEXT("%s\nContext: %s"), super::ErrorMessage(), (LPCTSTR)_context.toString());
if (_file)
p += _stprintf(p, TEXT("\nLocation: %hs:%d"), _file, _line);
return msg;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,612 @@
//
// XML storage classes
//
// xmlstorage.cpp
//
// Copyright (c) 2004, Martin Fuchs <martin-fuchs@gmx.net>
//
/*
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
//#include "xmlstorage.h"
#include "precomp.h"
// work around GCC's wide string constant bug
#ifdef __GNUC__
const LPCXSSTR XMLStorage::XS_TRUE = XS_TEXT("true");
const LPCXSSTR XMLStorage::XS_FALSE = XS_TEXT("false");
const LPCXSSTR XMLStorage::XS_NUMBERFMT = XS_TEXT("%d");
#endif
namespace XMLStorage {
static std::string unescape(const char* s, char b='"', char e='"')
{
const char* end = s + strlen(s);
// if (*s == b)
// ++s;
//
// if (end>s && end[-1]==e)
// --end;
if (*s == b)
if (end>s && end[-1]==e)
++s, --end;
return std::string(s, end-s);
}
static std::string unescape(const char* s, int l, char b='"', char e='"')
{
const char* end = s + l;
// if (*s == b)
// ++s;
//
// if (end>s && end[-1]==e)
// --end;
if (*s == b)
if (end>s && end[-1]==e)
++s, --end;
return std::string(s, end-s);
}
/// move XPath like to position in XML tree
bool XMLPos::go(const char* path)
{
XMLNode* node = _cur;
// Is this an absolute path?
if (*path == '/') {
node = _root;
++path;
}
node = node->find_relative(path);
if (node) {
go_to(node);
return true;
} else
return false;
}
/// move XPath like to position in XML tree
bool const_XMLPos::go(const char* path)
{
const XMLNode* node = _cur;
// Is this an absolute path?
if (*path == '/') {
node = _root;
++path;
}
node = node->find_relative(path);
if (node) {
go_to(node);
return true;
} else
return false;
}
const XMLNode* XMLNode::find_relative(const char* path) const
{
const XMLNode* node = this;
// parse relative path
while(*path) {
const char* slash = strchr(path, '/');
if (slash == path)
return NULL;
int l = slash? slash-path: strlen(path);
std::string comp(path, l);
path += l;
// look for [n] and [@attr_name="attr_value"] expressions in path components
const char* bracket = strchr(comp.c_str(), '[');
l = bracket? bracket-comp.c_str(): comp.length();
std::string child_name(comp.c_str(), l);
std::string attr_name, attr_value;
int n = 0;
if (bracket) {
std::string expr = unescape(bracket, '[', ']');
const char* p = expr.c_str();
n = atoi(p); // read index number
if (n)
n = n - 1; // convert into zero based index
const char* at = strchr(p, '@');
if (at) {
p = at + 1;
const char* equal = strchr(p, '=');
// read attribute name and value
if (equal) {
attr_name = unescape(p, equal-p);
attr_value = unescape(equal+1);
}
}
}
if (attr_name.empty())
// search n.th child node with specified name
node = node->find(child_name, n);
else
// search n.th child node with specified name and matching attribute value
node = node->find(child_name, attr_name, attr_value, n);
if (!node)
return NULL;
if (*path == '/')
++path;
}
return node;
}
XMLNode* XMLNode::create_relative(const char* path)
{
XMLNode* node = this;
// parse relative path
while(*path) {
const char* slash = strchr(path, '/');
if (slash == path)
return NULL;
int l = slash? slash-path: strlen(path);
std::string comp(path, l);
path += l;
// look for [n] and [@attr_name="attr_value"] expressions in path components
const char* bracket = strchr(comp.c_str(), '[');
l = bracket? bracket-comp.c_str(): comp.length();
std::string child_name(comp.c_str(), l);
std::string attr_name, attr_value;
int n = 0;
if (bracket) {
std::string expr = unescape(bracket, '[', ']');
const char* p = expr.c_str();
n = atoi(p); // read index number
if (n)
n = n - 1; // convert into zero based index
const char* at = strchr(p, '@');
if (at) {
p = at + 1;
const char* equal = strchr(p, '=');
// read attribute name and value
if (equal) {
attr_name = unescape(p, equal-p);
attr_value = unescape(equal+1);
}
}
}
XMLNode* child;
if (attr_name.empty())
// search n.th child node with specified name
child = node->find(child_name, n);
else
// search n.th child node with specified name and matching attribute value
child = node->find(child_name, attr_name, attr_value, n);
if (!child) {
child = new XMLNode(child_name);
node->add_child(child);
if (!attr_name.empty())
(*node)[attr_name] = attr_value;
}
node = child;
if (*path == '/')
++path;
}
return node;
}
/// read XML stream into XML tree below _pos
XML_Status XMLReaderBase::read()
{
XML_Status status = XML_STATUS_OK;
while(status == XML_STATUS_OK) {
char* buffer = (char*) XML_GetBuffer(_parser, BUFFER_LEN);
int l = read_buffer(buffer, BUFFER_LEN);
if (l < 0)
break;
status = XML_ParseBuffer(_parser, l, false);
}
if (status != XML_STATUS_ERROR)
status = XML_ParseBuffer(_parser, 0, true);
if (_pos->_children.empty())
_pos->_trailing.append(_content);
else
_pos->_children.back()->_trailing.append(_content);
_content.erase();
return status;
}
/// store XML version and encoding into XML reader
void XMLCALL XMLReaderBase::XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
if (version)
pReader->_xml_version = version;
if (encoding)
pReader->_encoding = encoding;
}
/// notifications about XML start tag
void XMLCALL XMLReaderBase::XML_StartElementHandler(void* userData, const XML_Char* name, const XML_Char** atts)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
XMLPos& pos = pReader->_pos;
// search for end of first line
const char* s = pReader->_content.c_str();
const char* p = s;
const char* e = p + pReader->_content.length();
for(; p<e; ++p)
if (*p == '\n') {
++p;
break;
}
if (p != s)
if (pos->_children.empty()) { // no children in last node?
if (pReader->_last_tag == TAG_START)
pos->_content.append(s, p-s);
else if (pReader->_last_tag == TAG_END)
pos->_trailing.append(s, p-s);
// else TAG_NONE -> don't store white space in root node
} else
pos->_children.back()->_trailing.append(s, p-s);
std::string leading;
if (p != e)
leading.assign(p, e-p);
XMLNode* node = new XMLNode(String_from_XML_Char(name), leading);
pos.add_down(node);
while(*atts) {
const XML_Char* attr_name = *atts++;
const XML_Char* attr_value = *atts++;
(*node)[String_from_XML_Char(attr_name)] = String_from_XML_Char(attr_value);
}
pReader->_last_tag = TAG_START;
pReader->_content.erase();
}
/// notifications about XML end tag
void XMLCALL XMLReaderBase::XML_EndElementHandler(void* userData, const XML_Char* name)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
XMLPos& pos = pReader->_pos;
// search for end of first line
const char* s = pReader->_content.c_str();
const char* p = s;
const char* e = p + pReader->_content.length();
for(; p<e; ++p)
if (*p == '\n') {
++p;
break;
}
if (p != s)
if (pos->_children.empty()) // no children in current node?
pos->_content.append(s, p-s);
else
if (pReader->_last_tag == TAG_START)
pos->_content.append(s, p-s);
else
pos->_children.back()->_trailing.append(s, p-s);
if (p != e)
pos->_end_leading.assign(p, e-p);
pos.back();
pReader->_last_tag = TAG_END;
pReader->_content.erase();
}
/// store content, white space and comments
void XMLCALL XMLReaderBase::XML_DefaultHandler(void* userData, const XML_Char* s, int len)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
pReader->_content.append(s, len);
}
std::string XMLReaderBase::get_error_string() const
{
XML_Error error = XML_GetErrorCode(_parser);
switch(error) {
case XML_ERROR_NONE: return "XML_ERROR_NONE";
case XML_ERROR_NO_MEMORY: return "XML_ERROR_NO_MEMORY";
case XML_ERROR_SYNTAX: return "XML_ERROR_SYNTAX";
case XML_ERROR_NO_ELEMENTS: return "XML_ERROR_NO_ELEMENTS";
case XML_ERROR_INVALID_TOKEN: return "XML_ERROR_INVALID_TOKEN";
case XML_ERROR_UNCLOSED_TOKEN: return "XML_ERROR_UNCLOSED_TOKEN";
case XML_ERROR_PARTIAL_CHAR: return "XML_ERROR_PARTIAL_CHAR";
case XML_ERROR_TAG_MISMATCH: return "XML_ERROR_TAG_MISMATCH";
case XML_ERROR_DUPLICATE_ATTRIBUTE: return "XML_ERROR_DUPLICATE_ATTRIBUTE";
case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: return "XML_ERROR_JUNK_AFTER_DOC_ELEMENT";
case XML_ERROR_PARAM_ENTITY_REF: return "XML_ERROR_PARAM_ENTITY_REF";
case XML_ERROR_UNDEFINED_ENTITY: return "XML_ERROR_UNDEFINED_ENTITY";
case XML_ERROR_RECURSIVE_ENTITY_REF: return "XML_ERROR_RECURSIVE_ENTITY_REF";
case XML_ERROR_ASYNC_ENTITY: return "XML_ERROR_ASYNC_ENTITY";
case XML_ERROR_BAD_CHAR_REF: return "XML_ERROR_BAD_CHAR_REF";
case XML_ERROR_BINARY_ENTITY_REF: return "XML_ERROR_BINARY_ENTITY_REF";
case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: return "XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF";
case XML_ERROR_MISPLACED_XML_PI: return "XML_ERROR_MISPLACED_XML_PI";
case XML_ERROR_UNKNOWN_ENCODING: return "XML_ERROR_UNKNOWN_ENCODING";
case XML_ERROR_INCORRECT_ENCODING: return "XML_ERROR_INCORRECT_ENCODING";
case XML_ERROR_UNCLOSED_CDATA_SECTION: return "XML_ERROR_UNCLOSED_CDATA_SECTION";
case XML_ERROR_EXTERNAL_ENTITY_HANDLING: return "XML_ERROR_EXTERNAL_ENTITY_HANDLING";
case XML_ERROR_NOT_STANDALONE: return "XML_ERROR_NOT_STANDALONE";
case XML_ERROR_UNEXPECTED_STATE: return "XML_ERROR_UNEXPECTED_STATE";
case XML_ERROR_ENTITY_DECLARED_IN_PE: return "XML_ERROR_ENTITY_DECLARED_IN_PE";
case XML_ERROR_FEATURE_REQUIRES_XML_DTD: return "XML_ERROR_FEATURE_REQUIRES_XML_DTD";
case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: return "XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING";
case XML_ERROR_UNBOUND_PREFIX: return "XML_ERROR_UNBOUND_PREFIX";
// EXPAT version >= 1.95.8
#if XML_MAJOR_VERSION>1 || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION>95) || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION==95 && XML_MICRO_VERSION>7)
case XML_ERROR_SUSPENDED: return "XML_ERROR_SUSPENDED";
case XML_ERROR_NOT_SUSPENDED: return "XML_ERROR_NOT_SUSPENDED";
case XML_ERROR_ABORTED: return "XML_ERROR_ABORTED";
case XML_ERROR_FINISHED: return "XML_ERROR_FINISHED";
case XML_ERROR_SUSPEND_PE: return "XML_ERROR_SUSPEND_PE";
#endif
}
std::ostringstream out;
out << "XML parser error #" << error;
return out.str();
}
std::string EncodeXMLString(const XS_String& str)
{
LPCXSSTR s = str.c_str();
LPXSSTR buffer = (LPXSSTR)alloca(5*sizeof(XS_CHAR)*XS_len(s)); // worst case. "&amp;"
LPXSSTR o = buffer;
for(LPCXSSTR p=s; *p; ++p)
switch(*p) {
case '&':
*o++ = '&'; *o++ = 'a'; *o++ = 'm'; *o++ = 'p'; *o++ = ';';
break;
case '<':
*o++ = '&'; *o++ = 'l'; *o++ = 't'; *o++ = ';';
break;
case '>':
*o++ = '&'; *o++ = 'g'; *o++ = 't'; *o++ = ';';
break;
case '"':
*o++ = '&'; *o++ = 'q'; *o++ = 'u'; *o++ = 'o'; *o++ = 't'; *o++ = ';';
break;
case '\'':
*o++ = '&'; *o++ = 'a'; *o++ = 'p'; *o++ = 'o'; *o++ = 's'; *o++ = ';';
break;
default:
*o++ = *p;
}
#ifdef XS_STRING_UTF8
return XS_String(buffer, o-buffer);
#else
return get_utf8(buffer, o-buffer);
#endif
}
XS_String DecodeXMLString(const XS_String& str)
{
LPCXSSTR s = str.c_str();
LPXSSTR buffer = (LPXSSTR)alloca(sizeof(XS_CHAR)*XS_len(s));
LPXSSTR o = buffer;
for(LPCXSSTR p=s; *p; ++p)
if (*p == '&') {
if (!XS_nicmp(p+1, XS_TEXT("lt;"), 3)) {
*o++ = '<';
p += 3;
} else if (!XS_nicmp(p+1, XS_TEXT("gt;"), 3)) {
*o++ = '>';
p += 3;
} else if (!XS_nicmp(p+1, XS_TEXT("amp;"), 4)) {
*o++ = '&';
p += 4;
} else if (!XS_nicmp(p+1, XS_TEXT("quot;"), 5)) {
*o++ = '"';
p += 5;
} else if (!XS_nicmp(p+1, XS_TEXT("apos;"), 5)) {
*o++ = '\'';
p += 5;
} else
*o++ = *p;
} else
*o++ = *p;
return XS_String(buffer, o-buffer);
}
/// write node with children tree to output stream using original white space
void XMLNode::write_worker(std::ostream& out, int indent) const
{
out << _leading << '<' << EncodeXMLString(*this);
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
if (!_children.empty() || !_content.empty()) {
out << '>' << _content;
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
(*it)->write_worker(out, indent+1);
out << _end_leading << "</" << EncodeXMLString(*this) << '>';
} else
out << "/>";
out << _trailing;
}
/// pretty print node with children tree to output stream
void XMLNode::pretty_write_worker(std::ostream& out, int indent) const
{
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
out << '<' << EncodeXMLString(*this);
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
if (!_children.empty() || !_content.empty()) {
out << ">\n";
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
(*it)->pretty_write_worker(out, indent+1);
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
out << "</" << EncodeXMLString(*this) << ">\n";
} else
out << "/>\n";
}
/// write node with children tree to output stream using smart formating
void XMLNode::smart_write_worker(std::ostream& out, int indent) const
{
if (_leading.empty())
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
else
out << _leading;
out << '<' << EncodeXMLString(*this);
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";
if (_children.empty() && _content.empty())
out << "/>";
else {
out << '>';
if (_content.empty())
out << '\n';
else
out << _content;
Children::const_iterator it = _children.begin();
if (it != _children.end()) {
for(; it!=_children.end(); ++it)
(*it)->smart_write_worker(out, indent+1);
if (_end_leading.empty())
for(int i=indent; i--; )
out << XML_INDENT_SPACE;
else
out << _end_leading;
} else
out << _end_leading;
out << "</" << EncodeXMLString(*this) << '>';
}
if (_trailing.empty())
out << '\n';
else
out << _trailing;
}
} // namespace XMLStorage

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,309 @@
/*
* Copyright 2004, 2005 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// ROS Internet Web Browser
//
// webchild.cpp
//
// Martin Fuchs, 25.01.2005
//
#include "precomp.h"
#include "ibrowser_intres.h"
#include "webchild.h"
#ifdef _MSC_VER
#if _MSC_VER>=1300 // vtMissing for VS.Net
#include <comutil.h>
#pragma comment(lib, "comsupp")
#endif
#else
#ifdef __MINGW32__ // MinGW is lacking vtMissing (as of 07.02.2004)
static Variant vtMissing;
#endif
#endif
//#include <mshtml.h>
Variant::Variant(const VARIANT& var)
{
VariantInit(this);
CheckError(VariantCopy(this, const_cast<VARIANT*>(&var)));
}
Variant::Variant(const VARIANT* var)
{
VariantInit(this);
CheckError(VariantCopy(this, const_cast<VARIANT*>(var)));
}
Variant::~Variant()
{
VariantClear(this);
}
Variant::operator long() const
{
Variant v;
CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_I4));
return V_I4(&v);
}
Variant::operator bool() const
{
Variant v;
CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_BOOL));
return V_BOOL(&v)? true: false;
}
Variant::operator IDispatch*() const
{
Variant v;
CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_DISPATCH));
return V_DISPATCH(&v);
}
Variant::operator VARIANT_BOOL() const
{
Variant v;
CheckError(VariantChangeType(&v, (VARIANT*)this, 0, VT_BOOL));
return V_BOOL(&v);
}
void BStr::assign(BSTR s)
{
if (!SysReAllocString(&_p, s))
THROW_EXCEPTION(E_OUTOFMEMORY);
}
void BStr::assign(const VARIANT& var)
{
if (V_VT(&var) == VT_BSTR)
assign(V_BSTR(&var));
else {
Variant v;
CheckError(VariantChangeType(&v, const_cast<VARIANT*>(&var), 0, VT_BSTR));
assign(V_BSTR(&v));
}
}
BrowserNavigator::BrowserNavigator()
: _browser_initialized(false)
{
}
void BrowserNavigator::attach(IWebBrowser* browser)
{
_browser = browser;
}
void BrowserNavigator::goto_url(LPCTSTR url)
{
if (_browser_initialized)
_browser->Navigate(BStr(url), NULL, NULL, NULL, NULL);
else {
_new_url = url;
_browser->Navigate(L"about:blank", NULL, NULL, NULL, NULL);
}
}
void BrowserNavigator::set_html_page(const String& html_txt)
{
_new_html_txt = html_txt;
goto_url(TEXT("about:blank"));
}
void T2nA_binary(LPCTSTR s, LPSTR d, int len)
{
while(len-- > 0)
*d++ = (unsigned char)*s++;
}
void BrowserNavigator::navigated(LPCTSTR url)
{
_browser_initialized = true;
bool nav = false;
if (!_new_url.empty()) {
if (!_tcscmp(url,TEXT("about:blank")) && _new_url!=TEXT("about:blank")) {
_browser->Navigate(BStr(_new_url), NULL, NULL, NULL, NULL);
++nav;
}
_new_url.erase();
}
if (!nav && !_new_html_txt.empty()) { ///@todo move this into DocumentComplete() ?
int len = _new_html_txt.length();
HGLOBAL hHtmlText = GlobalAlloc(GPTR, len);
if (!hHtmlText) {
T2nA_binary(_new_html_txt, (char*)hHtmlText, len);
_new_html_txt.erase();
SIfacePtr<IStream> pStream;
HRESULT hr = CreateStreamOnHGlobal(hHtmlText, TRUE, &pStream);
if (SUCCEEDED(hr)) {
SIfacePtr<IDispatch> pHtmlDoc;
CheckError(_browser->get_Document(&pHtmlDoc));
SIfacePtr<IPersistStreamInit> pPersistStreamInit;
pHtmlDoc.QueryInterface(IID_IPersistStreamInit, &pPersistStreamInit);
CheckError(pPersistStreamInit->InitNew());
CheckError(pPersistStreamInit->Load(pStream));
} else
GlobalFree(hHtmlText);
}
}
}
HWND create_webchildwindow(const WebChildWndInfo& info)
{
WebChildWindow* pWnd = WebChildWindow::create(info);
if (!pWnd)
return 0;
return *pWnd;
}
static const CLSID CLSID_MozillaBrowser =
{0x1339B54C, 0x3453, 0x11D2, {0x93, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
WebChildWindow::WebChildWindow(HWND hwnd, const WebChildWndInfo& info)
: super(hwnd, info._hwndFrame),
web_super(_navigator)
{
// first try to create a web control with MS IE's CLASSID
HRESULT hr = create_control(hwnd, CLSID_WebBrowser, IID_IWebBrowser2);
// If this failed, try to use Mozilla's web control
if (FAILED(hr))
hr = create_control(hwnd, CLSID_MozillaBrowser, IID_IWebBrowser2);
if (SUCCEEDED(hr)) {
_navigator.attach(_control);
_connector = auto_ptr<EventConnector>(new EventConnector(_control, DIID_DWebBrowserEvents2, this));
_control->Navigate(BStr(info._url), &vtMissing, &vtMissing, &vtMissing, &vtMissing);
//browser->Navigate2(&Variant(info._url), &vtMissing, &vtMissing, &vtMissing, &vtMissing);
}
}
LRESULT WebChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{
try {
switch(nmsg) {
case WM_ERASEBKGND:
if (!_control) {
HDC hdc = (HDC)wparam;
ClientRect rect(_hwnd);
HBRUSH hbrush = CreateSolidBrush(RGB(200,200,235));
BkMode mode(hdc, TRANSPARENT);
TextColor color(hdc, RGB(200,40,40));
FillRect(hdc, &rect, hbrush);
DrawText(hdc, TEXT("Sorry - no web browser control could be loaded."), -1, &rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
DeleteObject(hbrush);
}
return TRUE;
case PM_DISPATCH_COMMAND: {
if (_control) {
HRESULT hr = E_FAIL;
switch(LOWORD(wparam)) {
case ID_GO_BACK:
hr = _control->GoBack();
break;
case ID_GO_FORWARD:
hr = _control->GoForward();
break;
case ID_GO_UP:
///@todo
break;
case ID_GO_HOME:
hr = _control->GoHome();
break;
case ID_GO_SEARCH:
hr = _control->GoSearch();
break;
case ID_REFRESH:
hr = _control->Refresh();
break;
case ID_STOP:
hr = _control->Stop();
break;
default:
return super::WndProc(nmsg, wparam, lparam);
}
if (FAILED(hr) && hr!=E_FAIL)
THROW_EXCEPTION(hr);
}
return TRUE;}
default:
return super::WndProc(nmsg, wparam, lparam);
}
} catch(COMException& e) {
HandleException(e, _hwnd);
}
return 0;
}
String WebChildWindow::jump_to_int(LPCTSTR url)
{
_navigator.goto_url(url);
return url;
}

File diff suppressed because it is too large Load diff