📄 mainfrm.cpp
字号:
/*
* Copyright (C) 2001-2006 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 "../client/DCPlusPlus.h"
#include "Resource.h"
#include "MainFrm.h"
#include "AboutDlg.h"
#include "HubFrame.h"
#include "SearchFrm.h"
#include "PublicHubsFrm.h"
#include "PropertiesDlg.h"
#include "UsersFrame.h"
#include "DirectoryListingFrm.h"
#include "FavoritesFrm.h"
#include "NotepadFrame.h"
#include "QueueFrame.h"
#include "SpyFrame.h"
#include "FinishedFrame.h"
#include "ADLSearchFrame.h"
#include "FinishedULFrame.h"
#include "TextFrame.h"
#include "StatsFrame.h"
#include "WaitingUsersFrame.h"
#include "LineDlg.h"
#include "HashProgressDlg.h"
#include "UPnP.h"
#include "SystemFrame.h"
#include "PrivateFrame.h"
#include "../client/ConnectionManager.h"
#include "../client/DownloadManager.h"
#include "../client/UploadManager.h"
#include "../client/StringTokenizer.h"
#include "../client/SimpleXML.h"
#include "../client/ShareManager.h"
#include "../client/version.h"
MainFrame::MainFrame() : trayMessage(0), trayIcon(false), maximized(false), lastUpload(-1), lastUpdate(0),
lastUp(0), lastDown(0), oldshutdown(false), stopperThread(NULL), c(new HttpConnection()),
closing(false), missedAutoConnect(false), UPnP_TCPConnection(NULL), UPnP_UDPConnection(NULL)
{
memset(statusSizes, 0, sizeof(statusSizes));
links.homepage = _T("http://dcpp.net/");
links.downloads = links.homepage + _T("download/");
links.geoipfile = _T("http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip");
links.translations = _T("http://sourceforge.net/tracker/?atid=460289&group_id=40287");
links.faq = links.homepage + _T("faq/");
links.help = links.homepage + _T("forum/");
links.discuss = links.homepage + _T("forum/");
links.features = links.homepage + _T("bugzilla/");
links.bugs = links.homepage + _T("bugzilla/");
}
MainFrame::~MainFrame() {
m_CmdBar.m_hImageList = NULL;
images.Destroy();
largeImages.Destroy();
largeImagesHot.Destroy();
WinUtil::uninit();
}
DWORD WINAPI MainFrame::stopper(void* p) {
MainFrame* mf = (MainFrame*)p;
HWND wnd, wnd2 = NULL;
while( (wnd=::GetWindow(mf->m_hWndMDIClient, GW_CHILD)) != NULL) {
if(wnd == wnd2)
Sleep(100);
else {
::PostMessage(wnd, WM_CLOSE, 0, 0);
wnd2 = wnd;
}
}
mf->PostMessage(WM_CLOSE);
return 0;
}
LRESULT MainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) {
TimerManager::getInstance()->addListener(this);
QueueManager::getInstance()->addListener(this);
LogManager::getInstance()->addListener(this);
WinUtil::init(m_hWnd);
//trayMessage = RegisterWindowMessage(_T("TaskbarCreated"));
// Use ASCII version as opencow doesn't support the wide one...
trayMessage = RegisterWindowMessageA("TaskbarCreated");
TimerManager::getInstance()->start();
// Set window name
SetWindowText(_T(APPNAME) _T(" ") _T(VERSIONSTRING));
// Load images
// create command bar window
HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE);
m_hMenu = WinUtil::mainMenu;
// attach menu
m_CmdBar.AttachMenu(m_hMenu);
// load command bar images
images.CreateFromImage(IDB_TOOLBAR, 16, 16, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_SHARED);
m_CmdBar.m_hImageList = images;
m_CmdBar.m_arrCommand.Add(ID_FILE_CONNECT);
m_CmdBar.m_arrCommand.Add(ID_FILE_RECONNECT);
m_CmdBar.m_arrCommand.Add(IDC_FOLLOW);
m_CmdBar.m_arrCommand.Add(IDC_FAVORITES);
m_CmdBar.m_arrCommand.Add(IDC_FAVUSERS);
m_CmdBar.m_arrCommand.Add(IDC_QUEUE);
m_CmdBar.m_arrCommand.Add(IDC_FINISHED);
m_CmdBar.m_arrCommand.Add(IDC_VIEW_WAITING_USERS);
m_CmdBar.m_arrCommand.Add(IDC_FINISHED_UL);
m_CmdBar.m_arrCommand.Add(ID_FILE_SEARCH);
m_CmdBar.m_arrCommand.Add(IDC_FILE_ADL_SEARCH);
m_CmdBar.m_arrCommand.Add(IDC_SEARCH_SPY);
m_CmdBar.m_arrCommand.Add(IDC_OPEN_FILE_LIST);
m_CmdBar.m_arrCommand.Add(ID_FILE_SETTINGS);
m_CmdBar.m_arrCommand.Add(IDC_NOTEPAD);
m_CmdBar.m_arrCommand.Add(IDC_NET_STATS);
m_CmdBar.m_arrCommand.Add(ID_WINDOW_CASCADE);
m_CmdBar.m_arrCommand.Add(ID_WINDOW_TILE_HORZ);
m_CmdBar.m_arrCommand.Add(ID_WINDOW_TILE_VERT);
m_CmdBar.m_arrCommand.Add(ID_WINDOW_MINIMIZE_ALL);
m_CmdBar.m_arrCommand.Add(ID_WINDOW_RESTORE_ALL);
// remove old menu
SetMenu(NULL);
HWND hWndToolBar = createToolbar();
CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
AddSimpleReBarBand(hWndCmdBar);
AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
CreateSimpleStatusBar();
ctrlStatus.Attach(m_hWndStatusBar);
ctrlStatus.SetSimple(FALSE);
int w[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
ctrlStatus.SetParts(8, w);
statusSizes[0] = WinUtil::getTextWidth(TSTRING(AWAY), ::GetDC(ctrlStatus.m_hWnd)); // for "AWAY" segment
CToolInfo ti(TTF_SUBCLASS, ctrlStatus.m_hWnd);
ctrlLastLines.Create(ctrlStatus.m_hWnd, rcDefault, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, WS_EX_TOPMOST);
ctrlLastLines.SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
ctrlLastLines.AddTool(&ti);
CreateMDIClient();
m_CmdBar.SetMDIClient(m_hWndMDIClient);
WinUtil::mdiClient = m_hWndMDIClient;
ctrlTab.Create(m_hWnd, rcDefault);
WinUtil::tabCtrl = &ctrlTab;
transferView.Create(m_hWnd);
SetSplitterPanes(m_hWndMDIClient, transferView.m_hWnd);
SetSplitterExtendedStyle(SPLIT_PROPORTIONAL);
m_nProportionalPos = 8000;
UIAddToolBar(hWndToolBar);
UISetCheck(ID_VIEW_TOOLBAR, 1);
UISetCheck(ID_VIEW_STATUS_BAR, 1);
UISetCheck(ID_VIEW_TRANSFER_VIEW, 1);
// register object for message filtering and idle updates
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);
pLoop->AddIdleHandler(this);
c->addListener(this);
c->downloadFile("http://dcplusplus.sourceforge.net/version.xml");
if(BOOLSETTING(OPEN_SYSTEM_LOG)) PostMessage(WM_COMMAND, IDC_SYSTEM_LOG);
if(BOOLSETTING(OPEN_PUBLIC)) PostMessage(WM_COMMAND, ID_FILE_CONNECT);
if(BOOLSETTING(OPEN_FAVORITE_HUBS)) PostMessage(WM_COMMAND, IDC_FAVORITES);
if(BOOLSETTING(OPEN_FAVORITE_USERS)) PostMessage(WM_COMMAND, IDC_FAVUSERS);
if(BOOLSETTING(OPEN_QUEUE)) PostMessage(WM_COMMAND, IDC_QUEUE);
if(BOOLSETTING(OPEN_FINISHED_DOWNLOADS)) PostMessage(WM_COMMAND, IDC_FINISHED);
if(BOOLSETTING(OPEN_WAITING_USERS)) PostMessage(WM_COMMAND, IDC_VIEW_WAITING_USERS);
if(BOOLSETTING(OPEN_FINISHED_UPLOADS)) PostMessage(WM_COMMAND, IDC_FINISHED_UL);
if(BOOLSETTING(OPEN_SEARCH_SPY)) PostMessage(WM_COMMAND, IDC_SEARCH_SPY);
if(BOOLSETTING(OPEN_NETWORK_STATISTICS)) PostMessage(WM_COMMAND, IDC_NET_STATS);
if(BOOLSETTING(OPEN_NOTEPAD)) PostMessage(WM_COMMAND, IDC_NOTEPAD);
if(!BOOLSETTING(SHOW_STATUSBAR)) PostMessage(WM_COMMAND, ID_VIEW_STATUS_BAR);
if(!BOOLSETTING(SHOW_TOOLBAR)) PostMessage(WM_COMMAND, ID_VIEW_TOOLBAR);
if(!BOOLSETTING(SHOW_TRANSFERVIEW)) PostMessage(WM_COMMAND, ID_VIEW_TRANSFER_VIEW);
if(!WinUtil::isShift())
PostMessage(WM_SPEAKER, AUTO_CONNECT);
PostMessage(WM_SPEAKER, PARSE_COMMAND_LINE);
File::ensureDirectory(SETTING(LOG_DIRECTORY));
startSocket();
if(SETTING(NICK).empty()) {
HtmlHelp(m_hWnd, WinUtil::getHelpFile().c_str(), HH_HELP_CONTEXT, IDD_GENERALPAGE);
PostMessage(WM_COMMAND, ID_FILE_SETTINGS);
}
// We want to pass this one on to the splitter...hope it get's there...
bHandled = FALSE;
return 0;
}
void MainFrame::startSocket() {
SearchManager::getInstance()->disconnect();
ConnectionManager::getInstance()->disconnect();
if(ClientManager::getInstance()->isActive()) {
try {
ConnectionManager::getInstance()->listen();
} catch(const Exception&) {
MessageBox(CTSTRING(TCP_PORT_BUSY), _T(APPNAME) _T(" ") _T(VERSIONSTRING), MB_ICONSTOP | MB_OK);
}
try {
SearchManager::getInstance()->listen();
} catch(const Exception&) {
MessageBox(CTSTRING(TCP_PORT_BUSY), _T(APPNAME) _T(" ") _T(VERSIONSTRING), MB_ICONSTOP | MB_OK);
}
}
startUPnP();
}
void MainFrame::startUPnP() {
stopUPnP();
if( SETTING(INCOMING_CONNECTIONS) == SettingsManager::INCOMING_FIREWALL_UPNP ) {
UPnP_TCPConnection = new UPnP( Util::getLocalIp(), "TCP", APPNAME " Download Port (" + Util::toString(ConnectionManager::getInstance()->getPort()) + " TCP)", ConnectionManager::getInstance()->getPort() );
UPnP_UDPConnection = new UPnP( Util::getLocalIp(), "UDP", APPNAME " Search Port (" + Util::toString(SearchManager::getInstance()->getPort()) + " UDP)", SearchManager::getInstance()->getPort() );
if ( FAILED(UPnP_UDPConnection->OpenPorts()) || FAILED(UPnP_TCPConnection->OpenPorts()) )
{
LogManager::getInstance()->message(STRING(UPNP_FAILED_TO_CREATE_MAPPINGS));
MessageBox(CTSTRING(UPNP_FAILED_TO_CREATE_MAPPINGS), _T(APPNAME) _T(" ") _T(VERSIONSTRING), MB_OK | MB_ICONWARNING);
// We failed! thus reset the objects
delete UPnP_TCPConnection;
delete UPnP_UDPConnection;
UPnP_TCPConnection = UPnP_UDPConnection = NULL;
}
else
{
if(!BOOLSETTING(NO_IP_OVERRIDE)) {
// now lets configure the external IP (connect to me) address
string ExternalIP = UPnP_TCPConnection->GetExternalIP();
if ( !ExternalIP.empty() ) {
// woohoo, we got the external IP from the UPnP framework
SettingsManager::getInstance()->set(SettingsManager::EXTERNAL_IP, ExternalIP );
} else {
//:-( Looks like we have to rely on the user setting the external IP manually
// no need to do cleanup here because the mappings work
LogManager::getInstance()->message(STRING(UPNP_FAILED_TO_GET_EXTERNAL_IP));
MessageBox(CTSTRING(UPNP_FAILED_TO_GET_EXTERNAL_IP), _T(APPNAME) _T(" ") _T(VERSIONSTRING), MB_OK | MB_ICONWARNING);
}
}
}
}
}
void MainFrame::stopUPnP() {
// Just check if the port mapping objects are initialized (NOT NULL)
if ( UPnP_TCPConnection != NULL )
{
if (FAILED(UPnP_TCPConnection->ClosePorts()) )
{
LogManager::getInstance()->message(STRING(UPNP_FAILED_TO_REMOVE_MAPPINGS));
}
delete UPnP_TCPConnection;
}
if ( UPnP_UDPConnection != NULL )
{
if (FAILED(UPnP_UDPConnection->ClosePorts()) )
{
LogManager::getInstance()->message(STRING(UPNP_FAILED_TO_REMOVE_MAPPINGS));
}
delete UPnP_UDPConnection;
}
// Not sure this is required (i.e. Objects are checked later in execution)
// But its better being on the save side :P
UPnP_TCPConnection = UPnP_UDPConnection = NULL;
}
HWND MainFrame::createToolbar() {
CToolBarCtrl ctrlToolbar;
largeImages.CreateFromImage(IDB_TOOLBAR20, 20, 15, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_SHARED);
largeImagesHot.CreateFromImage(IDB_TOOLBAR20_HOT, 20, 15, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_SHARED);
ctrlToolbar.Create(m_hWnd, NULL, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS, 0, ATL_IDW_TOOLBAR);
ctrlToolbar.SetImageList(largeImages);
ctrlToolbar.SetHotImageList(largeImagesHot);
const int numButtons = 22;
TBBUTTON tb[numButtons];
memset(tb, 0, sizeof(tb));
int n = 0, bitmap = 0;
tb[n].iBitmap = bitmap++;
tb[n].idCommand = ID_FILE_CONNECT;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].fsStyle = TBSTYLE_SEP;
n++;
tb[n].iBitmap = bitmap++;
tb[n].idCommand = ID_FILE_RECONNECT;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].iBitmap = bitmap++;
tb[n].idCommand = IDC_FOLLOW;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].fsStyle = TBSTYLE_SEP;
n++;
tb[n].iBitmap = bitmap++;
tb[n].idCommand = IDC_FAVORITES;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].iBitmap = bitmap++;
tb[n].idCommand = IDC_FAVUSERS;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].fsStyle = TBSTYLE_SEP;
n++;
tb[n].iBitmap = bitmap++;
tb[n].idCommand = IDC_QUEUE;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -