← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2915: Remove ADC_DEBUG, add in a DebugFrame based off of BigMuscles implementation in StrongDC

 

------------------------------------------------------------
revno: 2915
committer: iceman50 <bdcdevel@xxxxxxxxx>
branch nick: dcplusplus
timestamp: Thu 2012-05-10 03:01:35 -0500
message:
  Remove ADC_DEBUG, add in a DebugFrame based off of BigMuscles implementation in StrongDC
added:
  dcpp/DebugManager.h
  win32/DebugFrame.cpp
  win32/DebugFrame.h
modified:
  dcpp/AdcHub.cpp
  dcpp/Client.cpp
  dcpp/DCPlusPlus.cpp
  dcpp/SettingsManager.cpp
  dcpp/UserConnection.cpp
  dwt/include/dwt/widgets/ComboBox.h
  dwt/src/widgets/ComboBox.cpp
  win32/MainWindow.cpp


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'dcpp/AdcHub.cpp'
--- dcpp/AdcHub.cpp	2012-04-17 17:59:40 +0000
+++ dcpp/AdcHub.cpp	2012-05-10 08:01:35 +0000
@@ -1093,9 +1093,6 @@
 		return;
 	}
 
-	if(BOOLSETTING(ADC_DEBUG)) {
-		fire(ClientListener::StatusMessage(), this, "<ADC>" + aLine + "</ADC>");
-	}
 	dispatch(aLine);
 }
 

=== modified file 'dcpp/Client.cpp'
--- dcpp/Client.cpp	2012-01-13 20:55:20 +0000
+++ dcpp/Client.cpp	2012-05-10 08:01:35 +0000
@@ -22,6 +22,7 @@
 #include "BufferedSocket.h"
 #include "ClientManager.h"
 #include "ConnectivityManager.h"
+#include "DebugManager.h"
 #include "FavoriteManager.h"
 #include "TimerManager.h"
 #include "UserMatchManager.h"
@@ -121,6 +122,7 @@
 	}
 	updateActivity();
 	sock->write(aMessage, aLen);
+	COMMAND_DEBUG(aMessage, DebugManager::HUB_OUT, getIpPort());
 }
 
 void Client::on(Connected) noexcept {
@@ -227,8 +229,9 @@
 	fire(ClientListener::UsersUpdated(), this, users);
 }
 
-void Client::on(Line, const string& /*aLine*/) noexcept {
+void Client::on(Line, const string& aLine) noexcept {
 	updateActivity();
+	COMMAND_DEBUG(aLine, DebugManager::HUB_IN, getIpPort());
 }
 
 void Client::on(Second, uint64_t aTick) noexcept {

=== modified file 'dcpp/DCPlusPlus.cpp'
--- dcpp/DCPlusPlus.cpp	2012-01-13 20:55:20 +0000
+++ dcpp/DCPlusPlus.cpp	2012-05-10 08:01:35 +0000
@@ -24,6 +24,7 @@
 #include "ConnectionManager.h"
 #include "ConnectivityManager.h"
 #include "CryptoManager.h"
+#include "DebugManager.h"
 #include "DownloadManager.h"
 #include "FavoriteManager.h"
 #include "FinishedManager.h"
@@ -82,6 +83,7 @@
 	GeoManager::newInstance();
 	UserMatchManager::newInstance();
 	WindowManager::newInstance();
+	DebugManager::newInstance();
 
 	SettingsManager::getInstance()->load();
 
@@ -136,6 +138,7 @@
 	ClientManager::getInstance()->saveUsers();
 	SettingsManager::getInstance()->save();
 
+	DebugManager::deleteInstance();
 	WindowManager::deleteInstance();
 	UserMatchManager::deleteInstance();
 	GeoManager::deleteInstance();

=== added file 'dcpp/DebugManager.h'
--- dcpp/DebugManager.h	1970-01-01 00:00:00 +0000
+++ dcpp/DebugManager.h	2012-05-10 08:01:35 +0000
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2001-2012 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#if !defined DCPLUSPLUS_DCPP_DEBUGMANAGER_H
+#define DCPLUSPLUS_DCPP_DEBUGMANAGER_H
+
+#pragma once
+
+#include "DCPlusPlus.h"
+#include "Singleton.h"
+#include "TimerManager.h"
+
+namespace dcpp {
+
+class DebugManagerListener {
+public:
+template<int I>	struct X { enum { TYPE = I };  };
+
+	typedef X<0> DebugCommand;
+
+	virtual void on(DebugCommand, const string&, int, const string&) noexcept { }
+
+};
+
+class DebugManager : public Singleton<DebugManager>, public Speaker<DebugManagerListener>
+{
+	friend class Singleton<DebugManager>;
+	DebugManager() { };
+public:
+	void SendCommandMessage(const string& mess, int cmdType, const string& ip) {
+		fire(DebugManagerListener::DebugCommand(), mess, cmdType, ip);
+	}
+	~DebugManager() { };
+	enum {
+		HUB_IN, HUB_OUT, CLIENT_IN, CLIENT_OUT
+	};
+};
+#define COMMAND_DEBUG(a,b,c) DebugManager::getInstance()->SendCommandMessage(a,b,c);
+
+} // namespace dcpp
+
+#endif // !defined(DEBUG_MANAGER_H)

=== modified file 'dcpp/SettingsManager.cpp'
--- dcpp/SettingsManager.cpp	2012-03-11 18:06:18 +0000
+++ dcpp/SettingsManager.cpp	2012-05-10 08:01:35 +0000
@@ -73,7 +73,7 @@
 	"ShowToolbar", "ShowTransferview", "PopunderPm", "PopunderFilelist", "MagnetAsk", "MagnetAction", "MagnetRegister",
 	"AddFinishedInstantly", "DontDLAlreadyShared", "UseCTRLForLineHistory",
 	"OpenNewWindow", "UDPPort", "HubLastLogLines", "PMLastLogLines",
-	"AdcDebug", "ToggleActiveTab", "SearchHistory", "SetMinislotSize", "MaxFilelistSize",
+	"ToggleActiveTab", "SearchHistory", "SetMinislotSize", "MaxFilelistSize",
 	"HighestPrioSize", "HighPrioSize", "NormalPrioSize", "LowPrioSize", "LowestPrio",
 	"AutoDropSpeed", "AutoDropInterval", "AutoDropElapsed", "AutoDropInactivity", "AutoDropMinSources", "AutoDropFilesize",
 	"AutoDropAll", "AutoDropFilelists", "AutoDropDisconnect",
@@ -239,7 +239,6 @@
 	setDefault(JOIN_OPEN_NEW_WINDOW, false);
 	setDefault(HUB_LAST_LOG_LINES, 10);
 	setDefault(PM_LAST_LOG_LINES, 10);
-	setDefault(ADC_DEBUG, false);
 	setDefault(TOGGLE_ACTIVE_WINDOW, false);
 	setDefault(SEARCH_HISTORY, 10);
 	setDefault(SET_MINISLOT_SIZE, 64);

=== modified file 'dcpp/UserConnection.cpp'
--- dcpp/UserConnection.cpp	2012-03-03 19:33:45 +0000
+++ dcpp/UserConnection.cpp	2012-05-10 08:01:35 +0000
@@ -26,6 +26,7 @@
 #include "Transfer.h"
 #include "format.h"
 #include "SettingsManager.h"
+#include "DebugManager.h"
 
 namespace dcpp {
 
@@ -47,6 +48,8 @@
 
 void UserConnection::on(BufferedSocketListener::Line, const string& aLine) noexcept {
 
+	COMMAND_DEBUG(aLine, DebugManager::CLIENT_IN, getRemoteIp());
+
 	if(aLine.length() < 2) {
 		fire(UserConnectionListener::ProtocolError(), this, _("Invalid data"));
 		return;
@@ -261,6 +264,7 @@
 
 void UserConnection::send(const string& aString) {
 	lastActivity = GET_TICK();
+	COMMAND_DEBUG(aString, DebugManager::CLIENT_OUT, getRemoteIp());
 	socket->write(aString);
 }
 

=== modified file 'dwt/include/dwt/widgets/ComboBox.h'
--- dwt/include/dwt/widgets/ComboBox.h	2012-01-13 20:55:20 +0000
+++ dwt/include/dwt/widgets/ComboBox.h	2012-05-10 08:01:35 +0000
@@ -110,6 +110,11 @@
 	  */
 	tstring getValue( int index );
 
+	/** Finds the first string in a combo box list that exactly matches the specified string,
+	 * except that the search is not case sensitive.
+	 */
+	int findString(const tstring& text);
+
 	/// Actually creates the ComboBox Control
 	/** You should call WidgetFactory::createComboBox if you instantiate class
 	  * directly. <br>

=== modified file 'dwt/src/widgets/ComboBox.cpp'
--- dwt/src/widgets/ComboBox.cpp	2012-01-13 20:55:20 +0000
+++ dwt/src/widgets/ComboBox.cpp	2012-05-10 08:01:35 +0000
@@ -62,6 +62,10 @@
 	return retVal;
 }
 
+int ComboBox::findString(const tstring& text) {
+	return ComboBox_FindStringExact(handle(), -1, text.c_str()); 
+}
+
 Point ComboBox::getPreferredSize() {
 	// Pixels between text and arrow
 	const int MARGIN = 2;

=== added file 'win32/DebugFrame.cpp'
--- win32/DebugFrame.cpp	1970-01-01 00:00:00 +0000
+++ win32/DebugFrame.cpp	2012-05-10 08:01:35 +0000
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2001-2012 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+ 
+#include "stdafx.h"
+
+#include "DebugFrame.h"
+
+#include <dcpp/ClientManager.h>
+#include <dcpp/File.h>
+
+#include <dwt/widgets/Grid.h>
+#include <dwt/widgets/Button.h>
+
+#include "HoldRedraw.h"
+#include "ShellMenu.h"
+#include "WinUtil.h"
+
+#define IDH_DEBUG_FRAME 0
+
+using dwt::Grid;
+using dwt::GridInfo;
+
+
+const string DebugFrame::id = "DebugMessages";
+const string& DebugFrame::getId() const { return id; }
+
+DebugFrame::DebugFrame(TabViewPtr parent) :
+BaseType(parent, T_("Debug Messages"), IDH_DEBUG_FRAME, IDI_DCPP, false),
+grid(0),
+debug(0),
+clientMsg(0),
+showClientMsg(true),
+hubMsg(0),
+showHubMsg(true),
+filterHub(0),
+filterByHub(false),
+hubs(0)
+{
+	grid = addChild(Grid::Seed(2, 5));
+	grid->column(0).mode = GridInfo::FILL;
+	grid->column(1).mode = GridInfo::FILL;
+	grid->column(2).mode = GridInfo::FILL;
+	grid->column(3).mode = GridInfo::FILL;
+	grid->column(4).mode = GridInfo::FILL;
+	grid->row(0).mode = GridInfo::FILL;
+	grid->row(0).align = GridInfo::STRETCH;
+
+	{
+		TextBox::Seed seed = WinUtil::Seeds::textBox;
+		seed.style |= WS_VSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | ES_NOHIDESEL | ES_READONLY | ES_SUNKEN;
+		debug = grid->addChild(seed);
+		grid->setWidget(debug, 0, 0, 1, 5);
+		debug->setTextLimit(1024*64*5);
+		addWidget(debug);
+
+		debug->onKeyDown([this](int c) { return handleKeyDown(c); });
+	}
+	
+	{
+		ButtonPtr button;
+		Button::Seed cs = WinUtil::Seeds::button;
+		
+		cs.caption = T_("&Clear");
+		button = grid->addChild(cs);
+		button->onClicked([this] { clearMessages(); });
+		addWidget(button);
+		
+		CheckBox::Seed cb = WinUtil::Seeds::checkBox;
+		
+		cb.caption = T_("Show client messages");
+		clientMsg = grid->addChild(cb);
+		clientMsg->setChecked(showClientMsg);
+		clientMsg->onClicked([this] { handleClientMsg(); });
+		
+		cb.caption = T_("Show hub messages");
+		hubMsg = grid->addChild(cb);
+		hubMsg->setChecked(showHubMsg);
+		hubMsg->onClicked([this] { handleHubMsg(); });
+		
+		cb.caption = T_("Filter by hub");
+		filterHub = grid->addChild(cb);
+		filterHub->setChecked(filterByHub);
+		filterHub->onClicked([this] { handleFilterHub(); });
+
+		ComboBox::Seed cbSeed = WinUtil::Seeds::comboBox;
+		hubs = grid->addChild(cbSeed);
+		addWidget(hubs);
+
+	}
+
+	initStatus();
+
+	layout();
+	activate();
+
+	ClientManager* clientMgr = ClientManager::getInstance();
+	{
+		auto lock = clientMgr->lock();
+		clientMgr->addListener(this);
+		auto& clients = clientMgr->getClients();
+		for(auto it = clients.begin(); it != clients.end(); ++it) {
+			Client* client = *it;
+			if(!client->isConnected())
+				continue;
+
+			onHubAdded(new HubInfo(client));
+		}
+	}
+	
+	updateStatus();
+	
+	start();
+	DebugManager::getInstance()->addListener(this);	
+}
+
+DebugFrame::~DebugFrame() {
+}
+
+void DebugFrame::layout() {
+	dwt::Rectangle r(this->getClientSize());
+
+	r.size.y -= status->refresh();
+
+	grid->resize(r);	
+}
+
+void DebugFrame::updateStatus() {	
+	
+	if(showClientMsg) {
+		status->setText(STATUS_CLIENT, T_("Showing client debug messages"));
+    } else {
+		status->setText(STATUS_CLIENT, T_("Client debug messages are disabled"));
+	}
+
+	if(showHubMsg) {
+		status->setText(STATUS_HUB, T_("Showing hub debug messages"));
+	} else {
+		status->setText(STATUS_HUB, T_("Hub debug messages are disabled"));
+	}
+	
+	if(filterByHub) {
+		status->setText(STATUS_HUB_ADDRESS, T_("Hub address filtering is enabled"));
+	} else {
+		status->setText(STATUS_HUB_ADDRESS, T_("Hub address filtering is disabled"));
+	}
+}
+
+void DebugFrame::addLine(const tstring& msg) {
+	bool scroll = debug->scrollIsAtEnd();
+
+	debug->addText(Text::toT("\r\n[" + Util::getTimeString() + "] ") + msg);
+
+	if(scroll)
+		debug->scrollToBottom();
+
+	setDirty(SettingsManager::BOLD_SYSTEM_LOG);
+}
+
+bool DebugFrame::preClosing() {
+	ClientManager::getInstance()->removeListener(this);
+	DebugManager::getInstance()->removeListener(this);	
+	
+	stop = true;
+	s.signal();
+		
+	return true;
+}
+
+void DebugFrame::clearMessages() { 
+	debug->setSelection();
+	debug->replaceSelection(_T(""));
+}
+
+void DebugFrame::handleClientMsg() {
+	showClientMsg = clientMsg->getChecked();
+	updateStatus();
+}
+
+void DebugFrame::handleHubMsg() {
+	showHubMsg = hubMsg->getChecked();
+	updateStatus();
+}
+
+void DebugFrame::handleFilterHub() {
+	filterByHub = filterHub->getChecked();
+	updateStatus();	
+}
+
+bool DebugFrame::handleKeyDown(int c) {
+	switch(c) {
+	case VK_DELETE:
+		clearMessages();
+		return true;
+	}
+	return false;
+}
+
+void DebugFrame::on(ClientConnected, Client* c) noexcept {
+	auto hi = new HubInfo(c);
+	callAsync([=] { onHubAdded(hi); });
+}
+
+void DebugFrame::on(ClientDisconnected, Client* c) noexcept {
+	auto hi = new HubInfo(c);
+	callAsync([=] { onHubRemoved(hi); });
+}
+
+void DebugFrame::onHubAdded(HubInfo* info) {
+	hubs->addValue(info->ip);
+}
+
+void DebugFrame::onHubRemoved(HubInfo* info) {
+	auto idx = hubs->findString(info->ip);
+	hubs->erase(idx);
+}
+
+void DebugFrame::on(DebugCommand, const string& message) noexcept {
+	callAsync([=] { addLine(Text::toT(message)); });
+}

=== added file 'win32/DebugFrame.h'
--- win32/DebugFrame.h	1970-01-01 00:00:00 +0000
+++ win32/DebugFrame.h	2012-05-10 08:01:35 +0000
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2001-2012 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef DCPLUSPLUS_WIN32_DEBUG_FRAME_H
+#define DCPLUSPLUS_WIN32_DEBUG_FRAME_H
+
+#include <dcpp/Client.h>
+#include <dcpp/ClientManagerListener.h>
+#include <dcpp/DebugManager.h>
+#include <dcpp/Semaphore.h>
+
+#include <deque>
+
+#include "StaticFrame.h"
+
+using std::deque;
+
+class DebugFrame : public StaticFrame<DebugFrame>, public Thread,
+	private DebugManagerListener,
+	private ClientManagerListener
+{
+	typedef StaticFrame<DebugFrame> BaseType;
+public:
+	enum Status {
+		STATUS_STATUS,
+		STATUS_CLIENT,		
+		STATUS_HUB,
+		STATUS_HUB_ADDRESS,
+		STATUS_LAST
+	};
+	
+	static const string id;
+	const string& getId() const;
+	
+	void addLine(const tstring& msg);
+
+private:
+	bool stop;
+	CriticalSection cs;
+	Semaphore s;
+	deque<string> cmdList;
+
+	int run() {
+		setThreadPriority(Thread::LOW);
+		string x = Util::emptyString;
+		stop = false;
+
+		while(true) {
+			s.wait();
+			if(stop)
+				break;
+
+			{
+				Lock l(cs);
+				if(cmdList.empty()) continue;
+
+				x = cmdList.front();
+				cmdList.pop_front();
+			}
+			addLine(Text::toT(x));
+		}
+		
+		stop = false;
+		return 0;
+	}
+
+	void addDbgLine(const string& cmd) {
+		{
+			Lock l(cs);
+			cmdList.push_back(cmd);
+		}
+		s.signal();
+	}
+
+	struct HubInfo : public FastAlloc<HubInfo> {
+		HubInfo(const tstring& aIp) : ip(aIp) { }
+		HubInfo(Client* client) : ip(Text::toT(client->getIpPort())) { }
+
+		tstring ip;
+	};
+
+	friend class StaticFrame<DebugFrame>;
+	friend class MDIChildFrame<DebugFrame>;
+
+	GridPtr grid;
+	
+	TextBoxPtr debug;
+	
+	CheckBoxPtr clientMsg, hubMsg, filterHub;
+	bool showClientMsg, showHubMsg, filterByHub;
+
+	ComboBoxPtr hubs;
+	
+	DebugFrame(TabViewPtr parent);
+	virtual ~DebugFrame();
+
+	void layout();
+	void updateStatus();
+	bool preClosing();
+	
+	void clearMessages();
+	void handleClientMsg();
+	void handleHubMsg();
+	void handleFilterHub();
+
+	bool handleKeyDown(int c);
+	
+	void on(DebugManagerListener::DebugCommand, const string& aLine, int cmdType, const string& ip) throw() {
+			auto url = hubs->getText();
+			switch(cmdType) {
+				case DebugManager::HUB_IN:
+						if(!showHubMsg)
+							return;
+						if(!filterByHub || Text::toT(ip) == url) {
+							addDbgLine("From Hub:\t\t<" + ip + ">\t \t" + aLine);
+						}
+					break;
+				case DebugManager::HUB_OUT:
+						if(!showHubMsg)
+							return;
+						if(!filterByHub || Text::toT(ip) == url) {
+							addDbgLine("To Hub:\t\t<" + ip + ">\t \t" + aLine);
+						}
+					break;
+				case DebugManager::CLIENT_IN:
+						if(!showClientMsg)
+							return;
+						if(!filterByHub || Text::toT(ip) == url) {
+							addDbgLine("From Client:\t\t<" + ip + ">\t \t" + aLine);
+						}
+					break;
+				case DebugManager::CLIENT_OUT:
+						if(!showClientMsg)
+							return;
+						if(!filterByHub || Text::toT(ip) == url) {
+							addDbgLine("To Client:\t\t<" + ip + ">\t \t" + aLine);
+						}
+					break;
+				default: dcassert(0);
+			}
+	}
+
+	// ClientManagerListener
+	virtual void on(ClientConnected, Client* c) noexcept;
+	virtual void on(ClientDisconnected, Client* c) noexcept;
+
+	void onHubAdded(HubInfo* info);
+	void onHubRemoved(HubInfo* info);
+
+	// DebugManagerListener
+	virtual void on(DebugCommand, const string& message) noexcept;
+
+};
+
+#endif

=== modified file 'win32/MainWindow.cpp'
--- win32/MainWindow.cpp	2012-04-30 16:31:37 +0000
+++ win32/MainWindow.cpp	2012-05-10 08:01:35 +0000
@@ -78,6 +78,7 @@
 #include "StatsFrame.h"
 #include "SystemFrame.h"
 #include "UsersFrame.h"
+#include "DebugFrame.h"
 
 #ifdef HAVE_HTMLHELP_H
 #include <htmlhelp.h>
@@ -332,6 +333,8 @@
 			[this] { NotepadFrame::openWindow(getTabView()); }, WinUtil::menuIcon(IDI_NOTEPAD));
 		viewIndexes[SystemFrame::id] = viewMenu->appendItem(T_("System Log"),
 			[this] { SystemFrame::openWindow(getTabView()); });
+		viewIndexes[DebugFrame::id] = viewMenu->appendItem(T_("Debug Messages"),
+			[this] { DebugFrame::openWindow(getTabView()); }, WinUtil::menuIcon(IDI_DCPP));
 		viewIndexes[StatsFrame::id] = viewMenu->appendItem(T_("Network Statistics"),
 			[this] { StatsFrame::openWindow(getTabView()); }, WinUtil::menuIcon(IDI_NET_STATS));
 		viewMenu->appendItem(T_("Indexing progress"), [this] { handleHashProgress(); }, WinUtil::menuIcon(IDI_INDEXING));