📄 mainfrm.cpp
字号:
/*
* Copyright (C) 2001-2003 Jacek Sieka, j_s@telia.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 "PrivateFrame.h"
#include "FinishedULFrame.h"
#include "../client/ConnectionManager.h"
#include "../client/DownloadManager.h"
#include "../client/UploadManager.h"
#include "../client/StringTokenizer.h"
#include "../client/SimpleXML.h"
int MainFrame::columnIndexes[] = { COLUMN_USER, COLUMN_STATUS, COLUMN_TIMELEFT, COLUMN_SPEED, COLUMN_FILE, COLUMN_SIZE, COLUMN_PATH };
int MainFrame::columnSizes[] = { 150, 250, 75, 75, 175, 100, 200 };
static ResourceManager::Strings columnNames[] = { ResourceManager::USER, ResourceManager::STATUS,
ResourceManager::TIME_LEFT, ResourceManager::SPEED, ResourceManager::FILENAME, ResourceManager::SIZE, ResourceManager::PATH };
MainFrame::~MainFrame() {
m_CmdBar.m_hImageList = NULL;
arrows.Destroy();
images.Destroy();
largeImages.Destroy();
WinUtil::uninit();
}
DWORD WINAPI MainFrame::stopper(void* p) {
MainFrame* mf = (MainFrame*)p;
HWND wnd, wnd2 = NULL;
while( (wnd=::GetWindow(mf->m_hWndClient, GW_CHILD)) != NULL) {
if(wnd == wnd2)
Sleep(100);
else {
::PostMessage(wnd, WM_CLOSE, 0, 0);
wnd2 = wnd;
}
}
shutdown();
mf->PostMessage(WM_CLOSE);
return 0;
}
LRESULT MainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) {
TimerManager::getInstance()->addListener(this);
DownloadManager::getInstance()->addListener(this);
UploadManager::getInstance()->addListener(this);
ConnectionManager::getInstance()->addListener(this);
QueueManager::getInstance()->addListener(this);
WinUtil::init(m_hWnd);
// Ugly fix for the multi-cpu issues: we set all threads to run on processor 0
if(::SetThreadAffinityMask(GetCurrentThread(), 1) == 0)
throw ThreadException(STRING(UNABLE_TO_CREATE_THREAD));
// Register server socket message
WSAAsyncSelect(ConnectionManager::getInstance()->getServerSocket().getSocket(),
m_hWnd, SERVER_SOCKET_MESSAGE, FD_ACCEPT);
trayMessage = RegisterWindowMessage("TaskbarCreated");
TimerManager::getInstance()->start();
if(!SETTING(LANGUAGE_FILE).empty()) {
ResourceManager::getInstance()->loadLanguage(SETTING(LANGUAGE_FILE));
}
// Set window name
SetWindowText(APPNAME " " 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, 5, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_SHARED);
largeImages.CreateFromImage(IDB_TOOLBAR20, 20, 5, 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_QUEUE);
m_CmdBar.m_arrCommand.Add(IDC_FINISHED); // adds icon to File menu
m_CmdBar.m_arrCommand.Add(IDC_FINISHED_UL); // Finished Upload 16 x 16 menu icon
m_CmdBar.m_arrCommand.Add(ID_FILE_SEARCH);
m_CmdBar.m_arrCommand.Add(IDC_FILE_ADL_SEARCH);
m_CmdBar.m_arrCommand.Add(ID_FILE_SETTINGS);
m_CmdBar.m_arrCommand.Add(IDC_NOTEPAD);
// 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(STRING(AWAY), ::GetDC(ctrlStatus.m_hWnd)); // for "AWAY" segment
CreateMDIClient();
m_CmdBar.SetMDIClient(m_hWndMDIClient);
arrows.CreateFromImage(IDB_ARROWS, 16, 2, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_SHARED);
ctrlTransfers.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
WS_HSCROLL | WS_VSCROLL | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS, WS_EX_CLIENTEDGE, IDC_TRANSFERS);
if(BOOLSETTING(FULL_ROW_SELECT)) {
ctrlTransfers.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP);
} else {
ctrlTransfers.SetExtendedListViewStyle(LVS_EX_HEADERDRAGDROP);
}
WinUtil::splitTokens(columnIndexes, SETTING(MAINFRAME_ORDER), COLUMN_LAST);
WinUtil::splitTokens(columnSizes, SETTING(MAINFRAME_WIDTHS), COLUMN_LAST);
for(int j=0; j<COLUMN_LAST; j++) {
int fmt = (j == COLUMN_SIZE || j == COLUMN_TIMELEFT || j == COLUMN_SPEED) ? LVCFMT_RIGHT : LVCFMT_LEFT;
ctrlTransfers.InsertColumn(j, CSTRING_I(columnNames[j]), fmt, columnSizes[j], j);
}
ctrlTransfers.SetColumnOrderArray(COLUMN_LAST, columnIndexes);
ctrlTransfers.SetBkColor(WinUtil::bgColor);
ctrlTransfers.SetTextBkColor(WinUtil::bgColor);
ctrlTransfers.SetTextColor(WinUtil::textColor);
ctrlTransfers.SetImageList(arrows, LVSIL_SMALL);
ctrlTab.Create(m_hWnd, rcDefault);
WinUtil::tabCtrl = &ctrlTab;
SetSplitterPanes(m_hWndClient, ctrlTransfers.m_hWnd);
SetSplitterExtendedStyle(SPLIT_PROPORTIONAL);
m_nProportionalPos = 8000;
UIAddToolBar(hWndToolBar);
UISetCheck(ID_VIEW_TOOLBAR, 1);
UISetCheck(ID_VIEW_STATUS_BAR, 1);
// register object for message filtering and idle updates
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);
pLoop->AddIdleHandler(this);
transferMenu.CreatePopupMenu();
transferMenu.AppendMenu(MF_STRING, IDC_GETLIST, CSTRING(GET_FILE_LIST));
transferMenu.AppendMenu(MF_STRING, IDC_PRIVATEMESSAGE, CSTRING(SEND_PRIVATE_MESSAGE));
transferMenu.AppendMenu(MF_STRING, IDC_GRANTSLOT, CSTRING(GRANT_EXTRA_SLOT));
transferMenu.AppendMenu(MF_STRING, IDC_ADD_TO_FAVORITES, CSTRING(ADD_TO_FAVORITES));
transferMenu.AppendMenu(MF_STRING, IDC_FORCE, CSTRING(FORCE_ATTEMPT));
transferMenu.AppendMenu(MF_SEPARATOR, 0, (LPTSTR)NULL);
transferMenu.AppendMenu(MF_STRING, IDC_REMOVE, CSTRING(CLOSE_CONNECTION));
transferMenu.AppendMenu(MF_STRING, IDC_REMOVEALL, CSTRING(REMOVE_FROM_ALL));
c->addListener(this);
c->downloadFile("http://dcplusplus.sourceforge.net/version.xml");
if(BOOLSETTING(OPEN_PUBLIC))
PostMessage(WM_COMMAND, ID_FILE_CONNECT);
if(BOOLSETTING(OPEN_QUEUE))
PostMessage(WM_COMMAND, IDC_QUEUE);
if(BOOLSETTING(OPEN_FAVORITE_HUBS))
PostMessage(WM_COMMAND, IDC_FAVORITES);
if(BOOLSETTING(OPEN_FINISHED_DOWNLOADS))
PostMessage(WM_COMMAND, IDC_FINISHED);
if(!(GetAsyncKeyState(VK_SHIFT) & 0x8000))
PostMessage(WM_SPEAKER, AUTO_CONNECT);
PostMessage(WM_SPEAKER, PARSE_COMMAND_LINE);
Util::ensureDirectory(SETTING(LOG_DIRECTORY));
ctrlTransfers.setSort(COLUMN_STATUS, ExListViewCtrl::SORT_FUNC, true, sortStatus);
startSocket();
if(SETTING(NICK).empty()) {
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(SETTING(CONNECTION_TYPE) == SettingsManager::CONNECTION_ACTIVE) {
short lastPort = (short)SETTING(IN_PORT);
short firstPort = lastPort;
while(true) {
try {
ConnectionManager::getInstance()->setPort(lastPort);
WSAAsyncSelect(ConnectionManager::getInstance()->getServerSocket().getSocket(), m_hWnd, SERVER_SOCKET_MESSAGE, FD_ACCEPT);
SearchManager::getInstance()->setPort(lastPort);
break;
} catch(const Exception& e) {
dcdebug("MainFrame::OnCreate caught %s\n", e.getError().c_str());
short newPort = (short)((lastPort == 32000) ? 1025 : lastPort + 1);
SettingsManager::getInstance()->setDefault(SettingsManager::IN_PORT, newPort);
if(SETTING(IN_PORT) == lastPort || (firstPort == newPort)) {
// Changing default didn't change port, a fixed port must be in use...(or we
// tried all ports
char* buf = new char[STRING(PORT_IS_BUSY).size() + 8];
sprintf(buf, CSTRING(PORT_IS_BUSY), SETTING(IN_PORT));
MessageBox(buf);
delete[] buf;
break;
}
lastPort = newPort;
}
}
}
}
HWND MainFrame::createToolbar() {
CToolBarCtrl ctrl;
ctrl.Create(m_hWnd, NULL, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS, 0, ATL_IDW_TOOLBAR);
ctrl.SetImageList(largeImages);
TBBUTTON tb[11];
memset(tb, 0, sizeof(tb));
int n = 0;
tb[n].iBitmap = n;
tb[n].idCommand = ID_FILE_CONNECT;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].iBitmap = n;
tb[n].idCommand = ID_FILE_RECONNECT;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].iBitmap = n;
tb[n].idCommand = IDC_FOLLOW;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].iBitmap = n;
tb[n].idCommand = IDC_FAVORITES;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].iBitmap = n;
tb[n].idCommand = IDC_QUEUE;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++; // toolbar icon
tb[n].iBitmap = n;
tb[n].idCommand = IDC_FINISHED;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++; // Finished Upload 20x20 toolbar icon
tb[n].iBitmap = n;
tb[n].idCommand = IDC_FINISHED_UL;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].iBitmap = n;
tb[n].idCommand = ID_FILE_SEARCH;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].iBitmap = n;
tb[n].idCommand = IDC_FILE_ADL_SEARCH;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].iBitmap = n;
tb[n].idCommand = ID_FILE_SETTINGS;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
n++;
tb[n].iBitmap = n;
tb[n].idCommand = IDC_NOTEPAD;
tb[n].fsState = TBSTATE_ENABLED;
tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
ctrl.SetButtonStructSize();
ctrl.AddButtons(11, tb);
ctrl.AutoSize();
return ctrl.m_hWnd;
}
int MainFrame::sortSize(LPARAM a, LPARAM b) {
int i = sortItem(a, b);
if( i == ExListViewCtrl::SORT_STRING_NOCASE) {
ItemInfo* c = (ItemInfo*)a;
ItemInfo* d = (ItemInfo*)b;
return compare(c->size, d->size);
}
return i;
}
int MainFrame::sortStatus(LPARAM a, LPARAM b) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -