// Takes a snapshot of the specified processes
// CuToolhelp.h
class CuToolhelp
{
HANDLE m_hSnapshot;
public:
CuToolhelp();
virtual ~CuToolhelp();
BOOL CreateSnapshot(DWORD dwFlags, DWORD dwProcessID = 0);
void CloseSnapshot();
BOOL ProcessFirst(PPROCESSENTRY32 ppe) const;
BOOL ProcessNext(PPROCESSENTRY32 ppe) const;
BOOL ProcessFind(DWORD dwProcessID, PPROCESSENTRY32 ppe) ;
BOOL ProcessFind(wstring strExeFile, PPROCESSENTRY32 ppe) ;
};
// CuToolhelp.cpp
CuToolhelp::CuToolhelp()
:m_hSnapshot(INVALID_HANDLE_VALUE)
{
}
CuToolhelp::~CuToolhelp()
{
CloseSnapshot();
}
BOOL CuToolhelp::CreateSnapshot(DWORD dwFlags, DWORD dwProcessID)
{
CloseSnapshot();
if( dwFlags == 0 )
{
m_hSnapshot = INVALID_HANDLE_VALUE;
}
else
{
m_hSnapshot = CreateToolhelp32Snapshot(dwFlags, dwProcessID);
}
return (m_hSnapshot != INVALID_HANDLE_VALUE);
}
void CuToolhelp::CloseSnapshot()
{
if( m_hSnapshot != INVALID_HANDLE_VALUE )
CloseToolhelp32Snapshot(m_hSnapshot);
}
BOOL CuToolhelp::ProcessFirst(PPROCESSENTRY32 ppe) const
{
BOOL fOk = ::Process32First(m_hSnapshot, ppe);
// Remove the "[ System Process]" (PID = 0)
if( fOk && (ppe->th32ProcessID == 0 ))
fOk = ProcessNext(ppe);
return (fOk);
}
BOOL CuToolhelp::ProcessNext(PPROCESSENTRY32 ppe) const
{
BOOL fOk = ::Process32Next(m_hSnapshot, ppe);
// Remove the "[ System Process]" (PID = 0)
if( fOk && (ppe->th32ProcessID == 0 ))
fOk = ProcessNext(ppe);
return (fOk);
}
BOOL CuToolhelp::ProcessFind(DWORD dwProcessID, PPROCESSENTRY32 ppe)
{
BOOL bFound = FALSE;
for( BOOL fOk = ProcessFirst(ppe); fOk; fOk = ProcessNext(ppe) )
{
bFound = ( ppe->th32ProcessID == dwProcessID );
if( bFound )
break;
}
return (bFound);
}
BOOL CuToolhelp::ProcessFind(wstring strExeFile, PPROCESSENTRY32 ppe)
{
BOOL bFound = FALSE;
for( BOOL fOk = ProcessFirst(ppe); fOk; fOk = ProcessNext(ppe) )
{
bFound = (strExeFile == ppe->szExeFile);
if( bFound )
break;
}
return (bFound);
}
2010年1月31日 星期日
CuToolhelp - Takes a snapshot of the specified processes
2010年1月30日 星期六
TuPowerNotification -
//
class PowerNotificationTest
{
private:
TuPowerNotification<PowerNotificationTest> uPowerNotification;
public:
PowerNotificationTest() {}
~PowerNotificationTest() {}
void Init()
{
//初始化 TuPowerNotification
uPowerNotification.CombineElement(this, PowerNotificationTest::PowerNotify);
uPowerNotification.RequestPowerNotifications();
}
void PowerNotify(PPOWER_BROADCAST ppower_broadcast)
{
switch(ppower_broadcast->Message)
{
//取得 power status
case PBT_TRANSITION:
break;
case PBT_RESUME:
break;
case PBT_POWERSTATUSCHANGE:
break;
case PBT_POWERINFOCHANGE:
break;
}
}
// TuPowerNotification.h
template <typename T>
class TuPowerNotification : public CuPowerNotification
{
typedef void ( T::*POWER_NOTIFICATION_PROC)(PPOWER_BROADCAST ppower_broadcast);
POWER_NOTIFICATION_PROC m_fpPowerNotificationProc;
T *m_pElement;
public:
TuPowerNotification();
~TuPowerNotification();
void CombineElement(T *pElement, POWER_NOTIFICATION_PROC fpTimeOutProc);
virtual void OnPowerNotification(PPOWER_BROADCAST ppower_broadcast);
};
template <typename T>
TuPowerNotification<T>::TuPowerNotification()
:m_fpPowerNotificationProc(NULL)
,m_pElement(NULL)
{
}
template <typename T>
TuPowerNotification<T>::~TuPowerNotification()
{
}
template <typename T>
void TuPowerNotification<T>::OnPowerNotification(PPOWER_BROADCAST ppower_broadcast)
{
if(m_fpPowerNotificationProc)
(m_pElement->*m_fpPowerNotificationProc)(ppower_broadcast);
}
template <typename T>
void TuPowerNotification<T>::CombineElement(T *pElement, POWER_NOTIFICATION_PROC fpTimeOutProc)
{
m_pElement = pElement;
m_fpPowerNotificationProc = fpTimeOutProc;
}
2010年1月29日 星期五
CuFileLex - 文字檔剖析
// config.sys
--------------------------------------------
從某一隻ASE檔載入器中抓出來的,
CuFileLex 跟CuStringList 相比, 能載入較多格式的文字串, 組合後可以使用更豐富的設定檔
上面有兩大段分別支援一般文字檔跟UNICODE文字檔, 很顯示需要重構! 現在沒打算重構!
重構時間點在何時呢? 在他出錯的時後, 或是下次程式碼"review"的時後!
--------------------------------------------
TOTAL_ELEMENT_NUM 8
ELEMENT_NUM 1
ELEMENT_TYPE "element"
ELEMENT_NAME "background"
ELEMENT_POINT 0 0
ELEMENT_NEEDALPHA 0
TOTAL_PHOTO_NUM 1
PHOTO_NAME "media_bg.bmp" 4
ELEMENT_END
ELEMENT_NUM 2
ELEMENT_TYPE "button"
ELEMENT_NAME "close"
ELEMENT_POINT 3 3
ELEMENT_NEEDALPHA 1
TOTAL_PHOTO_NUM 4
PHOTO_NAME "close.bmp" 0
PHOTO_NAME "close_alpha.bmp" 1
PHOTO_NAME "close_down.bmp" 2
PHOTO_NAME "close_down_alpha.bmp" 3
ELEMENT_END
BUTTON_END
ELEMENT_NUM 3
ELEMENT_TYPE "commandbt"
ELEMENT_NAME "goto-photo"
ELEMENT_POINT 208 85
ELEMENT_NEEDALPHA 1
TOTAL_PHOTO_NUM 4
PHOTO_NAME "photoviewer_Icon.bmp" 13
PHOTO_NAME "photoviewer_Icon_alpha.bmp" 14
PHOTO_NAME "photoviewer_animation01.bmp" 15
PHOTO_NAME "photoviewer_animation01_alpha.bmp" 16
ELEMENT_END
BUTTON_END
COMMANDBT_ACTIVE_NAME "photoviewv350.exe"
COMMANDBT_END
ELEMENT_NUM 4
ELEMENT_TYPE "commandbt"
ELEMENT_NAME "goto-music"
ELEMENT_POINT 14 85
ELEMENT_NEEDALPHA 1
TOTAL_PHOTO_NUM 4
PHOTO_NAME "music_Icon.bmp" 9
PHOTO_NAME "music_Icon_alpha.bmp" 10
PHOTO_NAME "music_animation01.bmp" 11
PHOTO_NAME "music_animation01_alpha.bmp" 12
ELEMENT_END
BUTTON_END
COMMANDBT_ACTIVE_NAME "musicv350.exe"
COMMANDBT_END
ELEMENT_NUM 5
ELEMENT_TYPE "commandbt"
ELEMENT_NAME "goto-video"
ELEMENT_POINT 113 85
ELEMENT_NEEDALPHA 1
TOTAL_PHOTO_NUM 4
PHOTO_NAME "movie_Icon.bmp" 5
PHOTO_NAME "movie_Icon_alpha.bmp" 6
PHOTO_NAME "movie_animation01.bmp" 7
PHOTO_NAME "movie_animation01_alpha.bmp" 8
ELEMENT_END
BUTTON_END
COMMANDBT_ACTIVE_NAME "video\videov350.exe"
COMMANDBT_END
ELEMENT_NUM 6
ELEMENT_TYPE "statictext"
"PhotoView"
"text-photoview"
208 180 98 30
12
255 255 255
ELEMENT_NUM 7
ELEMENT_TYPE "statictext"
"Music"
"text-music"
14 180 98 30
12
255 255 255
ELEMENT_NUM 8
ELEMENT_TYPE "statictext"
"Video"
"text-Video"
113 180 98 30
12
255 255 255
//
// CuFileLex.h
class CuFileLex
{
BOOL m_bUnicode;
BOOL _IsUnicodeFile();
int _lexw(void);
int _lexa(void);
CuFile m_File;
public:
CuFileLex(void);
~CuFileLex(void);
BOOL Open( LPCSTR lpszFileName, LPCSTR lpszOpenMode);
virtual BOOL Open( LPCTSTR lpszFileName, LPCTSTR lpszOpenMode);
int _type; // 最後呼叫 _lex() 的字串類型
wstring _text; // 將讀到的字串 放到這裡
enum {UNKNOW = 0, INTEGER = 1, FLOAT, SYMBOL, INDEX, STRING, NODE, BLOCKSTART, BLOCKEND};
// 讀一段字 並分析字串 傳回字串類型
int _lex(void);
void _readInt(int &i);
void _readInt3(int i[3]);
void _readInt4(int i[4]);
void _readFloat(float &f);
void _readFloat3(float f[3]);
void _readSymbol(wstring &str);
void _readIndex();
void _readString(wstring &str);
void _readNode();
void _readBlockStart();
int _skip();
};
// CuFileLex.cpp
CuFileLex::CuFileLex(void) : _type(UNKNOW)
{
}
CuFileLex::~CuFileLex(void)
{
}
int CuFileLex::_lex(void)
{
// static
// char check[] = "-0123456789._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"{}:*";
//"12345678901234567890123456789012345678901234567890123456789012345 678901234
//"0 1 2 3 4 5 6 7
// 1~11 = INTEGER
// 12 = FLOAT
// 13~65 = SYMBOL
// 69 = INDEX
// 66 = STRING
// 70 = NODE
// 67 = BLOCKSTART
// 68 = BLOCKEND
// 字串分析的權位 左邊比較低 右邊比較高
// enum {UNKNOW = 0, INTEGER = 1, FLOAT, SYMBOL, INDEX, STRING, NODE, BLOCKSTART, BLOCKEND};
_text = L"";
int result;
int current_type = 0;
int type = UNKNOW; // 分析字串的類型
bool baString = false; // 當正在讀字串時 會一直讀到 下一個 '\"'
// 排除前置空白 換行 定位 字元
do
{
result = m_File.get();
}while( result != EOF && (result == 9 || result == 32 || result == 13 || result == 10 ));
while(result != EOF)
{
// ---------------+---------------
// 字串種類判段
if( baString )
{
if( result == 0x22 )
baString = !baString;
}else if( (result >= 0x41 && result <= 0x5a) ||
(result >= 0x61 && result <= 0x7a) ||
(result == 0x5f) )
current_type = SYMBOL;
else if( (result >= 0x30 && result <= 0x39) || result == 0x2d )
current_type = INTEGER;
else
{
switch( result )
{
case 0x2e:
current_type = FLOAT;
break;
case 0x3a:
current_type = INDEX;
break;
case 0x22:
current_type = STRING;
baString = !baString;
break;
case 0x2a:
current_type = NODE;
break;
case 0x7b:
current_type = BLOCKSTART;
break;
case 0x7d:
current_type = BLOCKEND;
break;
default:
{
_type = type;
return type;
}
}
}
if( type < current_type )
type = current_type;
// ---------------+---------------
_text += result;
result = m_File.get();
}
_type = type;
return type;
}
int CuFileLex::_lexw(void)
{
// static
// TCHAR check[] = L"-0123456789._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"{}:*";
//"12345678901234567890123456789012345678901234567890123456789012345 678901234
//"0 1 2 3 4 5 6 7
// 1~11 = INTEGER
// 12 = FLOAT
// 13~65 = SYMBOL
// 69 = INDEX
// 66 = STRING
// 70 = NODE
// 67 = BLOCKSTART
// 68 = BLOCKEND
// 字串分析的權位 左邊比較低 右邊比較高
// enum {UNKNOW = 0, INTEGER = 1, FLOAT, SYMBOL, INDEX, STRING, NODE, BLOCKSTART, BLOCKEND};
_text = L"";
WORD result;
int current_type = 0;
int type = UNKNOW; // 分析字串的類型
bool baString = false; // 當正在讀字串時 會一直讀到 下一個 '\"'
int nSizeT = 0;
// 排除前置空白 換行 定位 字元
do
{
nSizeT = m_File.Read(&result, sizeof(result) );
}while( nSizeT != 0 && (result != EOF && result == 9 || result == 32 || result == 13 || result == 10 ));
while(result != EOF && nSizeT != 0 )
{
// ---------------+---------------
// 字串種類判段
if( baString )
{
if( result == 0x22 )
baString = !baString;
}else if( (result >= 0x41 && result <= 0x5a) ||
(result >= 0x61 && result <= 0x7a) ||
(result == 0x5f) )
current_type = SYMBOL;
else if( (result >= 0x30 && result <= 0x39) || result == 0x2d )
current_type = INTEGER;
else
{
switch( result )
{
case 0x2e:
current_type = FLOAT;
break;
case 0x3a:
current_type = INDEX;
break;
case 0x22:
current_type = STRING;
baString = !baString;
break;
case 0x2a:
current_type = NODE;
break;
case 0x7b:
current_type = BLOCKSTART;
break;
case 0x7d:
current_type = BLOCKEND;
break;
default:
{
_type = type;
return type;
}
}
}
if( type < current_type )
type = current_type;
// ---------------+---------------
_text += result;
nSizeT = m_File.Read(&result, sizeof(result) );
}
_type = type;
return type;
}
// 讀一段字 並分析字串 傳回字串類型
int CuFileLex::_lex(void)
{
if( m_bUnicode )
return _lexw();
else
return _lexa();
return m_bUnicode ? _lexw() : _lexa();
}
// 讀一段字 並分析字串 傳回字串類型
void CuFileLex::_readInt(int &i)
{
_lex();
Assert( _type == INTEGER , L"CuFileLex::_readInt: Expected an integer\n");
swscanf(_text.c_str(), L"%i", &i);
}
void CuFileLex::_readInt3(int i[3])
{
_readInt(i[0]);
_readInt(i[1]);
_readInt(i[2]);
}
void CuFileLex::_readInt4(int i[4])
{
_readInt(i[0]);
_readInt(i[1]);
_readInt(i[2]);
_readInt(i[3]);
}
void CuFileLex::_readFloat(float &f)
{
_lex();
Assert( _type == FLOAT , L"CuFileLex::_readFloat: Expected an float\n");
swscanf(_text.c_str(), L"%f", &f);
}
void CuFileLex::_readFloat3(float f[3])
{
_readFloat(f[0]);
_readFloat(f[1]);
_readFloat(f[2]);
}
void CuFileLex::_readSymbol(wstring &str)
{
_lex();
Assert( _type == SYMBOL , L"CuFileLex::_readSymbol: Expected a symbol\n");
str = _text;
}
void CuFileLex::_readIndex()
{
_lex();
Assert( _type == INDEX , L"CuFileLex::_readIndex: Expected a index\n");
}
void CuFileLex::_readString(wstring &str)
{
_lex();
Assert( _type == STRING , L"CuFileLex::_readString: Expected a string\n");
// 脫溢字串兩頭的 雙引號
if( _text.size() != 0 )
str.assign( _text, 1, _text.size() - 2);
}
void CuFileLex::_readNode()
{
_lex();
Assert( _type == NODE , L"CuFileLex::_readNode: Expected a node\n");
}
void CuFileLex::_readBlockStart()
{
_lex();
Assert( _type == BLOCKSTART , L"CuFileLex::_readBlockStart: Expected an open brace\n");
}
int CuFileLex::_skip()
{
int nextToken;
int depth = 0;
char neednext = 1;
do {
if(neednext)
nextToken = _lex();
else
neednext = 1;
if(nextToken == BLOCKSTART)
depth++;
if(nextToken == BLOCKEND)
if(depth > 0) {
/*printf("skipping %s\n", ASE_text);*/
depth--;
nextToken = _lex();
neednext = 0;
}
/*printf("skipping %s (%i) (depth %i)\n", ASE_text, ASE_linenum, depth);*/
} while(nextToken && (depth || (nextToken != NODE && nextToken != BLOCKEND)));
/*printf("done (got %s)\n", ASE_text);*/
return nextToken;
}
BOOL CuFileLex::_IsUnicodeFile()
{
FILE* pFileStream = m_File.GetFILE();
WORD result = 0;
fseek( pFileStream, 0, SEEK_SET);
int nSizeT = m_File.Read(&result, sizeof(result) );
if( result != 0xfeff )
{
fseek( pFileStream, 0, SEEK_SET);
}
return (result == 0xfeff);
}
BOOL CuFileLex::Open( LPCSTR lpszFileName, LPCSTR lpszOpenMode)
{
string strFileName = lpszFileName;
string strOpenMode = lpszOpenMode;
wstring wstrFileName(strFileName.begin(), strFileName.end());
wstring wstrOpenMode(strOpenMode.begin(), strOpenMode.end());
return Open(wstrFileName.c_str(),wstrOpenMode.c_str() );
}
BOOL CuFileLex::Open( LPCTSTR lpszFileName, LPCTSTR lpszOpenMode)
{
BOOL bResult = m_File.Open(lpszFileName, lpszOpenMode);
Assert(bResult != FALSE, L"can't open file" );
Assert(bResult != FALSE, const_cast<TCHAR *>(lpszFileName) );
if( bResult == FALSE )
return FALSE;
m_bUnicode = this->_IsUnicodeFile();
if( m_bUnicode )
{
if( wcscmp (lpszOpenMode , L"r") == 0 )
{
lpszOpenMode = L"rb";
m_File.Close();
bResult = m_File.Open(lpszFileName, lpszOpenMode);
m_bUnicode = this->_IsUnicodeFile();
}
}
else
{
m_File.Close();
bResult = m_File.Open(lpszFileName, lpszOpenMode);
}
return bResult;
}
從某一隻ASE檔載入器中抓出來的,
CuFileLex 跟CuStringList 相比, 能載入較多格式的文字串, 組合後可以使用更豐富的設定檔
上面有兩大段分別支援一般文字檔跟UNICODE文字檔, 很顯示需要重構! 現在沒打算重構!
重構時間點在何時呢? 在他出錯的時後, 或是下次程式碼"review"的時後!
2010年1月28日 星期四
CuMicroTime - the current timestamp with microseconds.
// the current timestamp with microseconds.
// CuMicroTime.php
class CuMicroTime {
var $usec;
var $sec;
function CuMicroTime(/* CuMicroTime */ $MicroTime = null) {
if( $this->CheckClassType($MicroTime) )
{
$this->usec = $MicroTime->usec;
$this->sec = $MicroTime->sec;
}
else
{
list($this->usec, $this->sec) = explode(" ", microtime());
}
}
function Dec( /* CuMicroTime */ $MicroTime)
{
if( CheckClassType($MicroTime) )
return NULL;
$usec = (float)$this->usec - (float)$MicroTime->usec;
$sec = $this->sec - $MicroTime->sec;
$usec = substr($usec, 1);
return $sec.$usec;
}
function CheckClassType($MicroTime)
{
if( gettype($MicroTime) != 'object' || get_class($MicroTime) != "cumicrotime" )
return false;
else
return true;
}
}
2010年1月27日 星期三
CuShellExecuteEx - Performs an operation on a specified file.
// Performs an operation on a specified file.
// CuShellExecuteEx.h
class CuShellExecuteEx
{
public:
void SetExecuteFile(wstring strFile, BOOL bAutoModuleFile = FALSE);
BOOL OnShellExecuteEx();
SHELLEXECUTEINFO m_sei;
wstring m_strExecuteFile;
CuShellExecuteEx();
~CuShellExecuteEx();
};
// CuShellExecuteEx.cpp
CuShellExecuteEx::CuShellExecuteEx()
{
m_sei.cbSize = sizeof(SHELLEXECUTEINFO);
m_sei.fMask = 0;
m_sei.hwnd = NULL;
m_sei.lpVerb = TEXT("open");
m_sei.lpFile = NULL;
m_sei.lpParameters = NULL;
m_sei.lpDirectory = NULL;
m_sei.nShow = SW_SHOW;
m_sei.hInstApp = NULL;
}
CuShellExecuteEx::~CuShellExecuteEx()
{
}
BOOL CuShellExecuteEx::OnShellExecuteEx()
{
return ::ShellExecuteEx(&m_sei);
}
void CuShellExecuteEx::SetExecuteFile(wstring strFile, BOOL bAutoModuleFile /*= FALSE*/)
{
if( bAutoModuleFile )
{
CuModuleFile mf;
strFile = mf.GetModuleFileName(strFile);
}
m_strExecuteFile = strFile;
m_sei.lpFile = m_strExecuteFile.c_str();
}
2010年1月26日 星期二
CuModuleFile - Retrieves the fully-qualified path for the file that contains the onwer module.
// Retrieves the fully-qualified path for the file that contains the onwer module.
// CuModuleFile.h
class CuModuleFile //: public IuModuleFile
{
public:
CuModuleFile();
~CuModuleFile();
wstring GetModuleFileName(wstring strFileName);
// 傳入空的字串 會傳回執行檔檔名
wstring GetUnModuleFileName(wstring strFileName = L"");
wstring CutRFind(wstring str, TCHAR ch);
};
// CuModuleFile.cpp
CuModuleFile::CuModuleFile()
{
}
CuModuleFile::~CuModuleFile()
{
}
//////////////////////////////////////////////////////////////////////
// 函式名稱:GetModuleFileName
// 函式說明:將strFileName 前面加上 主執行緒執行檔同目錄的路徑
// 使用範例:
// 啟動 C:\Documents and Settings\Eric Wang\My Documents\Work\test.exe
// strFileName = L"sample.ini"
// str = mf.GetModuleFileName(strFileName);
// Access(str = L"C:\Documents and Settings\Eric Wang\My Documents\Work\sample.ini");
//////////////////////////////////////////////////////////////////////
wstring CuModuleFile::GetModuleFileName(wstring strFileName)
{
wstring filename;
wstring strFile = strFileName;
wstring::size_type npos = -1;
wstring::size_type indexCh1a;
int nCount = 0;
while ( (indexCh1a = strFile.find(L"..\\")) != npos )
{
nCount++;
strFile = strFile.substr(indexCh1a + 3);
}
TCHAR szModule[255] = L"";
LPTSTR psz;
::GetModuleFileName(GetModuleHandle(NULL), szModule, MAX_PATH);
do
{
psz = wcsrchr(szModule, L'\\');
if (psz)
{
*psz = L'\0';
}
}while( nCount-- );
wcscat(szModule, L"\\");
wcscat(szModule, strFile.c_str());
return szModule;
}
//////////////////////////////////////////////////////////////////////
// 函式名稱:GetUnModuleFileName
// 函式說明:函路徑的檔名前面的路徑清掉, strFileName = NULL 時 會傳回主執行緒的執行檔檔名
// 使用範例:
// strFileName = L"C:\\Documents and Settings\\Eric Wang\My Documents\\Work\\temp.txt"
// str = mf.GetUnModuleFileName(strFileName);
// Access(str = L"temp.txt");
//////////////////////////////////////////////////////////////////////
wstring CuModuleFile::GetUnModuleFileName(wstring strFileName /* = L"" */)
{
wstring filename;
wstring strFull;
if( strFileName.size() == 0 )
{
TCHAR szModule[255] = L"";
::GetModuleFileName(GetModuleHandle(NULL), szModule, MAX_PATH);
strFull = szModule;
}
else
strFull = strFileName;
static const wstring::size_type npos = -1;
wstring::size_type indexCh1a;
indexCh1a = strFull.rfind('\\');
if( indexCh1a != npos )
filename = strFull.substr(indexCh1a + 1);
else
filename = strFull;
return filename;
}
//////////////////////////////////////////////////////////////////////
// 函式名稱: CutRFind
// 函式說明: 去掉 ch 右邊的字串
// 使用範例:
// str = text.txt
// str2 = mf.GetRFind(str, '.');
// Assert( str2 = L"text");
//////////////////////////////////////////////////////////////////////
wstring CuModuleFile::CutRFind(wstring str, TCHAR ch)
{
wstring strResult;
static const wstring::size_type npos = -1;
wstring::size_type indexCh1a;
indexCh1a = str.rfind(ch);
if( indexCh1a != npos )
strResult = str.substr(0, indexCh1a);
else
strResult = str;
return strResult;
}
2010年1月25日 星期一
CuVolume - sets the volume of a waveform output device.
// sets the volume of a waveform output device.
DWORD dw, dw2;
// dw : 0x0000~0xffff
// dw2: 0~MAX
CuVolume Volume;
dw = Volume.GetVolume();
dw2 = Volume.GetVolume(MAX);
Volume.SetVolume(dw);
Volume.SetVolume(dw2, MAX);
Volume.IncVolume(MAX);
Volume.DecVolume(MAX);
// CuVolume.h
class CuVolume
{
BOOL m_bMute;
unsigned long m_nVolume;
//////////////////////////////////////////////////////////////////////
//
CuDllManager dll;
typedef DWORD (*pAudio) ();
pAudio pProc;
void UpdateVolumeFromRegistry();
//////////////////////////////////////////////////////////////////////
public:
CuVolume();
virtual ~CuVolume();
void IncVolume(int nMax);
void DecVolume(int nMax);
BOOL GetMute(void){ return m_bMute; }
BOOL SetMute(BOOL b);
// 直接指定值 v = 0 ~ 0xffff
BOOL SetVolume(unsigned long v);
unsigned long GetVolume(void);
// 正規化過的值 指定max Ex: v = 50 , nMAx = 100 , 會設定 50%
// v = 1, nMax = 5, 會設定 20%
BOOL SetVolume(int v, int nMax);
// 取回正規化過的值
int GetVolume(int nMax);
};
// CuVolume.cpp
#define MAX_VALUES 0xffff
void CuVolume::UpdateVolumeFromRegistry()
{
if( pProc )
pProc();
}
CuVolume::CuVolume()
:m_bMute(FALSE)
{
GetVolume();
dll.LoadLibrary(_T("coredll.dll"));
pProc = (pAudio)dll.GetProcAddress(_T("AudioUpdateFromRegistry"));
}
CuVolume::~CuVolume()
{
}
BOOL CuVolume::SetMute(BOOL b)
{
static unsigned long nVolume = GetVolume();
m_bMute = b;
if (m_bMute)
{
nVolume = GetVolume();
SetVolume(0);
}
else
{
SetVolume(nVolume);
}
return TRUE;
}
BOOL CuVolume::SetVolume(unsigned long v)
{
m_nVolume = v;
waveOutSetVolume(NULL, 0x10001 * v) ;
CReg reg(HKEY_CURRENT_USER, _T("ControlPanel\\Volume"));
reg.SetDW(_T("Volume"), 0x10001 * v);
UpdateVolumeFromRegistry();
return TRUE;
}
unsigned long CuVolume::GetVolume(void)
{
unsigned long Value;
if (waveOutGetVolume(NULL,&Value) == MMSYSERR_NOERROR)
{
m_nVolume = ( (LOWORD(Value)+HIWORD(Value)) ) / 2 ;
}
return m_nVolume;
}
BOOL CuVolume::SetVolume(int v, int nMax)
{
DWORD Value = v * MAX_VALUES / nMax;
SetVolume(Value);
return TRUE;
}
int CuVolume::GetVolume(int nMax)
{
unsigned long Value;
Value = (float)nMax * ((float)GetVolume() + 600) / (float)MAX_VALUES;
return Value;
}
void CuVolume::IncVolume(int nMax)
{
if( GetMute() )
SetMute(FALSE);
unsigned long offset_Value = (float)MAX_VALUES / nMax;
unsigned long Value = (float)GetVolume();
Value += offset_Value;
if( Value > MAX_VALUES)
Value = MAX_VALUES;
SetVolume(Value);
}
void CuVolume::DecVolume(int nMax)
{
if( GetMute() )
SetMute(FALSE);
float offset_Value = (float)MAX_VALUES / nMax;
float Value = (float)GetVolume();
if( Value <= offset_Value)
Value = 0;
else
Value -= offset_Value;
SetVolume(Value);
}
訂閱:
文章 (Atom)