📄 winutil.cpp
字号:
bool WinUtil::browseDirectory(tstring& target, HWND owner /* = NULL */) {
TCHAR buf[MAX_PATH];
BROWSEINFO bi;
LPMALLOC ma;
ZeroMemory(&bi, sizeof(bi));
bi.hwndOwner = owner;
bi.pszDisplayName = buf;
bi.lpszTitle = CTSTRING(CHOOSE_FOLDER);
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI;
bi.lParam = (LPARAM)target.c_str();
bi.lpfn = &browseCallbackProc;
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
if(pidl != NULL) {
SHGetPathFromIDList(pidl, buf);
target = buf;
if(target.size() > 0 && target[target.size()-1] != L'\\')
target+=L'\\';
if(SHGetMalloc(&ma) != E_FAIL) {
ma->Free(pidl);
ma->Release();
}
return true;
}
return false;
}
bool WinUtil::browseFile(tstring& target, HWND owner /* = NULL */, bool save /* = true */, const tstring& initialDir /* = Util::emptyString */, const TCHAR* types /* = NULL */, const TCHAR* defExt /* = NULL */) {
TCHAR buf[MAX_PATH];
OPENFILENAME ofn = { 0 }; // common dialog box structure
target = Text::toT(Util::validateFileName(Text::fromT(target)));
_tcscpy(buf, target.c_str());
// Initialize OPENFILENAME
ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
ofn.hwndOwner = owner;
ofn.lpstrFile = buf;
ofn.lpstrFilter = types;
ofn.lpstrDefExt = defExt;
ofn.nFilterIndex = 1;
if(!initialDir.empty()) {
ofn.lpstrInitialDir = initialDir.c_str();
}
ofn.nMaxFile = sizeof(buf);
ofn.Flags = (save ? 0: OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST);
// Display the Open dialog box.
if ( (save ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn) ) ==TRUE) {
target = ofn.lpstrFile;
return true;
}
return false;
}
tstring WinUtil::encodeFont(LOGFONT const& font)
{
tstring res(font.lfFaceName);
res += L',';
res += Text::toT(Util::toString(font.lfHeight));
res += L',';
res += Text::toT(Util::toString(font.lfWeight));
res += L',';
res += Text::toT(Util::toString(font.lfItalic));
return res;
}
void WinUtil::setClipboard(const tstring& str) {
if(!::OpenClipboard(mainWnd)) {
return;
}
EmptyClipboard();
#ifdef UNICODE
OSVERSIONINFOEX ver;
if( WinUtil::getVersionInfo(ver) ) {
if( ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) {
string tmp = Text::wideToAcp(str);
HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (tmp.size() + 1) * sizeof(char));
if (hglbCopy == NULL) {
CloseClipboard();
return;
}
// Lock the handle and copy the text to the buffer.
char* lptstrCopy = (char*)GlobalLock(hglbCopy);
strcpy(lptstrCopy, tmp.c_str());
GlobalUnlock(hglbCopy);
SetClipboardData(CF_TEXT, hglbCopy);
CloseClipboard();
return;
}
}
#endif
// Allocate a global memory object for the text.
HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (str.size() + 1) * sizeof(TCHAR));
if (hglbCopy == NULL) {
CloseClipboard();
return;
}
// Lock the handle and copy the text to the buffer.
TCHAR* lptstrCopy = (TCHAR*)GlobalLock(hglbCopy);
_tcscpy(lptstrCopy, str.c_str());
GlobalUnlock(hglbCopy);
// Place the handle on the clipboard.
#ifdef UNICODE
SetClipboardData(CF_UNICODETEXT, hglbCopy);
#else
SetClipboardData(CF_TEXT hglbCopy);
#endif
CloseClipboard();
}
void WinUtil::splitTokens(int* array, const string& tokens, int maxItems /* = -1 */) throw() {
StringTokenizer<string> t(tokens, _T(','));
StringList& l = t.getTokens();
if(maxItems == -1)
maxItems = l.size();
int k = 0;
for(StringList::const_iterator i = l.begin(); i != l.end() && k < maxItems; ++i, ++k) {
array[k] = Util::toInt(*i);
}
}
bool WinUtil::getUCParams(HWND parent, const UserCommand& uc, StringMap& sm) throw() {
string::size_type i = 0;
StringMap done;
while( (i = uc.getCommand().find("%[line:", i)) != string::npos) {
i += 7;
string::size_type j = uc.getCommand().find(']', i);
if(j == string::npos)
break;
string name = uc.getCommand().substr(i, j-i);
if(done.find(name) == done.end()) {
LineDlg dlg;
dlg.title = Text::toT(uc.getName());
dlg.description = Text::toT(name);
dlg.line = Text::toT(sm["line:" + name]);
if(dlg.DoModal(parent) == IDOK) {
sm["line:" + name] = Text::fromT(dlg.line);
done[name] = Text::fromT(dlg.line);
} else {
return false;
}
}
i = j + 1;
}
return true;
}
#define LINE2 _T("-- http://dcplusplus.sourceforge.net <DC++ ") _T(VERSIONSTRING) _T(">")
TCHAR *msgs[] = { _T("\r\n-- I'm a happy dc++ user. You could be happy too.\r\n") LINE2,
_T("\r\n-- Neo-...what? Nope...never heard of it...\r\n") LINE2,
_T("\r\n-- Evolution of species: Ape --> Man\r\n-- Evolution of science: \"The Earth is Flat\" --> \"The Earth is Round\"\r\n-- Evolution of sharing: NMDC --> DC++\r\n") LINE2,
_T("\r\n-- I share, therefore I am.\r\n") LINE2,
_T("\r\n-- I came, I searched, I found...\r\n") LINE2,
_T("\r\n-- I came, I shared, I sent...\r\n") LINE2,
_T("\r\n-- I can set away mode, can't you?\r\n") LINE2,
_T("\r\n-- I don't have to see any ads, do you?\r\n") LINE2,
_T("\r\n-- I don't have to see those annoying kick messages, do you?\r\n") LINE2,
_T("\r\n-- I can resume my files to a different filename, can you?\r\n") LINE2,
_T("\r\n-- I can share huge amounts of files, can you?\r\n") LINE2,
_T("\r\n-- My client doesn't spam the chat with useless debug messages, does yours?\r\n") LINE2,
_T("\r\n-- I can add multiple users to the same download and have the client connect to another automatically when one goes offline, can you?\r\n") LINE2,
_T("\r\n-- These addies are pretty annoying, aren't they? Get revenge by sending them yourself!\r\n") LINE2,
_T("\r\n-- My client supports TTH hashes, does yours?\r\n") LINE2,
_T("\r\n-- My client supports XML file lists, does yours?\r\n") LINE2
};
#define MSGS 16
tstring WinUtil::commands = _T("/refresh, /slots #, /search <string>, /dc++, /away <msg>, /back, /g <searchstring>, /imdb <imdbquery>, /u <url>, /rebuild");
bool WinUtil::checkCommand(tstring& cmd, tstring& param, tstring& message, tstring& status) {
string::size_type i = cmd.find(' ');
if(i != string::npos) {
param = cmd.substr(i+1);
cmd = cmd.substr(1, i - 1);
} else {
cmd = cmd.substr(1);
}
if(Util::stricmp(cmd.c_str(), _T("log")) == 0) {
if(Util::stricmp(param.c_str(), _T("system")) == 0) {
WinUtil::openFile(Text::toT(Util::validateFileName(SETTING(LOG_DIRECTORY) + "system.log")));
} else if(Util::stricmp(param.c_str(), _T("downloads")) == 0) {
WinUtil::openFile(Text::toT(Util::validateFileName(SETTING(LOG_DIRECTORY) + Util::formatTime(SETTING(LOG_FILE_DOWNLOAD), time(NULL)))));
} else if(Util::stricmp(param.c_str(), _T("uploads")) == 0) {
WinUtil::openFile(Text::toT(Util::validateFileName(SETTING(LOG_DIRECTORY) + Util::formatTime(SETTING(LOG_FILE_UPLOAD), time(NULL)))));
} else {
return false;
}
} else if(Util::stricmp(cmd.c_str(), _T("refresh"))==0) {
try {
ShareManager::getInstance()->setDirty();
ShareManager::getInstance()->refresh(true);
} catch(const ShareException& e) {
status = Text::toT(e.getError());
}
} else if(Util::stricmp(cmd.c_str(), _T("slots"))==0) {
int j = Util::toInt(Text::fromT(param));
if(j > 0) {
SettingsManager::getInstance()->set(SettingsManager::SLOTS, j);
status = TSTRING(SLOTS_SET);
ClientManager::getInstance()->infoUpdated();
} else {
status = TSTRING(INVALID_NUMBER_OF_SLOTS);
}
} else if(Util::stricmp(cmd.c_str(), _T("search")) == 0) {
if(!param.empty()) {
SearchFrame::openWindow(param);
} else {
status = TSTRING(SPECIFY_SEARCH_STRING);
}
} else if(Util::stricmp(cmd.c_str(), _T("dc++")) == 0) {
message = msgs[GET_TICK() % MSGS];
} else if(Util::stricmp(cmd.c_str(), _T("away")) == 0) {
if(Util::getAway() && param.empty()) {
Util::setAway(false);
Util::setManualAway(false);
status = TSTRING(AWAY_MODE_OFF);
} else {
Util::setAway(true);
Util::setManualAway(true);
Util::setAwayMessage(Text::fromT(param));
status = TSTRING(AWAY_MODE_ON) + Text::toT(Util::getAwayMessage());
}
} else if(Util::stricmp(cmd.c_str(), _T("back")) == 0) {
Util::setAway(false);
status = TSTRING(AWAY_MODE_OFF);
} else if(Util::stricmp(cmd.c_str(), _T("g")) == 0) {
if(param.empty()) {
status = TSTRING(SPECIFY_SEARCH_STRING);
} else {
WinUtil::openLink(_T("http://www.google.com/search?q=") + Text::toT(Util::encodeURI(Text::fromT(param))));
}
} else if(Util::stricmp(cmd.c_str(), _T("imdb")) == 0) {
if(param.empty()) {
status = TSTRING(SPECIFY_SEARCH_STRING);
} else {
WinUtil::openLink(_T("http://www.imdb.com/find?q=") + Text::toT(Util::encodeURI(Text::fromT(param))));
}
} else if(Util::stricmp(cmd.c_str(), _T("u")) == 0) {
if (param.empty()) {
status = TSTRING(SPECIFY_URL);
} else {
WinUtil::openLink(Text::toT(Util::encodeURI(Text::fromT(param))));
}
} else if(Util::stricmp(cmd.c_str(), _T("rebuild")) == 0) {
HashManager::getInstance()->rebuild();
} else {
return false;
}
return true;
}
void WinUtil::bitziLink(const TTHValue* aHash) {
// to use this free service by bitzi, we must not hammer or request information from bitzi
// except when the user requests it (a mass lookup isn't acceptable), and (if we ever fetch
// this data within DC++, we must identify the client/mod in the user agent, so abuse can be
// tracked down and the code can be fixed
if(aHash != NULL) {
openLink(_T("http://bitzi.com/lookup/tree:tiger:") + Text::toT(aHash->toBase32()));
}
}
void WinUtil::copyMagnet(const TTHValue* aHash, const tstring& aFile) {
if(aHash != NULL && !aFile.empty()) {
setClipboard(_T("magnet:?xt=urn:tree:tiger:") + Text::toT(aHash->toBase32()) + _T("&dn=") + Text::toT(Util::encodeURI(Text::fromT(aFile))));
}
}
void WinUtil::searchHash(const TTHValue* aHash) {
if(aHash != NULL) {
SearchFrame::openWindow(Text::toT(aHash->toBase32()), 0, SearchManager::SIZE_DONTCARE, SearchManager::TYPE_TTH);
}
}
void WinUtil::registerDchubHandler() {
HKEY hk;
TCHAR Buf[512];
tstring app = _T("\"") + Text::toT(Util::getAppName()) + _T("\" %1");
Buf[0] = 0;
if(::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("dchub\\Shell\\Open\\Command"), 0, KEY_WRITE | KEY_READ, &hk) == ERROR_SUCCESS) {
DWORD bufLen = sizeof(Buf);
DWORD type;
::RegQueryValueEx(hk, NULL, 0, &type, (LPBYTE)Buf, &bufLen);
::RegCloseKey(hk);
}
if(Util::stricmp(app.c_str(), Buf) != 0) {
if (::RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("dchub"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hk, NULL)) {
LogManager::getInstance()->message(STRING(ERROR_CREATING_REGISTRY_KEY_DCHUB));
return;
}
TCHAR* tmp = _T("URL:Direct Connect Protocol");
::RegSetValueEx(hk, NULL, 0, REG_SZ, (LPBYTE)tmp, sizeof(TCHAR) * (_tcslen(tmp) + 1));
::RegSetValueEx(hk, _T("URL Protocol"), 0, REG_SZ, (LPBYTE)_T(""), sizeof(TCHAR));
::RegCloseKey(hk);
::RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("dchub\\Shell\\Open\\Command"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hk, NULL);
::RegSetValueEx(hk, _T(""), 0, REG_SZ, (LPBYTE)app.c_str(), sizeof(TCHAR) * (app.length() + 1));
::RegCloseKey(hk);
::RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("dchub\\DefaultIcon"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hk, NULL);
app = Text::toT(Util::getAppName());
::RegSetValueEx(hk, _T(""), 0, REG_SZ, (LPBYTE)app.c_str(), sizeof(TCHAR) * (app.length() + 1));
::RegCloseKey(hk);
}
}
void WinUtil::unRegisterDchubHandler() {
SHDeleteKey(HKEY_CLASSES_ROOT, _T("dchub"));
}
void WinUtil::registerADChubHandler() {
HKEY hk;
TCHAR Buf[512];
tstring app = _T("\"") + Text::toT(Util::getAppName()) + _T("\" %1");
Buf[0] = 0;
if(::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("adc\\Shell\\Open\\Command"), 0, KEY_WRITE | KEY_READ, &hk) == ERROR_SUCCESS) {
DWORD bufLen = sizeof(Buf);
DWORD type;
::RegQueryValueEx(hk, NULL, 0, &type, (LPBYTE)Buf, &bufLen);
::RegCloseKey(hk);
}
if(Util::stricmp(app.c_str(), Buf) != 0) {
if (::RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("adc"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hk, NULL)) {
LogManager::getInstance()->message(STRING(ERROR_CREATING_REGISTRY_KEY_ADC));
return;
}
TCHAR* tmp = _T("URL:Direct Connect Protocol");
::RegSetValueEx(hk, NULL, 0, REG_SZ, (LPBYTE)tmp, sizeof(TCHAR) * (_tcslen(tmp) + 1));
::RegSetValueEx(hk, _T("URL Protocol"), 0, REG_SZ, (LPBYTE)_T(""), sizeof(TCHAR));
::RegCloseKey(hk);
::RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("adc\\Shell\\Open\\Command"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hk, NULL);
::RegSetValueEx(hk, _T(""), 0, REG_SZ, (LPBYTE)app.c_str(), sizeof(TCHAR) * (app.length() + 1));
::RegCloseKey(hk);
::RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("adc\\DefaultIcon"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hk, NULL);
app = Text::toT(Util::getAppName());
::RegSetValueEx(hk, _T(""), 0, REG_SZ, (LPBYTE)app.c_str(), sizeof(TCHAR) * (app.length() + 1));
::RegCloseKey(hk);
}
}
void WinUtil::unRegisterADChubHandler() {
SHDeleteKey(HKEY_CLASSES_ROOT, _T("adc"));
}
void WinUtil::registerMagnetHandler() {
HKEY hk;
TCHAR buf[512];
tstring openCmd, magnetLoc, magnetExe;
buf[0] = 0;
bool haveMagnet = true;
// what command is set up to handle magnets right now?
if(::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("magnet\\shell\\open\\command"), 0, KEY_READ, &hk) == ERROR_SUCCESS) {
DWORD bufLen = sizeof(TCHAR) * sizeof(buf);
::RegQueryValueEx(hk, NULL, NULL, NULL, (LPBYTE)buf, &bufLen);
::RegCloseKey(hk);
}
openCmd = buf;
buf[0] = 0;
// read the location of magnet.exe
if(::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Magnet"), NULL, KEY_READ, &hk) == ERROR_SUCCESS) {
DWORD bufLen = sizeof(buf) * sizeof(TCHAR);
::RegQueryValueEx(hk, _T("Location"), NULL, NULL, (LPBYTE)buf, &bufLen);
::RegCloseKey(hk);
}
magnetLoc = buf;
string::size_type i;
if (magnetLoc[0]==_T('"') && string::npos != (i = magnetLoc.find(_T('"'), 1))) {
magnetExe = magnetLoc.substr(1, i-1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -