📄 winutil.cpp
字号:
::RegCloseKey(hk);
}
}
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);
}
// check for the existence of magnet.exe
if(File::getSize(Text::fromT(magnetExe)) == -1) {
magnetExe = Text::toT(Util::getAppPath() + "magnet.exe");
if(File::getSize(Text::fromT(magnetExe)) == -1) {
// gracefully fall back to registering DC++ to handle magnets
magnetExe = Text::toT(Util::getAppName());
haveMagnet = false;
} else {
// set Magnet\Location
::RegCreateKey(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Magnet"), &hk);
::RegSetValueEx(hk, _T("Location"), NULL, REG_SZ, (LPBYTE)magnetExe.c_str(), sizeof(TCHAR) * (magnetExe.length()+1));
::RegCloseKey(hk);
}
magnetLoc = _T('"') + magnetExe + _T('"');
}
// (re)register the handler if magnet.exe isn't the default, or if DC++ is handling it
if(BOOLSETTING(MAGNET_REGISTER) && (Util::strnicmp(openCmd, magnetLoc, magnetLoc.size()) != 0 || !haveMagnet)) {
SHDeleteKey(HKEY_CLASSES_ROOT, _T("magnet"));
::RegCreateKey(HKEY_CLASSES_ROOT, _T("magnet"), &hk);
::RegSetValueEx(hk, NULL, NULL, REG_SZ, (LPBYTE)CTSTRING(MAGNET_SHELL_DESC), sizeof(TCHAR)*(TSTRING(MAGNET_SHELL_DESC).length()+1));
::RegSetValueEx(hk, _T("URL Protocol"), NULL, REG_SZ, NULL, NULL);
::RegCloseKey(hk);
::RegCreateKey(HKEY_CLASSES_ROOT, _T("magnet\\DefaultIcon"), &hk);
::RegSetValueEx(hk, NULL, NULL, REG_SZ, (LPBYTE)magnetLoc.c_str(), sizeof(TCHAR)*(magnetLoc.length()+1));
::RegCloseKey(hk);
magnetLoc += _T(" %1");
::RegCreateKey(HKEY_CLASSES_ROOT, _T("magnet\\shell\\open\\command"), &hk);
::RegSetValueEx(hk, NULL, NULL, REG_SZ, (LPBYTE)magnetLoc.c_str(), sizeof(TCHAR)*(magnetLoc.length()+1));
::RegCloseKey(hk);
}
// magnet-handler specific code
// clean out the DC++ tree first
SHDeleteKey(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Magnet\\Handlers\\DC++"));
// add DC++ to magnet-handler's list of applications
::RegCreateKey(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Magnet\\Handlers\\DC++"), &hk);
::RegSetValueEx(hk, NULL, NULL, REG_SZ, (LPBYTE)CTSTRING(MAGNET_HANDLER_ROOT), sizeof(TCHAR) * (TSTRING(MAGNET_HANDLER_ROOT).size()+1));
::RegSetValueEx(hk, _T("Description"), NULL, REG_SZ, (LPBYTE)CTSTRING(MAGNET_HANDLER_DESC), sizeof(TCHAR) * (STRING(MAGNET_HANDLER_DESC).size()+1));
// set ShellExecute
tstring app = Text::toT("\"" + Util::getAppName() + "\" %URL");
::RegSetValueEx(hk, _T("ShellExecute"), NULL, REG_SZ, (LPBYTE)app.c_str(), sizeof(TCHAR) * (app.length()+1));
// set DefaultIcon
app = Text::toT('"' + Util::getAppName() + '"');
::RegSetValueEx(hk, _T("DefaultIcon"), NULL, REG_SZ, (LPBYTE)app.c_str(), sizeof(TCHAR)*(app.length()+1));
::RegCloseKey(hk);
// These two types contain a tth root, and are in common use. The other two are variations picked up
// from Shareaza's source, which come second hand from Gordon Mohr. -GargoyleMT
// Reference: http://forums.shareaza.com/showthread.php?threadid=23731
// Note: the three part hash types require magnethandler >= 1.0.0.3
DWORD nothing = 0;
::RegCreateKey(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Magnet\\Handlers\\DC++\\Type"), &hk);
::RegSetValueEx(hk, _T("urn:bitprint"), NULL, REG_DWORD, (LPBYTE)¬hing, sizeof(nothing));
::RegSetValueEx(hk, _T("urn:tree:tiger"), NULL, REG_DWORD, (LPBYTE)¬hing, sizeof(nothing));
::RegSetValueEx(hk, _T("urn:tree:tiger/"), NULL, REG_DWORD, (LPBYTE)¬hing, sizeof(nothing));
::RegSetValueEx(hk, _T("urn:tree:tiger/1024"), NULL, REG_DWORD, (LPBYTE)¬hing, sizeof(nothing));
::RegCloseKey(hk);
}
void WinUtil::openLink(const tstring& url) {
CRegKey key;
TCHAR regbuf[MAX_PATH];
ULONG len = MAX_PATH;
tstring x;
tstring::size_type i = url.find(_T("://"));
if(i != string::npos) {
x = url.substr(0, i);
} else {
x = _T("http");
}
x += _T("\\shell\\open\\command");
if(key.Open(HKEY_CLASSES_ROOT, x.c_str(), KEY_READ) == ERROR_SUCCESS) {
if(key.QueryStringValue(NULL, regbuf, &len) == ERROR_SUCCESS) {
/*
* Various values (for http handlers):
* C:\PROGRA~1\MOZILL~1\FIREFOX.EXE -url "%1"
* "C:\Program Files\Internet Explorer\iexplore.exe" -nohome
* "C:\Apps\Opera7\opera.exe"
* C:\PROGRAMY\MOZILLA\MOZILLA.EXE -url "%1"
* C:\PROGRA~1\NETSCAPE\NETSCAPE\NETSCP.EXE -url "%1"
*/
tstring cmd(regbuf); // otherwise you consistently get two trailing nulls
if(cmd.length() > 1) {
string::size_type start,end;
if(cmd[0] == '"') {
start = 1;
end = cmd.find('"', 1);
} else {
start = 0;
end = cmd.find(' ', 1);
}
if(end == string::npos)
end = cmd.length();
tstring cmdLine(cmd);
cmd = cmd.substr(start, end-start);
size_t arg_pos;
if((arg_pos = cmdLine.find(_T("%1"))) != string::npos) {
cmdLine.replace(arg_pos, 2, url);
} else {
cmdLine.append(_T(" \"") + url + _T('\"'));
}
STARTUPINFO si = { sizeof(si), 0 };
PROCESS_INFORMATION pi = { 0 };
AutoArray<TCHAR> buf(cmdLine.length() + 1);
_tcscpy(buf, cmdLine.c_str());
if(::CreateProcess(cmd.c_str(), buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
::CloseHandle(pi.hThread);
::CloseHandle(pi.hProcess);
return;
}
}
}
}
::ShellExecute(NULL, NULL, url.c_str(), NULL, NULL, SW_SHOWNORMAL);
}
void WinUtil::parseDchubUrl(const tstring& aUrl) {
string server, file;
u_int16_t port = 411;
Util::decodeUrl(Text::fromT(aUrl), server, port, file);
if(!server.empty()) {
HubFrame::openWindow(Text::toT(server + ":" + Util::toString(port)));
}
if(!file.empty()) {
if(file[0] == '/') // Remove any '/' in from of the file
file = file.substr(1);
try {
QueueManager::getInstance()->addList(ClientManager::getInstance()->getUser(file), QueueItem::FLAG_CLIENT_VIEW);
} catch(const Exception&) {
// ...
}
}
}
void WinUtil::parseADChubUrl(const tstring& aUrl) {
string server, file;
u_int16_t port = 0; //make sure we get a port since adc doesn't have a standard one
Util::decodeUrl(Text::fromT(aUrl), server, port, file);
if(!server.empty() && port > 0) {
HubFrame::openWindow(Text::toT("adc://" + server + ":" + Util::toString(port)));
}
}
void WinUtil::parseMagnetUri(const tstring& aUrl, bool /*aOverride*/) {
// official types that are of interest to us
// xt = exact topic
// xs = exact substitute
// as = acceptable substitute
// dn = display name
if (Util::strnicmp(aUrl.c_str(), _T("magnet:?"), 8) == 0) {
LogManager::getInstance()->message(STRING(MAGNET_DLG_TITLE) + ": " + Text::fromT(aUrl));
StringTokenizer<tstring> mag(aUrl.substr(8), _T('&'));
typedef map<tstring, tstring> MagMap;
MagMap hashes;
tstring fname, fhash, type, param;
for(TStringList::iterator idx = mag.getTokens().begin(); idx != mag.getTokens().end(); ++idx) {
// break into pairs
string::size_type pos = idx->find(_T('='));
if(pos != string::npos) {
type = Text::toT(Text::toLower(Util::encodeURI(Text::fromT(idx->substr(0, pos)), true)));
param = Text::toT(Util::encodeURI(Text::fromT(idx->substr(pos+1)), true));
} else {
type = Text::toT(Util::encodeURI(Text::fromT(*idx), true));
param.clear();
}
// extract what is of value
if(param.length() == 85 && Util::strnicmp(param.c_str(), _T("urn:bitprint:"), 13) == 0) {
hashes[type] = param.substr(46);
} else if(param.length() == 54 && Util::strnicmp(param.c_str(), _T("urn:tree:tiger:"), 15) == 0) {
hashes[type] = param.substr(15);
} else if(param.length() == 55 && Util::strnicmp(param.c_str(), _T("urn:tree:tiger/:"), 16) == 0) {
hashes[type] = param.substr(16);
} else if(param.length() == 59 && Util::strnicmp(param.c_str(), _T("urn:tree:tiger/1024:"), 20) == 0) {
hashes[type] = param.substr(20);
} else if(type.length() == 2 && Util::strnicmp(type.c_str(), _T("dn"), 2) == 0) {
fname = param;
}
}
// pick the most authoritative hash out of all of them.
if(hashes.find(_T("as")) != hashes.end()) {
fhash = hashes[_T("as")];
}
if(hashes.find(_T("xs")) != hashes.end()) {
fhash = hashes[_T("xs")];
}
if(hashes.find(_T("xt")) != hashes.end()) {
fhash = hashes[_T("xt")];
}
if(!fhash.empty()){
// ok, we have a hash, and maybe a filename.
//if(!BOOLSETTING(MAGNET_ASK)) {
// switch(SETTING(MAGNET_ACTION)) {
// case SettingsManager::MAGNET_AUTO_DOWNLOAD:
// break;
// case SettingsManager::MAGNET_AUTO_SEARCH:
// SearchFrame::openWindow(fhash, 0, SearchManager::SIZE_DONTCARE, SearchManager::TYPE_HASH);
// break;
// };
//} else {
// use aOverride to force the display of the dialog. used for auto-updating
MagnetDlg dlg(fhash, fname);
dlg.DoModal(mainWnd);
//}
} else {
MessageBox(mainWnd, CTSTRING(MAGNET_DLG_TEXT_BAD), CTSTRING(MAGNET_DLG_TITLE), MB_OK | MB_ICONEXCLAMATION);
}
}
}
int WinUtil::textUnderCursor(POINT p, CEdit& ctrl, tstring& x) {
int i = ctrl.CharFromPos(p);
int line = ctrl.LineFromChar(i);
int c = LOWORD(i) - ctrl.LineIndex(line);
int len = ctrl.LineLength(i) + 1;
if(len < 3) {
return 0;
}
AutoArray<TCHAR> buf(len);
ctrl.GetLine(line, buf, len);
x = tstring(buf, len-1);
string::size_type start = x.find_last_of(_T(" <\t\r\n"), c);
if(start == string::npos)
start = 0;
else
start++;
return start;
}
bool WinUtil::parseDBLClick(const tstring& aString, string::size_type start, string::size_type end) {
if( (Util::strnicmp(aString.c_str() + start, _T("http://"), 7) == 0) ||
(Util::strnicmp(aString.c_str() + start, _T("www."), 4) == 0) ||
(Util::strnicmp(aString.c_str() + start, _T("ftp://"), 6) == 0) ||
(Util::strnicmp(aString.c_str() + start, _T("irc://"), 6) == 0) ||
(Util::strnicmp(aString.c_str() + start, _T("https://"), 8) == 0) ||
(Util::strnicmp(aString.c_str() + start, _T("mailto:"), 7) == 0) )
{
openLink(aString.substr(start, end-start));
return true;
} else if(Util::strnicmp(aString.c_str() + start, _T("dchub://"), 8) == 0) {
parseDchubUrl(aString.substr(start, end-start));
return true;
} else if(Util::strnicmp(aString.c_str() + start, _T("magnet:?"), 8) == 0) {
parseMagnetUri(aString.substr(start, end-start));
return true;
} else if(Util::strnicmp(aString.c_str() + start, _T("adc://"), 6) == 0) {
parseADChubUrl(aString.substr(start, end-start));
return true;
}
return false;
}
void WinUtil::saveHeaderOrder(CListViewCtrl& ctrl, SettingsManager::StrSetting order,
SettingsManager::StrSetting widths, int n,
int* indexes, int* sizes) throw() {
string tmp;
ctrl.GetColumnOrderArray(n, indexes);
int i;
for(i = 0; i < n; ++i) {
tmp += Util::toString(indexes[i]);
tmp += ',';
}
tmp.erase(tmp.size()-1, 1);
SettingsManager::getInstance()->set(order, tmp);
tmp.clear();
for(i = 0; i < n; ++i) {
sizes[i] = ctrl.GetColumnWidth(i);
tmp += Util::toString(sizes[i]);
tmp += ',';
}
tmp.erase(tmp.size()-1, 1);
SettingsManager::getInstance()->set(widths, tmp);
}
int WinUtil::getIconIndex(const tstring& aFileName) {
if(BOOLSETTING(USE_SYSTEM_ICONS)) {
SHFILEINFO fi;
string x = Text::toLower(Util::getFileExt(Text::fromT(aFileName)));
if(!x.empty()) {
ImageIter j = fileIndexes.find(x);
if(j != fileIndexes.end())
return j->second;
}
tstring fn = Text::toT(Text::toLower(Util::getFileName(Text::fromT(aFileName))));
::SHGetFileInfo(fn.c_str(), FILE_ATTRIBUTE_NORMAL, &fi, sizeof(fi), SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES);
fileImages.AddIcon(fi.hIcon);
::DestroyIcon(fi.hIcon);
fileIndexes[x] = fileImageCount++;
return fileImageCount - 1;
} else {
return 2;
}
}
int WinUtil::getOsMajor() {
OSVERSIONINFOEX ver;
memset(&ver, 0, sizeof(OSVERSIONINFOEX));
if(!GetVersionEx((OSVERSIONINFO*)&ver))
{
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
}
GetVersionEx((OSVERSIONINFO*)&ver);
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
return ver.dwMajorVersion;
}
int WinUtil::getOsMinor()
{
OSVERSIONINFOEX ver;
memset(&ver, 0, sizeof(OSVERSIONINFOEX));
if(!GetVersionEx((OSVERSIONINFO*)&ver))
{
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
}
GetVersionEx((OSVERSIONINFO*)&ver);
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
return ver.dwMinorVersion;
}
/**
* @file
* $Id: WinUtil.cpp,v 1.78 2005/03/12 13:36:50 arnetheduck Exp $
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -