context menus for qick launch bar

svn path=/trunk/; revision=10363
This commit is contained in:
Martin Fuchs 2004-08-02 19:16:18 +00:00
parent efb2135435
commit 62f1a2a671
15 changed files with 247 additions and 139 deletions

View file

@ -81,7 +81,7 @@ DELAYIMPORTS = oleaut32 wsock32
all: precomp.h.gch $(TARGET)
precomp.h.gch:
precomp.h.gch: *.h utility/*.h shell/*.h desktop/*.h
$(CXX) $(CFLAGS) precomp.h
$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll libexpat.dll

View file

@ -159,8 +159,10 @@ TaskbarSettingsDlg::TaskbarSettingsDlg(HWND hwnd)
: super(hwnd),
_cfg_org(g_Globals._cfg)
{
CheckDlgButton(hwnd, ID_SHOW_CLOCK, XMLBool(g_Globals.get_cfg("desktopbar"), "options", "show-clock", true)? BST_CHECKED: BST_UNCHECKED);
CheckDlgButton(hwnd, ID_HIDE_INACTIVE_ICONS, XMLBool(g_Globals.get_cfg("notify-icons"), "options", "hide-inactive", true)? BST_CHECKED: BST_UNCHECKED);
XMLPos options(g_Globals.get_cfg("desktopbar"), "options");
CheckDlgButton(hwnd, ID_SHOW_CLOCK, XMLBool(options, "show-clock", true)? BST_CHECKED: BST_UNCHECKED);
CheckDlgButton(hwnd, ID_HIDE_INACTIVE_ICONS, XMLBool(options, "hide-inactive", true)? BST_CHECKED: BST_UNCHECKED);
}
int TaskbarSettingsDlg::Notify(int id, NMHDR* pnmh)
@ -190,13 +192,13 @@ int TaskbarSettingsDlg::Command(int id, int code)
break;
case ID_SHOW_CLOCK:
XMLBoolRef(g_Globals.get_cfg("desktopbar"), "options", "show-clock", true).toggle();
XMLBoolRef(XMLPos(g_Globals.get_cfg("desktopbar"),"options"), "show-clock", true).toggle();
SendMessage(g_Globals._hwndDesktopBar, PM_REFRESH_CONFIG, 0, 0);
PropSheet_Changed(GetParent(_hwnd), _hwnd);
break;
case ID_HIDE_INACTIVE_ICONS:
XMLBoolRef(g_Globals.get_cfg("notify-icons"), "options", "hide-inactive", true).toggle();
XMLBoolRef(XMLPos(g_Globals.get_cfg("notify-icons"),"options"), "hide-inactive", true).toggle();
SendMessage(g_Globals._hwndDesktopBar, PM_REFRESH_CONFIG, 0, 0);
PropSheet_Changed(GetParent(_hwnd), _hwnd);
break;

View file

@ -1,6 +1,5 @@
- rewrite autostart code and include all possible autostart locations
- read "DESCRIPT.ION" files to display file descriptions
- context menus for quick launch bar
- detect display mode changes and adjust desktop bar size
- handling of full screen applications
- implement additional deskbands

View file

@ -199,6 +199,10 @@ SOURCE=.\Makefile.MinGW
# End Source File
# Begin Source File
SOURCE=.\Makefile.PCH
# End Source File
# Begin Source File
SOURCE=.\Makefile.Wine
# End Source File
# End Target

View file

@ -395,6 +395,52 @@ BOOL Entry::launch_entry(HWND hwnd, UINT nCmdShow)
}
HRESULT Entry::do_context_menu(HWND hwnd, const POINT& pos)
{
ShellPath shell_path = create_absolute_pidl();
LPCITEMIDLIST pidl_abs = shell_path;
if (!pidl_abs)
return S_FALSE; // no action for registry entries, etc.
static DynamicFct<HRESULT(WINAPI*)(LPCITEMIDLIST, REFIID, LPVOID*, LPCITEMIDLIST*)> SHBindToParent(TEXT("SHELL32"), "SHBindToParent");
if (SHBindToParent) {
IShellFolder* parentFolder;
LPCITEMIDLIST pidlLast;
// get and use the parent folder to display correct context menu in all cases -> correct "Properties" dialog for directories, ...
HRESULT hr = (*SHBindToParent)(pidl_abs, IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast);
if (SUCCEEDED(hr)) {
hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pos.x, pos.y);
parentFolder->Release();
}
return hr;
} else {
/**@todo use parent folder instead of desktop folder
Entry* dir = _up;
ShellPath parent_path;
if (dir)
parent_path = dir->create_absolute_pidl();
else
parent_path = DesktopFolderPath();
ShellPath shell_path = create_relative_pidl(parent_path);
LPCITEMIDLIST pidl = shell_path;
ShellFolder parent_folder = parent_path;
return ShellFolderContextMenu(parent_folder, hwnd, 1, &pidl, pos.x, pos.y);
*/
return ShellFolderContextMenu(GetDesktopFolder(), hwnd, 1, &pidl_abs, pos.x, pos.y);
}
}
HRESULT Entry::GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut)
{
TCHAR path[MAX_PATH];

View file

@ -105,13 +105,14 @@ public:
void smart_scan(SORT_ORDER sortOrder=SORT_NAME, int scan_flags=SCAN_ALL);
void extract_icon();
virtual void read_directory(int scan_flags=SCAN_ALL) {}
virtual const void* get_next_path_component(const void*) const {return NULL;}
virtual Entry* find_entry(const void*) {return NULL;}
virtual bool get_path(PTSTR path) const = 0;
virtual ShellPath create_absolute_pidl() const {return (LPCITEMIDLIST)NULL;}
virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
virtual void read_directory(int scan_flags=SCAN_ALL) {}
virtual const void* get_next_path_component(const void*) const {return NULL;}
virtual Entry* find_entry(const void*) {return NULL;}
virtual bool get_path(PTSTR path) const = 0;
virtual ShellPath create_absolute_pidl() const {return (LPCITEMIDLIST)NULL;}
virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
virtual HRESULT do_context_menu(HWND hwnd, const POINT& pos);
};

View file

@ -496,6 +496,7 @@ LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
HWND hpanel = (HWND) wparam;
POINTS& pos = MAKEPOINTS(lparam);
POINT pt; POINTSTOPOINT(pt, pos);
POINT pt_screen = pt;
ScreenToClient(hpanel, &pt);
SendMessage(hpanel, WM_LBUTTONDOWN, 0, MAKELONG(pt.x, pt.y));
SendMessage(hpanel, WM_LBUTTONUP, 0, MAKELONG(pt.x, pt.y));
@ -506,28 +507,7 @@ LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
if (idx != -1) {
Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx);
ShellPath shell_path = entry->create_absolute_pidl();
LPCITEMIDLIST pidl_abs = shell_path;
if (pidl_abs) {
IShellFolder* parentFolder;
LPCITEMIDLIST pidlLast;
static DynamicFct<HRESULT(WINAPI*)(LPCITEMIDLIST, REFIID, LPVOID*, LPCITEMIDLIST*)> SHBindToParent(TEXT("SHELL32"), "SHBindToParent");
if (SHBindToParent) {
// get and use the parent folder to display correct context menu in all cases -> correct "Properties" dialog for directories, ...
if (SUCCEEDED((*SHBindToParent)(pidl_abs, IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast))) {
HRESULT hr = ShellFolderContextMenu(parentFolder, _hwnd, 1, &pidlLast, pos.x, pos.y);
parentFolder->Release();
CHECKERROR(hr);
}
} else {
CHECKERROR(ShellFolderContextMenu(GetDesktopFolder(), _hwnd, 1, &pidl_abs, pos.x, pos.y));
}
}
CHECKERROR(entry->do_context_menu(_hwnd, pt_screen));
}
break;}

View file

@ -198,32 +198,13 @@ void ShellBrowser::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh)
TreeView_HitTest(_left_hwnd, &tvhti);
if (TVHT_ONITEM & tvhti.flags) {
ClientToScreen(_left_hwnd, &tvhti.pt);
Tree_DoItemMenu(_left_hwnd, tvhti.hItem, &tvhti.pt);
}
}
LPARAM itemData = TreeView_GetItemData(_left_hwnd, tvhti.hItem);
void ShellBrowser::Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen)
{
CONTEXT("ShellBrowser::Tree_DoItemMenu()");
if (itemData) {
Entry* entry = (Entry*)itemData;
ClientToScreen(_left_hwnd, &tvhti.pt);
LPARAM itemData = TreeView_GetItemData(hwndTreeView, hItem);
if (itemData) {
Entry* entry = (Entry*)itemData;
if (entry->_etype == ET_SHELL) {
ShellDirectory* dir = static_cast<ShellDirectory*>(entry->_up);
ShellFolder folder = dir? dir->_folder: GetDesktopFolder();
LPCITEMIDLIST pidl = static_cast<ShellEntry*>(entry)->_pidl;
CHECKERROR(ShellFolderContextMenu(folder, ::GetParent(hwndTreeView), 1, &pidl, pptScreen->x, pptScreen->y));
} else {
ShellPath shell_path = entry->create_absolute_pidl();
LPCITEMIDLIST pidl = shell_path;
///@todo use parent folder instead of desktop
CHECKERROR(ShellFolderContextMenu(GetDesktopFolder(), _hwnd, 1, &pidl, pptScreen->x, pptScreen->y));
CHECKERROR(entry->do_context_menu(_hwnd, tvhti.pt));
}
}
}

View file

@ -132,7 +132,6 @@ struct ShellBrowser : public IShellBrowserImpl
HRESULT OnDefaultCommand(LPIDA pida);
void UpdateFolderView(IShellFolder* folder);
void Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen);
HTREEITEM select_entry(HTREEITEM hitem, Entry* entry, bool expand=true);
protected:

View file

@ -202,6 +202,17 @@ BOOL ShellEntry::launch_entry(HWND hwnd, UINT nCmdShow)
}
HRESULT ShellEntry::do_context_menu(HWND hwnd, LPPOINT pptScreen)
{
ShellDirectory* dir = static_cast<ShellDirectory*>(_up);
ShellFolder folder = dir? dir->_folder: GetDesktopFolder();
LPCITEMIDLIST pidl = _pidl;
return ShellFolderContextMenu(folder, hwnd, 1, &pidl, pptScreen->x, pptScreen->y);
}
HRESULT ShellEntry::GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut)
{
LPCITEMIDLIST pidl = _pidl;

View file

@ -32,12 +32,13 @@ struct ShellEntry : public Entry
ShellEntry(Entry* parent, LPITEMIDLIST shell_path) : Entry(parent, ET_SHELL), _pidl(shell_path) {}
ShellEntry(Entry* parent, const ShellPath& shell_path) : Entry(parent, ET_SHELL), _pidl(shell_path) {}
virtual bool get_path(PTSTR path) const;
virtual ShellPath create_absolute_pidl() const;
virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
virtual bool get_path(PTSTR path) const;
virtual ShellPath create_absolute_pidl() const;
virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
virtual HRESULT do_context_menu(HWND hwnd, LPPOINT pptScreen);
IShellFolder* get_parent_folder() const;
IShellFolder* get_parent_folder() const;
ShellPath _pidl; // parent relative PIDL

View file

@ -132,6 +132,7 @@ void QuickLaunchBar::AddShortcuts()
int cy = HIWORD(size);
RECT rect = {0, 0, cx, cy};
RECT textRect = {0, 0, cx-7, cy-7};
for(int i=0; i<DESKTOP_COUNT; ++i) {
HBITMAP hbmp = CreateCompatibleBitmap(canvas, cx, cy);
HBITMAP hbmp_old = SelectBitmap(hdc, hbmp);
@ -230,7 +231,28 @@ LRESULT QuickLaunchBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
UpdateDesktopButtons(wparam);
break;
default:
case WM_CONTEXTMENU: {
TBBUTTON btn;
QuickLaunchMap::iterator it;
Point pt(lparam), clnt_pt=pt;
ScreenToClient(_hwnd, &clnt_pt);
Entry* entry = NULL;
int idx = SendMessage(_hwnd, TB_HITTEST, 0, (LPARAM)&clnt_pt);
if (idx>=0 &&
SendMessage(_hwnd, TB_GETBUTTON, idx, (LPARAM)&btn)!=-1 &&
(it=_entries.find(btn.idCommand))!=_entries.end()) {
entry = it->second._entry;
}
if (entry) // entry is NULL for desktop switch buttons
CHECKERROR(entry->do_context_menu(_hwnd, pt));
else
goto def;
break;}
default: def:
return super::WndProc(nmsg, wparam, lparam);
}

View file

@ -216,14 +216,16 @@ void NotifyArea::read_config()
#endif
{
if (pos.go_down("desktopbar")) {
clock_visible = XMLBoolRef(pos, "options", "show-clock", !get_hide_clock_from_registry());
clock_visible = XMLBoolRef(XMLPos(pos,"options"), "show-clock", !get_hide_clock_from_registry());
pos.back();
}
}
if (pos.go_down("notify-icons")) {
_hide_inactive = XMLBool(pos, "options", "hide-inactive", true); ///@todo read default setting from registry
_show_hidden = XMLBool(pos, "options", "show-hidden", false); ///@todo read default setting from registry
XMLPos options(pos, "options");
_hide_inactive = XMLBool(options, "hide-inactive", true); ///@todo read default setting from registry
_show_hidden = XMLBool(options, "show-hidden", false); ///@todo read default setting from registry
XMLChildrenFilter icons(pos, "icon");
@ -260,13 +262,14 @@ void NotifyArea::write_config()
XMLPos pos = g_Globals.get_cfg();
pos.smart_create("desktopbar");
XMLBoolRef(pos, "options", "show-clock") = _hwndClock!=0;
XMLBoolRef(XMLPos(pos,"options"), "show-clock") = _hwndClock!=0;
pos.back();
pos.smart_create("notify-icons");
XMLBoolRef(pos, "options", "hide-inactive") = _hide_inactive;
XMLBoolRef(pos, "options", "show-hidden") = _show_hidden;
XMLPos options(pos, "options");
XMLBoolRef(options, "hide-inactive") = _hide_inactive;
XMLBoolRef(options, "show-hidden") = _show_hidden;
for(NotifyIconCfgList::iterator it=_cfg.begin(); it!=_cfg.end(); ++it) {
NotifyIconConfig& cfg = *it;
@ -285,6 +288,8 @@ void NotifyArea::write_config()
pos.back();
}
pos.back(); // smart_create
}
void NotifyArea::show_clock(bool flag)

View file

@ -81,7 +81,7 @@ HRESULT STDMETHODCALLTYPE IShellBrowserImpl::QueryService(REFGUID guidService, R
return S_OK;
}
HRESULT STDMETHODCALLTYPE IShellBrowserImpl::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT* pCmdText)
HRESULT STDMETHODCALLTYPE IShellBrowserImpl::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT* pCmdText)
{
return E_FAIL; ///@todo implement IOleCommandTarget
}

View file

@ -343,7 +343,28 @@ struct XMLNode : public String
#else
typedef std::map<String, String> AttributeMap;
#endif
typedef std::list<XMLNode*> Children;
struct Children : public std::list<XMLNode*>
{
void assign(const Children& other)
{
clear();
for(Children::const_iterator it=other.begin(); it!=other.end(); ++it)
push_back(new XMLNode(**it));
}
void clear()
{
while(!empty()) {
XMLNode* node = back();
pop_back();
node->clear();
delete node;
}
}
};
// access to protected class members for XMLPos and XMLReader
friend struct XMLPos;
@ -388,24 +409,14 @@ struct XMLNode : public String
_trailing.erase();
_attributes.clear();
while(!_children.empty()) {
XMLNode* node = _children.back();
_children.pop_back();
node->clear();
delete node;
}
_children.clear();
String::erase();
}
XMLNode& operator=(const XMLNode& other)
{
_children.clear();
for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it)
_children.push_back(new XMLNode(**it));
_children.assign(other._children);
_attributes = other._attributes;
@ -424,6 +435,12 @@ struct XMLNode : public String
}
/// write access to an attribute
void put(const String& attr_name, const String& value)
{
_attributes[attr_name] = value;
}
/// C++ write access to an attribute
String& operator[](const String& attr_name)
{
return _attributes[attr_name];
@ -441,7 +458,7 @@ struct XMLNode : public String
}
/// convenient value access in children node
String value(const String& name, const String& attr_name) const
String subvalue(const String& name, const String& attr_name) const
{
const XMLNode* node = find_first(name);
@ -452,7 +469,7 @@ struct XMLNode : public String
}
/// convenient storage of distinct values in children node
String& value(const String& name, const String& attr_name)
String& subvalue(const String& name, const String& attr_name)
{
XMLNode* node = find_first(name);
@ -466,7 +483,7 @@ struct XMLNode : public String
#ifdef UNICODE
/// convenient value access in children node
String value(const char* name, const char* attr_name) const
String subvalue(const char* name, const char* attr_name) const
{
const XMLNode* node = find_first(name);
@ -477,7 +494,7 @@ struct XMLNode : public String
}
/// convenient storage of distinct values in children node
String& value(const char* name, const String& attr_name)
String& subvalue(const char* name, const String& attr_name)
{
XMLNode* node = find_first(name);
@ -813,7 +830,46 @@ struct XMLPos
{ // don't copy _stack
}
XMLPos(XMLNode* node, const String& name)
: _root(node),
_cur(node)
{
smart_create(name);
}
XMLPos(XMLNode* node, const String& name, const String& attr_name, const String& attr_value)
: _root(node),
_cur(node)
{
smart_create(name, attr_name, attr_value);
}
XMLPos(const XMLPos& other, const String& name)
: _root(other._root),
_cur(other._cur)
{
smart_create(name);
}
XMLPos(const XMLPos& other, const String& name, const String& attr_name, const String& attr_value)
: _root(other._root),
_cur(other._cur)
{
smart_create(name, attr_name, attr_value);
}
/// access to current node
XMLNode& cur()
{
return *_cur;
}
const XMLNode& cur() const
{
return *_cur;
}
/// C++ access to current node
operator const XMLNode*() const {return _cur;}
operator XMLNode*() {return _cur;}
@ -824,6 +880,17 @@ struct XMLPos
XMLNode& operator*() {return *_cur;}
/// attribute access
String get(const String& attr_name) const
{
return _cur->get(attr_name);
}
void put(const String& attr_name, const String& value)
{
_cur->put(attr_name, value);
}
/// C++ attribute access
template<typename T> String get(const T& attr_name) const {return (*_cur)[attr_name];}
String& operator[](const String& attr_name) {return (*_cur)[attr_name];}
@ -897,7 +964,7 @@ struct XMLPos
if (node)
go_to(node);
else {
XMLNode* node = new XMLNode(name);
node = new XMLNode(name);
add_down(node);
(*node)[attr_name] = attr_value;
}
@ -982,6 +1049,12 @@ struct const_XMLPos
}
/// access to current node
const XMLNode& cur() const
{
return *_cur;
}
/// C++ access to current node
operator const XMLNode*() const {return _cur;}
const XMLNode* operator->() const {return _cur;}
@ -989,6 +1062,12 @@ struct const_XMLPos
const XMLNode& operator*() const {return *_cur;}
/// attribute access
String get(const String& attr_name) const
{
return _cur->get(attr_name);
}
/// C++ attribute access
template<typename T> String get(const T& attr_name) const {return _cur->get(attr_name);}
/// go back to previous position
@ -1069,7 +1148,7 @@ struct XMLBool
XMLBool(LPCTSTR value, bool def=false)
{
if (value && *value)
_value = !_tcsicmp(value, TEXT("TRUE"));
_value = !_tcsicmp(value, TEXT("true"));
else
_value = def;
}
@ -1079,17 +1158,7 @@ struct XMLBool
const String& value = node->get(attr_name);
if (!value.empty())
_value = !_tcsicmp(value, TEXT("TRUE"));
else
_value = def;
}
XMLBool(const XMLNode* node, const String& name, const String& attr_name, bool def=false)
{
const String& value = node->value(name, attr_name);
if (!value.empty())
_value = !_tcsicmp(value, TEXT("TRUE"));
_value = !_tcsicmp(value, TEXT("true"));
else
_value = def;
}
@ -1106,7 +1175,7 @@ struct XMLBool
operator LPCTSTR() const
{
return _value? TEXT("TRUE"): TEXT("FALSE");
return _value? TEXT("true"): TEXT("false");
}
protected:
@ -1118,8 +1187,8 @@ private:
struct XMLBoolRef
{
XMLBoolRef(XMLNode* node, const String& name, const String& attr_name, bool def=false)
: _ref(node->value(name, attr_name))
XMLBoolRef(XMLNode* node, const String& attr_name, bool def=false)
: _ref((*node)[attr_name])
{
if (_ref.empty())
assign(def);
@ -1127,12 +1196,12 @@ struct XMLBoolRef
operator bool() const
{
return !_tcsicmp(_ref, TEXT("TRUE"));
return !_tcsicmp(_ref, TEXT("true"));
}
bool operator!() const
{
return _tcsicmp(_ref, TEXT("TRUE"))? true: false;
return _tcsicmp(_ref, TEXT("true"))? true: false;
}
XMLBoolRef& operator=(bool value)
@ -1144,7 +1213,7 @@ struct XMLBoolRef
void assign(bool value)
{
_ref.assign(value? TEXT("TRUE"): TEXT("FALSE"));
_ref.assign(value? TEXT("true"): TEXT("false"));
}
void toggle()
@ -1182,16 +1251,6 @@ struct XMLInt
_value = def;
}
XMLInt(const XMLNode* node, const String& name, const String& attr_name, int def=0)
{
const String& value = node->value(name, attr_name);
if (!value.empty())
_value = _ttoi(value);
else
_value = def;
}
operator int() const
{
return _value;
@ -1213,8 +1272,8 @@ private:
struct XMLIntRef
{
XMLIntRef(XMLNode* node, const String& name, const String& attr_name, int def=0)
: _ref(node->value(name, attr_name))
XMLIntRef(XMLNode* node, const String& attr_name, int def=0)
: _ref((*node)[attr_name])
{
if (_ref.empty())
assign(def);
@ -1270,16 +1329,6 @@ struct XMLString
_value = def;
}
XMLString(const XMLNode* node, const String& name, const String& attr_name, LPCTSTR def=TEXT(""))
{
const String& value = node->value(name, attr_name);
if (!value.empty())
_value = value;
else
_value = def;
}
operator const String&() const
{
return _value;
@ -1299,8 +1348,15 @@ private:
struct XMStringRef
{
XMStringRef(XMLNode* node, const String& name, const String& attr_name, LPCTSTR def=TEXT(""))
: _ref(node->value(name, attr_name))
XMStringRef(XMLNode* node, const String& attr_name, LPCTSTR def=TEXT(""))
: _ref((*node)[attr_name])
{
if (_ref.empty())
assign(def);
}
XMStringRef(XMLNode* node, const String& node_name, const String& attr_name, LPCTSTR def=TEXT(""))
: _ref(node->subvalue(node_name, attr_name))
{
if (_ref.empty())
assign(def);
@ -1351,7 +1407,7 @@ template<>
#pragma warning(disable: 4355)
#endif
/// XML file reader
/// XML reader base class
struct XMLReaderBase
{
XMLReaderBase(XMLNode* node)
@ -1405,6 +1461,7 @@ protected:
};
/// XML file reader
struct XMLReader : public XMLReaderBase
{
XMLReader(XMLNode* node, std::istream& in)
@ -1429,7 +1486,7 @@ protected:
};
struct XMLHeader : public std::string
struct XMLHeader
{
XMLHeader(const std::string& xml_version="1.0", const std::string& encoding="UTF-8", const std::string& doctype="")
: _version(xml_version),
@ -1446,9 +1503,9 @@ struct XMLHeader : public std::string
out << _doctype << '\n';
}
std::string _version;
std::string _encoding;
std::string _doctype;
std::string _version;
std::string _encoding;
std::string _doctype;
};
@ -1548,7 +1605,7 @@ struct XMLDoc : public XMLNode
}
XML_Error _last_error;
std::string _last_error_msg;
std::string _last_error_msg;
};