diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f285c9c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +Release/* +Debug/* +taskbar.ncb +taskbar.suo +taskbar.vcproj.* \ No newline at end of file diff --git a/Release/StdAfx.obj b/Release/StdAfx.obj deleted file mode 100644 index ce02603..0000000 Binary files a/Release/StdAfx.obj and /dev/null differ diff --git a/Release/goagent.exe b/Release/goagent.exe deleted file mode 100644 index 66782c3..0000000 Binary files a/Release/goagent.exe and /dev/null differ diff --git a/Release/taskbar.obj b/Release/taskbar.obj deleted file mode 100644 index e2b304a..0000000 Binary files a/Release/taskbar.obj and /dev/null differ diff --git a/Release/taskbar.pch b/Release/taskbar.pch deleted file mode 100644 index 5413d8b..0000000 Binary files a/Release/taskbar.pch and /dev/null differ diff --git a/Release/taskbar.res b/Release/taskbar.res deleted file mode 100644 index b19d22a..0000000 Binary files a/Release/taskbar.res and /dev/null differ diff --git a/Release/vc60.idb b/Release/vc60.idb deleted file mode 100644 index 4c3778f..0000000 Binary files a/Release/vc60.idb and /dev/null differ diff --git a/StdAfx.h b/StdAfx.h index b99a13b..fd10e96 100644 --- a/StdAfx.h +++ b/StdAfx.h @@ -1,23 +1,46 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// -#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) -#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ +// stdafx.h : ±ê׼ϵͳ°üº¬ÎļþµÄ°üº¬Îļþ£¬ +// »òÊǾ­³£Ê¹Óõ«²»³£¸ü¸ÄµÄ +// ÌØ¶¨ÓÚÏîÄ¿µÄ°üº¬Îļþ -#if _MSC_VER > 1000 #pragma once -#endif // _MSC_VER > 1000 -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#ifndef _SECURE_ATL +#define _SECURE_ATL 1 +#endif + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // ´Ó Windows Í·ÖÐÅųý¼«ÉÙʹÓõÄ×ÊÁÏ +#endif + + +#pragma once + +// ÒÔϺ궨ÒåÒªÇóµÄ×îµÍƽ̨¡£ÒªÇóµÄ×îµÍƽ̨ +// ÊǾßÓÐÔËÐÐÓ¦ÓóÌÐòËùÐ蹦ÄÜµÄ Windows¡¢Internet Explorer µÈ²úÆ·µÄ +// ×îÔç°æ±¾¡£Í¨¹ýÔÚÖ¸¶¨°æ±¾¼°¸üµÍ°æ±¾µÄƽ̨ÉÏÆôÓÃËùÓпÉÓõŦÄÜ£¬ºê¿ÉÒÔ +// Õý³£¹¤×÷¡£ + +// Èç¹û±ØÐëÒªÕë¶ÔµÍÓÚÒÔÏÂÖ¸¶¨°æ±¾µÄƽ̨£¬ÇëÐÞ¸ÄÏÂÁж¨Òå¡£ +// Óйز»Í¬Æ½Ì¨¶ÔÓ¦ÖµµÄ×îÐÂÐÅÏ¢£¬Çë²Î¿¼ MSDN¡£ +#ifndef WINVER // Ö¸¶¨ÒªÇóµÄ×îµÍƽ̨ÊÇ Windows Vista¡£ +#define WINVER 0x0600 // ½«´ËÖµ¸ü¸ÄΪÏàÓ¦µÄÖµ£¬ÒÔÊÊÓÃÓÚ Windows µÄÆäËû°æ±¾¡£ +#endif + +#ifndef _WIN32_WINNT // Ö¸¶¨ÒªÇóµÄ×îµÍƽ̨ÊÇ Windows Vista¡£ +#define _WIN32_WINNT 0x0600 // ½«´ËÖµ¸ü¸ÄΪÏàÓ¦µÄÖµ£¬ÒÔÊÊÓÃÓÚ Windows µÄÆäËû°æ±¾¡£ +#endif + +#ifndef _WIN32_WINDOWS // Ö¸¶¨ÒªÇóµÄ×îµÍƽ̨ÊÇ Windows 98¡£ +#define _WIN32_WINDOWS 0x0410 // ½«´ËÖµ¸ü¸ÄΪÊʵ±µÄÖµ£¬ÒÔÊÊÓÃÓÚ Windows Me »ò¸ü¸ß°æ±¾¡£ +#endif + +#ifndef _WIN32_IE // Ö¸¶¨ÒªÇóµÄ×îµÍƽ̨ÊÇ Internet Explorer 7.0¡£ +#define _WIN32_IE 0x0700 // ½«´ËÖµ¸ü¸ÄΪÏàÓ¦µÄÖµ£¬ÒÔÊÊÓÃÓÚ IE µÄÆäËû°æ±¾¡£ +#endif + -#include -// TODO: reference additional headers your program requires here -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. -#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) diff --git a/ini/IniFileProcessor.cpp b/ini/IniFileProcessor.cpp new file mode 100644 index 0000000..027a899 --- /dev/null +++ b/ini/IniFileProcessor.cpp @@ -0,0 +1,32 @@ +/* + * IniFileProcessor class implementation file + * Author: Sun Junwen + * Version: 1.0.1 + */ +#include "stdafx.h" + +#include +#include +#include + +#include "IniFileProcessor.h" + +using namespace std; + +void IniFileProcessor::Save() +{ + ofstream out(m_strFileName.c_str()); + + if(out) + { + out << ToString(); + } + + out.close(); +} + +IniProcessor::IniMap IniFileProcessor::GetInfo(bool bProcSection, bool bRefresh) +{ + ifstream m_in(m_strFileName.c_str()); + return IniProcessor::GetInfo(m_in, bProcSection, bRefresh); +} diff --git a/ini/IniFileProcessor.h b/ini/IniFileProcessor.h new file mode 100644 index 0000000..6eed210 --- /dev/null +++ b/ini/IniFileProcessor.h @@ -0,0 +1,35 @@ +/* + * IniFileProcessor class header file + * Author: Sun Junwen + * Version: 1.0.1 + */ +#ifndef _INI_FILE_PROCESSOR_H_ +#define _INI_FILE_PROCESSOR_H_ + +#include "IniProcessor.h" +#include "strhelper.h" + +class IniFileProcessor: public IniProcessor +{ +public: + /* + * Constructor + * Specific the ini file name + */ + explicit IniFileProcessor(const sunjwbase::tstring& fileName) + { + m_strFileName = sunjwbase::tstrtostr(fileName); + } + + virtual void Save(); + + inline IniMap GetInfo(bool bSection) + { return GetInfo(bSection, true); } + + IniProcessor::IniMap GetInfo(bool bProcSection, bool bRefresh); + +private: + std::string m_strFileName; +}; + +#endif diff --git a/ini/IniProcessor.cpp b/ini/IniProcessor.cpp new file mode 100644 index 0000000..20e4337 --- /dev/null +++ b/ini/IniProcessor.cpp @@ -0,0 +1,194 @@ +/* + * IniProcessor class implementation file + * Author: Sun Junwen + * Version: 1.2.8 + */ +#include "stdafx.h" + +#include +#include +#include +#include +#include + +#include "IniProcessor.h" +#include "strhelper.h" + +using namespace std; +using namespace sunjwbase; + +IniProcessor::IniMap IniProcessor::GetInfo(istream& in, bool bProcSection, bool bRefresh) +{ + if(!bRefresh && m_iniMap.size() > 0) + return m_iniMap; + + m_iniMap.clear(); + + string line; + bool bSection = false; + bool bMultiLine = false; + string sectionName; + //IniValue sectionMap; + IniValue::StrMap sectionMap; + + string key; + string value; + + while(true) + { + if(!getline(in, line)) // eof + { + if(bProcSection && bSection) + { + AddSection(sectionName, sectionMap); + } + break; + } + + line = strtrim_right(line); + if(bMultiLine) + { + value.append(line); + if(value.length() > 0 && value[value.length() - 1] == '\\') + { + // value ½áβÊÇ \ ±íʾ¶àÐÐ + value[value.length() - 1] = '\n'; + bMultiLine = true; + } + else + { + bMultiLine = false; + if(bProcSection && bSection) + { + sectionMap[key] = value; + } + else + { + m_iniMap[key] = IniValue(value); + } + } + + continue; + } + line = strtrim(line); + + if(line.length() <= 1 || + line[0] == ';' || + line[0] == '#' || + (line[0] == '/' && line[1] == '/')) + continue; // ×¢ÊÍÐÐ + + if(bProcSection && + line[0] == '[' && + line[line.length() - 1] == ']') + { + if(bSection) + { + AddSection(sectionName, sectionMap); + } + + bSection = true; + sectionMap.clear(); + sectionName = line.length() - 2 > 0 ? + line.substr(1, line.length() - 2) : ""; + sectionName = strtrim(sectionName); + } + + size_t eqPos = line.find("="); + if(eqPos != string::npos) + { + key = line.substr(0, eqPos); + key = strtrim(key); + + value = eqPos + 1 >= line.length() ? + "" : line.substr(eqPos + 1); + value = strtrim(value); + if(value.length() > 0 && value[value.length() - 1] == '\\') + { + // value ½áβÊÇ \ ±íʾ¶àÐÐ + value[value.length() - 1] = '\n'; + bMultiLine = true; + continue; + } + else + bMultiLine = false; + + if(bProcSection && bSection) + { + sectionMap[key] = value; + } + else + { + m_iniMap[key] = IniValue(value); + } + } + } + + return m_iniMap; +} + +void IniProcessor::AddSection(const string& sectionName, const IniValue::StrMap& sectionMap) +{ + IniValue iniValue = m_iniMap[sectionName];// = sectionMap; + if(iniValue.IsStrValue()) + { + iniValue.SetMode(false); + iniValue.SetMapValue(sectionMap); + } + else + { + IniValue::StrMap::const_iterator itr = sectionMap.begin(); + for(; itr != sectionMap.end(); ++itr) + { + iniValue.Put((*itr).first, (*itr).second); + } + } + m_iniMap[sectionName] = iniValue; +} + +string IniProcessor::ToString(const IniProcessor::IniMap& map) const +{ + string ret(""); + + list sectionList; + + IniMap::const_iterator iniItr = map.begin(); + string line; + string key; + IniValue value; + for(; iniItr != map.end(); ++iniItr) + { + key = (*iniItr).first; + value = (*iniItr).second; + + if(value.IsStrValue()) + { + line = key; + line.append("="); + line.append(value.ToString()); + ret.append(line); + } + else + { + sectionList.push_back(*iniItr); + } + } + + while(!sectionList.empty()) + { + key = sectionList.front().first; + value = sectionList.front().second; + + line = "\n["; + line.append(key); + line.append("]\n"); + ret.append(line); + + line = value.ToString(); + ret.append(line); + + sectionList.pop_front(); + } + + return ret; +} diff --git a/ini/IniProcessor.h b/ini/IniProcessor.h new file mode 100644 index 0000000..a6c294e --- /dev/null +++ b/ini/IniProcessor.h @@ -0,0 +1,54 @@ +/* + * IniProcessor class header file + * Author: Sun Junwen + * Version: 1.2.8 + */ +#ifndef _INI_PROCESSOR_H_ +#define _INI_PROCESSOR_H_ + +#include +#include +#include + +#include "IniValue.h" +#include "unsortedmap.h" + +class IniProcessor +{ +public: + typedef UnsortedMap IniMap; + + /* + * Constructor + * Specific the ini file name + */ + IniProcessor() + {} + + virtual ~IniProcessor() + {} + + // Set value into map + void SetMap(const IniMap& map) + { m_iniMap = map; } + + // Save value into file + virtual void Save() = 0; + + // Convert value to string + inline std::string ToString() const + { return ToString(m_iniMap); } + std::string ToString(const IniMap& map) const; + +protected: + // Get info from istream + IniMap GetInfo(std::istream& in, bool bProcSection, bool bRefresh); + +private: + IniMap m_iniMap; + + // Add a section to map + void AddSection(const std::string& sectionName, const IniValue::StrMap& sectionMap); +}; + +#endif diff --git a/ini/IniValue.cpp b/ini/IniValue.cpp new file mode 100644 index 0000000..8d1a224 --- /dev/null +++ b/ini/IniValue.cpp @@ -0,0 +1,77 @@ +/* + * IniValue class implementation file + * Author: Sun Junwen + * Version: 1.1 + */ +#include "stdafx.h" + +#include +#include +#include + +#include "strhelper.h" +#include "IniValue.h" + +using namespace std; +using namespace sunjwbase; + +IniValue::StrMap IniValue::GetMapValue() const +{ + return mapValue; +} + +void IniValue::SetMapValue(const IniValue::StrMap& map) +{ + mapValue = map; +} + +string IniValue::GetStrValue() const +{ + return strValue; +} + +void IniValue::SetStrValue(const string& str) +{ + strValue = str; +} + +void IniValue::Put(const string& key, const string& value) +{ + mapValue[key] = value; +} + +string IniValue::ToString() const +{ + string ret(""); + + if(bStr) + { + ret.append(PreMultiLine(strValue)); + ret.append("\n"); + } + else + { + IniValue::StrMap::const_iterator itr = mapValue.begin(); + for(; itr != mapValue.end(); ++itr) + { + string line(""); + line.append((*itr).first); + line.append("="); + line.append(PreMultiLine((*itr).second)); + line.append("\n"); + ret.append(line); + } + } + + return ret; +} + +string IniValue::PreMultiLine(const string& value) const +{ + string ret(value); + ret = strreplace(ret, "\r\n", "\n"); + ret = strreplace(ret, "\\\n", "\\ \n"); + ret = strreplace(ret, "\n", "\\\n"); + + return ret; +} diff --git a/ini/IniValue.h b/ini/IniValue.h new file mode 100644 index 0000000..8328c89 --- /dev/null +++ b/ini/IniValue.h @@ -0,0 +1,61 @@ +/* + * IniValue class header file + * Author: Sun Junwen + * Version: 1.1 + */ +#ifndef _INI_VALUE_H_ +#define _INI_VALUE_H_ + +#include +#include + +#include "unsortedmap.h" + +class IniValue +{ +public: + typedef UnsortedMap StrMap; + + /* + * Constructors + * Default is string value + */ + explicit IniValue(bool bStr = true) + :bStr(bStr) + {}; + explicit IniValue(const std::string& strValue) + :bStr(true), strValue(strValue) + {}; + + // Get map value + StrMap GetMapValue() const; + // Set map value + void SetMapValue(const StrMap& map); + // Get string value + std::string GetStrValue() const; + // Set string value + void SetStrValue(const std::string& str); + + // Is string value or not + inline bool IsStrValue() const + { return bStr; } + // Set value mode, true is string, false is not string + inline void SetMode(bool bStr) + { this->bStr = bStr; } + + // Put key-value pair into map value + void Put(const std::string& key, const std::string& value); + + // Convert string value or map value to string + std::string ToString() const; + +private: + bool bStr; + std::string strValue; + IniValue::StrMap mapValue; + + std::string PreMultiLine(const std::string& value) const; + +}; + +#endif diff --git a/ini/strhelper.cpp b/ini/strhelper.cpp new file mode 100644 index 0000000..9f85983 --- /dev/null +++ b/ini/strhelper.cpp @@ -0,0 +1,312 @@ +/* + * strhelper implementation file + * Author: Sun Junwen + * Version: 1.3 + * Provides converting from tstring, string and wstring to each other + * And provides string's utf8 converting. + * Provides triming function to string and wstring. + * Provides replacing function to string and wstring. + * Provides newline fixing to string. + */ +#include "stdafx.h" + +#include + +#if defined (WIN32) +#include "Windows.h" +#endif + +#if defined (__APPLE__) || defined (UNIX) +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include "strhelper.h" + +namespace sunjwbase +{ +#if defined (WIN32) + // Windows convert + static std::string _wstrtostr(const std::wstring& wstr, UINT codePage) + { + // Convert a wstring to an string with specified code page + size_t strLen = WideCharToMultiByte(codePage, 0, wstr.c_str(), (int)wstr.length(), NULL, 0, NULL, NULL); + std::string strTo; + char *szTo = new char[strLen + 1]; + szTo[strLen] = '\0'; + WideCharToMultiByte(codePage, 0, wstr.c_str(), -1, szTo, (int)strLen, NULL, NULL); + strTo = szTo; + delete[] szTo; + return strTo; + } + + static std::wstring _strtowstr(const std::string& str, UINT codePage) + { + // Convert an string to a wstring with specified code page + size_t wstrLen = MultiByteToWideChar(codePage, 0, str.c_str(), -1, NULL, 0); + std::wstring wstrTo; + wchar_t *wszTo = new wchar_t[wstrLen + 1]; + wszTo[wstrLen] = L'\0'; + MultiByteToWideChar(codePage, 0, str.c_str(), -1, wszTo, (int)wstrLen); + wstrTo = wszTo; + delete[] wszTo; + return wstrTo; + } +#endif +} + +#if defined (__APPLE__) || defined (UNIX) +std::string sunjwbase::striconv(const std::string& input, + const std::string& to_code, + const std::string& from_code) +{ + char* inptr = new char[input.size() + 1]; + size_t inleft = input.size(); + size_t outleft = inleft * 4 + 1; // should be large enough + char* outptr = new char[outleft]; + bzero(outptr, outleft); + + strcpy(inptr, input.c_str()); + + iconv_t cd; // conversion descriptor + if ((cd = iconv_open(to_code.c_str(), from_code.c_str())) == (iconv_t) (-1)) + { + iconv_close(cd); // failed clean + return input; + } + + char* in = inptr; + char* out = outptr; + outleft = iconv(cd, &in, &inleft, &out, &outleft); + + iconv_close(cd); + + std::string strRet(outptr); + + delete[] inptr; + delete[] outptr; + + return strRet; +} +#endif + +/* + * ½« ascii ±àÂëµÄ wstring ת»»Îª utf8 ±àÂëµÄ string + */ +std::string sunjwbase::wstrtostrutf8(const std::wstring& wstr) +{ + // Convert a Unicode wstring to an ASCII string +#if defined (WIN32) + return _wstrtostr(wstr, CP_UTF8); +#endif +#if defined (__APPLE__) || defined (UNIX) + return striconv(wstrtostr(wstr), "UTF-8", "ASCII"); +#endif +} + +/* + * ½« utf8 ±àÂëµÄ string ת»»Îª wstring + * Èç¹ûÐèÒª°Ñ utf8 ±àÂëµÄ string ת»»Îª±¾µØ±àÂëµÄ string + * ÔÙµ÷ÓÃÒ»´Î wstrtostr + */ +std::wstring sunjwbase::strtowstrutf8(const std::string& str) +{ + // Convert an ASCII string to a Unicode wstring +#if defined (WIN32) + return _strtowstr(str, CP_UTF8); +#endif +#if defined (__APPLE__) || defined (UNIX) + return strtowstr(striconv(str, "ASCII", "UTF-8")); +#endif +} + +std::string sunjwbase::wstrtostr(const std::wstring& wstr) +{ + // Convert a wstring to an string +#if defined (WIN32) + return _wstrtostr(wstr, CP_ACP); +#endif +#if defined (__APPLE__) || defined (UNIX) + size_t num_chars = wcstombs(NULL, wstr.c_str(), 0); + char* char_buf = new char[num_chars + 1]; + wcstombs(char_buf, wstr.c_str(), wstr.size()); + std::string str(char_buf); + delete[] char_buf; + + return str; +#endif +} + +std::wstring sunjwbase::strtowstr(const std::string& str) +{ + // Convert an string to a wtring +#if defined (WIN32) + return _strtowstr(str, CP_ACP); +#endif +#if defined (__APPLE__) || defined (UNIX) + size_t num_chars = mbstowcs(NULL, str.c_str(), 0); + wchar_t* wct_buf = new wchar_t[num_chars + 1]; + mbstowcs(wct_buf, str.c_str(), str.size()); + std::wstring wstr(wct_buf, num_chars); + delete[] wct_buf; + + return wstr; +#endif +} + +std::string sunjwbase::strtrim_right(const std::string& s, const std::string& spaces) +{ + std::string d(s); + std::string::size_type i(d.find_last_not_of(spaces)); + if(i == std::string::npos) + return ""; + else + return d.erase(d.find_last_not_of(spaces) + 1); +} // end of trim_right + +std::string sunjwbase::strtrim_left(const std::string& s, const std::string& spaces) +{ + std::string d(s); + return d.erase(0, s.find_first_not_of(spaces)); +} // end of trim_left + +std::wstring sunjwbase::strtrim_right(const std::wstring& s, const std::wstring& spaces) +{ + std::wstring d(s); + std::wstring::size_type i(d.find_last_not_of(spaces)); + if(i == std::wstring::npos) + return L""; + else + return d.erase(d.find_last_not_of(spaces) + 1); +} + +std::wstring sunjwbase::strtrim_left(const std::wstring& s, const std::wstring& spaces) +{ + std::wstring d(s); + return d.erase(0, s.find_first_not_of(spaces)); +} + +std::string sunjwbase::strreplace(const std::string& base, const std::string& src, const std::string& des) +{ + std::string ret(base); + std::string::size_type pos = 0; + std::string::size_type srcLen = src.size(); + std::string::size_type desLen = des.size(); + pos = ret.find(src, pos); + while((pos != std::string::npos)) + { + ret.replace(pos, srcLen, des); + pos = ret.find(src, pos + desLen); + } + + return ret; +} + +std::wstring sunjwbase::strreplace(const std::wstring& base, const std::wstring& src, const std::wstring& des) +{ + std::wstring ret(base); + std::wstring::size_type pos = 0; + std::wstring::size_type srcLen = src.size(); + std::wstring::size_type desLen = des.size(); + pos = ret.find(src, pos); + while((pos != std::wstring::npos)) + { + ret.replace(pos, srcLen, des); + pos = ret.find(src, pos + desLen); + } + + return ret; +} + +std::string sunjwbase::fixnewline(const std::string& str) +{ + std::string ret; + std::string strRepairSrc(""), strRepairDst(""); + // ÐÞÀí»»Ðзû, /10->/13/10, /13/13/10->/13/10 + strRepairSrc += (char)10; + strRepairDst += (char)13; + strRepairDst += (char)10; + ret = strreplace(str, strRepairSrc, strRepairDst); + strRepairSrc = (char)13; + strRepairSrc += (char)13; + strRepairSrc += (char)10; + ret = strreplace(ret, strRepairSrc, strRepairDst); + // ÐÞÀí»»Ðзû, /13->/13/10, /13/10/10->/13/10 + strRepairSrc = ""; + strRepairDst = ""; + strRepairSrc += (char)13; + strRepairDst += (char)13; + strRepairDst += (char)10; + ret = strreplace(ret, strRepairSrc, strRepairDst); + strRepairSrc = (char)13; + strRepairSrc += (char)10; + strRepairSrc += (char)10; + ret = strreplace(ret, strRepairSrc, strRepairDst); + return ret; +} + +std::string sunjwbase::str_upper(const std::string& str) +{ + std::string ret(str); + std::transform(ret.begin(), ret.end(), ret.begin(), ::toupper); + return ret; +} + +std::string sunjwbase::str_lower(const std::string& str) +{ + std::string ret(str); + std::transform(ret.begin(), ret.end(), ret.begin(), ::tolower); + return ret; +} + +std::string sunjwbase::itostr(int num, int idx /* = 10 */) +{ + if(idx > 16) + idx = 16; + char temp[2] = {0}; + std::string ret; + while(1) + { + int n = num % idx; + if(n < 10) + temp[0] = n + '0'; + else + temp[0] = n - 10 + 'A'; + ret = temp + ret; + num /= idx; + if(num == 0) + break; + } + + return ret; +} + +std::string sunjwbase::strappendformat(std::string& str, const char *format, ...) +{ + int size = 100; + std::string temp; + va_list vl; + while (1) { + temp.resize(size); + va_start(vl, format); + int n = vsnprintf((char *)temp.c_str(), size, format, vl); + va_end(vl); + if (n > -1 && n < size) { + temp.resize(n); + break; + } + if (n > -1) + size = n + 1; // not large enough + else + size *= 2; + } + str.append(temp); + + return str; +} diff --git a/ini/strhelper.h b/ini/strhelper.h new file mode 100644 index 0000000..3b33be2 --- /dev/null +++ b/ini/strhelper.h @@ -0,0 +1,182 @@ +/* + * strhelper header file + * Author: Sun Junwen + * Version: 1.3 + * Provides converting from tstring, string and wstring to each other + * And provides string's utf8 converting. + * Provides triming function to string and wstring. + * Provides replacing function to string and wstring. + * Provides newline fixing to string. + */ +#ifndef _STR_HELPER_H_ +#define _STR_HELPER_H_ +#include +#include +#include + +namespace sunjwbase +{ + // define the tstring only for WIN32 platform +#if defined(WIN32) && (defined(UNICODE) || defined(_UNICODE)) +#define _UNICODE_HELPER // use _UNICODE_HELPER internally + typedef std::wstring tstring; +#else + typedef std::string tstring; +#endif + +#if defined (WIN32) + typedef __int64 INT64; +#endif +#if defined (__APPLE__) || defined (UNIX) + typedef long long INT64; +#endif + + // converting part + /* + * ½« ascii ±àÂëµÄ wstring ת»»Îª utf8 ±àÂëµÄ string + */ + std::string wstrtostrutf8(const std::wstring& wstr); + /* + * ½« utf8 ±àÂëµÄ string ת»»Îª wstring + * Èç¹ûÐèÒª°Ñ utf8 ±àÂëµÄ string ת»»Îª±¾µØ±àÂëµÄ string + * ÔÙµ÷ÓÃÒ»´Î wstrtostr + */ + std::wstring strtowstrutf8(const std::string& str); + + std::string wstrtostr(const std::wstring& wstr); + std::wstring strtowstr(const std::string& str); + +#if defined (__APPLE__) || defined (UNIX) + std::string striconv(const std::string& input, + const std::string& to_code, + const std::string& from_code); +#endif + + // ½«±¾µØ±àÂëµÄ string ת»»³É utf8 ±àÂëµÄ string + inline std::string utf8conv(std::string& strAscii) + { +#if defined (WIN32) + return wstrtostrutf8(strtowstr(strAscii)); +#endif +#if defined (__APPLE__) || defined (UNIX) + // current only support GB + return striconv(strAscii, "UTF-8", "GBK"); +#endif + } + // ½« utf8 ±àÂëµÄ string ת»»³É±¾µØ±àÂëµÄ string + inline std::string asciiconv(std::string& strUtf8) + { +#if defined (WIN32) + return wstrtostr(strtowstrutf8(strUtf8)); +#endif +#if defined (__APPLE__) || defined (UNIX) + // current only support GB + return striconv(strUtf8, "GBK", "UTF-8"); +#endif + } + + inline std::string tstrtostr(const tstring& tstr) + { +#if defined(_UNICODE_HELPER) + return wstrtostr(tstr); +#else + return tstr; +#endif + } + + inline std::wstring tstrtowstr(const tstring& tstr) + { +#if defined(_UNICODE_HELPER) + return tstr; +#else + return strtowstr(tstr); +#endif + } + + inline sunjwbase::tstring strtotstr(const std::string& str) + { +#if defined(_UNICODE_HELPER) + return strtowstr(str); +#else + return str; +#endif + } + + inline sunjwbase::tstring wstrtotstr(const std::wstring& wstr) + { +#if defined(_UNICODE_HELPER) + return wstr; +#else + return wstrtostr(wstr); +#endif + } + // converting part + + // triming part + const std::string SPACES(" \t\r\n"); + const std::wstring WSPACES(L" \t\r\n"); + + // string version + std::string strtrim_right(const std::string& s, const std::string& spaces = SPACES); + std::string strtrim_left(const std::string& s, const std::string& spaces = SPACES); + inline std::string strtrim(const std::string& s, const std::string& spaces = SPACES) + { return strtrim_left(strtrim_right(s, spaces), spaces); } + + // wstring version + std::wstring strtrim_right(const std::wstring& s, const std::wstring& spaces = WSPACES); + std::wstring strtrim_left(const std::wstring& s, const std::wstring& spaces = WSPACES); + inline std::wstring strtrim(const std::wstring& s, const std::wstring& spaces = WSPACES) + { return strtrim_left(strtrim_right(s, spaces), spaces); } + // triming part + + // replacing part + std::string strreplace(const std::string& base, const std::string& src, const std::string& des); + std::wstring strreplace(const std::wstring& base, const std::wstring& src, const std::wstring& des); + // replacing part + + // fixing + std::string fixnewline(const std::string& str); + // fixing + + // upper and lower + std::string str_upper(const std::string& str); + std::string str_lower(const std::string& str); + + // searching part + // case insensitive equal for ci_strfind + // templated version of ci_equal so it could work with both char and wchar_t + template + struct strequal_ci + { + strequal_ci( const std::locale& loc ):m_loc(loc) + {} + + bool operator()(charT ch1, charT ch2) + { + return std::toupper(ch1, m_loc) == std::toupper(ch2, m_loc); + } + private: + const std::locale& m_loc; + }; + + // case insensitive search + template + INT64 strfind_ci(const T& str, const T& substr, const std::locale& loc = std::locale()) + { + typename T::const_iterator it = std::search(str.begin(), str.end(), + substr.begin(), substr.end(), + strequal_ci(loc)); + if (it != str.end()) + return it - str.begin(); + else + return -1; // not found + } + + // itostr + std::string itostr(int num, int idx = 10); + // format append for std::string + std::string strappendformat(std::string& str, const char *format, ...); +} + + +#endif diff --git a/ini/unsortedmap.h b/ini/unsortedmap.h new file mode 100644 index 0000000..3f2920a --- /dev/null +++ b/ini/unsortedmap.h @@ -0,0 +1,113 @@ +/* unsortedmap.h + 2013-5-26 + Version: 0.1 + +Copyright (c) 2012- SUN Junwen + +¶Ô std::list > µÄ·â×° +ŬÁ¦ÊµÏÖ std::map µÄÌØÐÔ£¬²¢Ìṩ FIFO µü´úÆ÷ +¶ÔÓÚÔªËØµÄËÑË÷ ²åÈë ɾ³ý ²Ù×÷¶¼ÊÇ O(n) µÄ +ʱ¼ä¸´ÔÓ¶È +ÐÔÄÜ»ù±¾ÊÇÒ»¸ö std::list +²Ù×÷ÌØÐÔÀàËÆ std::map +*/ +#ifndef _UNSORTED_MAP_H_ +#define _UNSORTED_MAP_H_ + +#include +#include + +template +class UnsortedMap +{ +public: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair<_Key, _Tp> pair_type; + typedef std::list unsorted_map; + typedef typename unsorted_map::iterator iterator; + typedef typename unsorted_map::const_iterator const_iterator; + typedef typename unsorted_map::size_type size_type; + + UnsortedMap() + {} + virtual ~UnsortedMap() + {} + + // ²Ù×÷½Ó¿Ú¶¼ÊÇ¶Ô std::list µÄ·â×° + inline size_type size() + { return m_list.size(); } + + void push_front(const pair_type& pair) + { + erase(pair.first); + m_list.push_front(pair); + } + + void push_back(const pair_type& pair) + { + erase(pair.first); + m_list.push_back(pair); + } + + iterator insert(iterator itr, const pair_type& pair) + { + erase(pair.first); + return m_list.insert(itr, pair); + } + + iterator erase(const key_type& key) + { + typename unsorted_map::iterator itr = find(key); + if(itr != end()) + itr = erase(itr); + + return itr; + } + + inline iterator erase(iterator itr) + { return m_list.erase(itr); } + inline void clear() + { m_list.clear(); } + + inline const_iterator begin() const + { return m_list.begin(); } + inline iterator begin() + { return m_list.begin(); } + + inline const_iterator end() const + { return m_list.end(); } + inline iterator end() + { return m_list.end(); } + + iterator find(const key_type& key) + { + typename unsorted_map::iterator itr = m_list.begin(); + for(; itr != m_list.end(); ++itr) + { + if(key == itr->first) + return itr; + } + + return m_list.end(); + } + + // Ö»ÄÜÌṩ O(n) µÄÐÔÄÜ + mapped_type& operator[](const key_type& key) + { + typename unsorted_map::iterator itr = find(key); + if(itr == m_list.end()) + { + // ûÓÐ, ²åÈëÒ»¸ö + m_list.push_back(pair_type(key, mapped_type())); + itr = m_list.end(); + --itr; + } + return (*itr).second; + } + +private: + unsorted_map m_list; +}; + +#endif diff --git a/taskbar.cpp b/taskbar.cpp index a368d68..0646d89 100755 --- a/taskbar.cpp +++ b/taskbar.cpp @@ -1,18 +1,24 @@ #define _WIN32_IE 0x0500 +#include "stdafx.h" + +#include #include #include #include #include #include #include +#include #include "psapi.h" #include "resource.h" +#include "ini/IniFileProcessor.h" #pragma comment(lib, "shell32.lib") #pragma comment(lib, "psapi.lib") #pragma comment(lib, "advapi32.lib") #pragma comment(lib, "wininet.lib") +#pragma comment(lib, "Ws2_32.lib") #ifndef INTERNET_OPTION_PER_CONNECTION_OPTION @@ -62,37 +68,40 @@ extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow(); HINSTANCE hInst; HWND hWnd; HWND hConsole; -TCHAR szTitle[64] = L""; -TCHAR szWindowClass[16] = L"taskbar"; -TCHAR szCommandLine[1024] = L""; -TCHAR szTooltip[512] = L""; -TCHAR szBalloon[512] = L""; -TCHAR szEnvironment[1024] = L""; -TCHAR szProxyString[2048] = L""; +TCHAR szTitle[64] = _T(""); +TCHAR szWindowClass[16] = _T("taskbar"); +TCHAR szCommandLine[1024] = _T(""); +TCHAR szTooltip[512] = _T(""); +TCHAR szBalloon[512] = _T(""); +TCHAR szEnvironment[1024] = _T(""); +TCHAR szProxyString[2048] = _T(""); TCHAR *lpProxyList[8] = {0}; volatile DWORD dwChildrenPid; +BOOL fMinized = FALSE; +std::string strIp; +int iPort; -static DWORD GetProcessId(HANDLE hProcess) +static DWORD GetProcessIdGae(HANDLE hProcess) { // https://gist.github.com/kusma/268888 typedef DWORD (WINAPI *pfnGPI)(HANDLE); typedef ULONG (WINAPI *pfnNTQIP)(HANDLE, ULONG, PVOID, ULONG, PULONG); static int first = 1; - static pfnGPI GetProcessId; + static pfnGPI pGetProcessId; static pfnNTQIP ZwQueryInformationProcess; if (first) { first = 0; - GetProcessId = (pfnGPI)GetProcAddress( + pGetProcessId = (pfnGPI)GetProcAddress( GetModuleHandleW(L"KERNEL32.DLL"), "GetProcessId"); - if (!GetProcessId) + if (!pGetProcessId) ZwQueryInformationProcess = (pfnNTQIP)GetProcAddress( GetModuleHandleW(L"NTDLL.DLL"), "ZwQueryInformationProcess"); } - if (GetProcessId) - return GetProcessId(hProcess); + if (pGetProcessId) + return pGetProcessId(hProcess); if (ZwQueryInformationProcess) { struct @@ -117,11 +126,12 @@ BOOL ShowTrayIcon(LPCTSTR lpszProxy, DWORD dwMessage=NIM_ADD) nid.hWnd = hWnd; nid.uID = NID_UID; nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; - nid.dwInfoFlags=NIIF_INFO; + nid.dwInfoFlags = NIIF_INFO; nid.uCallbackMessage = WM_TASKBARNOTIFY; nid.hIcon = LoadIcon(hInst, (LPCTSTR)IDI_SMALL); - nid.uFlags |= NIF_INFO; - nid.uTimeoutAndVersion = 3 * 1000 | NOTIFYICON_VERSION; + if(!fMinized) + nid.uFlags |= NIF_INFO; + //nid.uTimeoutAndVersion = 3 * 1000 | NOTIFYICON_VERSION; lstrcpy(nid.szInfoTitle, szTitle); if (lpszProxy && lstrlen(lpszProxy) > 0) { @@ -155,7 +165,7 @@ LPCTSTR GetWindowsProxy() DWORD dwData = 0; DWORD dwSize = sizeof(DWORD); - if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, + if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 0, KEY_READ | 0x0200, @@ -375,7 +385,7 @@ BOOL ExecCmdline() BOOL bRet = CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi); if(bRet) { - dwChildrenPid = GetProcessId(pi.hProcess); + dwChildrenPid = GetProcessIdGae(pi.hProcess); } else { @@ -499,7 +509,29 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } break; case WM_TIMER: - CheckMemoryLimit(); + nID = LOWORD(wParam); + if(nID == 4) + { + SOCKET connSocket; + connSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + sockaddr_in gaePort; + gaePort.sin_family = AF_INET; + gaePort.sin_addr.s_addr = inet_addr(strIp.c_str()); + gaePort.sin_port = htons(iPort); + + int ret = connect(connSocket, (SOCKADDR *)&gaePort, sizeof (gaePort)); + if (ret == 0) { + ShowWindow(hConsole, SW_HIDE); + KillTimer(hWnd, 4); + } + + closesocket(connSocket); + } + else + { + CheckMemoryLimit(); + } break; case WM_DESTROY: PostQuitMessage(0); @@ -540,11 +572,40 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpCmdLine, int nCmd { return FALSE; } + + IniFileProcessor::IniMap map; + + IniFileProcessor fileProcessor(_T("proxy.ini")); + map = fileProcessor.GetInfo(true); + + IniValue::StrMap mapListen = map["listen"].GetMapValue(); + strIp = mapListen["ip"]; + std::string strPort = mapListen["port"]; + iPort = atoi(strPort.c_str()); + + // Initialize winsock + WORD wVersionRequested; + WSADATA wsaData; + wVersionRequested = MAKEWORD(2, 2); + WSAStartup(wVersionRequested, &wsaData); + + if(_tcscmp(lpCmdLine, _T("--min")) == 0) + { + fMinized = TRUE; + } + CreateConsole(); SetEenvironment(); ExecCmdline(); ShowTrayIcon(GetWindowsProxy()); + SetTimer(hWnd, 0, 30 * 1000, NULL); + + if(fMinized) + { + SetTimer(hWnd, 4, 2000, NULL); + } + while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); diff --git a/taskbar.ncb b/taskbar.ncb deleted file mode 100644 index 2696200..0000000 Binary files a/taskbar.ncb and /dev/null differ diff --git a/taskbar.sln b/taskbar.sln new file mode 100644 index 0000000..c423944 --- /dev/null +++ b/taskbar.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "taskbar", "taskbar.vcproj", "{2643765D-4F1E-4208-92CA-197570938FD3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2643765D-4F1E-4208-92CA-197570938FD3}.Debug|Win32.ActiveCfg = Debug|Win32 + {2643765D-4F1E-4208-92CA-197570938FD3}.Debug|Win32.Build.0 = Debug|Win32 + {2643765D-4F1E-4208-92CA-197570938FD3}.Release|Win32.ActiveCfg = Release|Win32 + {2643765D-4F1E-4208-92CA-197570938FD3}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/taskbar.vcproj b/taskbar.vcproj new file mode 100644 index 0000000..1d48768 --- /dev/null +++ b/taskbar.vcproj @@ -0,0 +1,348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +