以前在类中使用常量的成员变量,都会定义成静态变量,在class.cpp 最上面初始化一下.
在StackOverflow看到了一种方法:
在类中定义常量类成员,
然后在构造函数初始化成员列表处进行常量成员的初始化这样做很优雅,不用在类中定义static类型的成员变量
.h
private:
const std::wstring m_strIniFileName;
const std::wstring m_strIniSectionName_PinOpt;
const std::wstring m_strIniKeyName_PinOnce; ///< 已经设置过一次
.cpp
CAppTaskBarPiner::CAppTaskBarPiner() :
m_strIniFileName(L"AppTaskBarPiner.ini"),
m_strIniSectionName_PinOpt(L"PinOpt"),
m_strIniKeyName_PinOnce(L"PinWasDoOnce")
{
/// 不需要在构造函数初始化成员变量列表出做的初始化操作
m_strCfgDir = L"";
}
如果一个常量只在一个特定的类中用到,定义成宏就显得不是太适合
而且宏定义太多,找起来也很麻烦. e.g. 有超过100个以上的宏出现在一个工程中
记录这个问题的时候,做了一个类CAppTaskBarPiner来应用这种常量的初始化方法 .
写了一个Demo应用这个类, 算是这次记录的副产品~
工程下载点: srcTaskBarPiner_2014_1109_1405.rar
代码预览:
// srcTaskBarPiner.cpp : Defines the entry point for the console application.
//
/**
这个Demo使用一个类将程序图标锁定到任务栏
我的本意是记录类中定义常量成员变量的初始化问题,
在StackOverflow看到了在类中定义常量类成员,
然后在构造函数初始化成员列表处进行常量成员的初始化
这样做很优雅,不用在类中定义static类型的成员变量
如果一个常量只在一个特定的类中用到,定义成宏就显得不是太适合
而且宏定义太多,找起来也很麻烦. e.g. 有超过100个以上的宏出现在一个工程中
*/
#include "stdafx.h"
#include "utility/CommonHelper.h"
#include "utility/AppTaskBarPiner.h"
void fnTest();
int _tmain(int argc, _TCHAR* argv[])
{
ns_base::ComInit(); ///< !
fnTest();
ns_base::ComUnInit();
_tprintf(L"END, press any key to quit\r\n");
getwchar();
return 0;
}
void fnTest()
{
BOOL bRc = FALSE;
std::wstring strPePathName = L"";
std::wstring strLinkFilePathName = L"";
ns_logic::CAppTaskBarPiner Pinner;
// strPePathName and lnk file is match, here is the srcTaskBarPiner's PE
ns_base::GetFilePathName_Me(strPePathName);
/// if lnk file exist, fill to PinToTaskBar parameter 2
/// here, create a lnk file for PinToTaskBar
bRc = Pinner.CreateLinkFileToStartMenu(strPePathName.c_str(), L"test.lnk", strLinkFilePathName);
if (bRc)
{
bRc = Pinner.PinToTaskBar(strPePathName.c_str(), strLinkFilePathName.c_str(), FALSE);
}
_tprintf(L"PinToTaskBar %s\r\n", bRc ? L"TRUE" : L"FALSE");
}
/// @file AppTaskBarPiner.h
/// @brief 将应用程序图表锁定到任务栏
#ifndef __APP_TASK_BAR_PINER_H__
#define __APP_TASK_BAR_PINER_H__
#include "stdafx.h"
#include <string>
#include "Ini.h"
namespace ns_logic
{
class CAppTaskBarPiner
{
public:
CAppTaskBarPiner();
virtual ~CAppTaskBarPiner();
public:
void SetCfgDir(const WCHAR* pcPathName);
BOOL PinToTaskBar(
const WCHAR* pcPePathName,
const WCHAR* pcLinkFileName,
BOOL bPinForce = FALSE);
BOOL CreateLinkFileToStartMenu(
const WCHAR* pcPePathName,
const WCHAR* pcLinkFileName,
OUT std::wstring& strLinkFilePathName);
private:
BOOL CreateLinkFileToTaskBar(
const WCHAR* pcPePathName,
const WCHAR* pcLinkFilePathName);
BOOL GetDirStartMenu(std::wstring & strPathName);
BOOL GetDirByCsidl(DWORD dwCsidl, std::wstring & strPathName);
BOOL CreateLinkFileTo(
const WCHAR* pcPePathName,
const WCHAR* pcLinkFileName,
const WCHAR* pcDirTo,
std::wstring& strLinkFilePathName);
private:
const std::wstring m_strIniFileName;
const std::wstring m_strIniSectionName_PinOpt;
const std::wstring m_strIniKeyName_PinOnce; ///< 已经设置过一次
std::wstring m_strCfgDir;
CIni m_ini;
};
}
#endif // #ifndef __APP_TASK_BAR_PINER_H__
/// @file AppTaskBarPiner.cpp
/// @brief ...
#include "stdafx.h"
#include <shlobj.h>
#include "AppTaskBarPiner.h"
#include "CommonHelper.h"
namespace ns_logic
{
CAppTaskBarPiner::CAppTaskBarPiner() :
m_strIniFileName(L"AppTaskBarPiner.ini"),
m_strIniSectionName_PinOpt(L"PinOpt"),
m_strIniKeyName_PinOnce(L"PinWasDoOnce")
{
/// 不需要在构造函数初始化成员变量列表出做的初始化操作
m_strCfgDir = L"";
}
CAppTaskBarPiner::~CAppTaskBarPiner()
{
}
void CAppTaskBarPiner::SetCfgDir(const WCHAR* pcPathName)
{
m_strCfgDir = (NULL != pcPathName) ? pcPathName : L"";
if (!ns_base::IsStringLastCharMatch(m_strCfgDir.c_str(), L'\\'));
{
m_strCfgDir += L"\\";
}
}
BOOL CAppTaskBarPiner::PinToTaskBar(
const WCHAR* pcPePathName,
const WCHAR* pcLinkFileName,
BOOL bPinForce /*= FALSE*/)
{
BOOL bRc = FALSE;
int iValue = 0;
std::wstring strPathName = L"";
if ((NULL == pcPePathName)
|| (NULL == pcLinkFileName))
{
goto END_PinToTaskBar;
}
/// 如果用户取消过TaskBar上的已锁定程序图标,不再重新pin图标
strPathName = m_strCfgDir.c_str();
strPathName += m_strIniFileName.c_str();
m_ini.SetPathName(strPathName.c_str());
iValue = m_ini.GetInt(
m_strIniSectionName_PinOpt.c_str(),
m_strIniKeyName_PinOnce.c_str(),
0);
if ((iValue <= 0) || bPinForce)
{
bRc = CreateLinkFileToTaskBar(pcPePathName, pcLinkFileName);
if (bRc)
{
m_ini.WriteInt(
m_strIniSectionName_PinOpt.c_str(),
m_strIniKeyName_PinOnce.c_str(),
1);
}
}
END_PinToTaskBar:
return bRc;
}
BOOL CAppTaskBarPiner::CreateLinkFileToTaskBar(
const WCHAR* pcPePathName,
const WCHAR* pcLinkFilePathName)
{
HINSTANCE hRc = 0;
if ((NULL == pcPePathName)
|| (NULL == pcLinkFilePathName))
{
return FALSE;
}
_ASSERT_EXPR(ns_base::IsFileExist(pcPePathName), L"error : CreateLinkFileToTaskBar param1");
_ASSERT_EXPR(ns_base::IsFileExist(pcLinkFilePathName), L"error : CreateLinkFileToTaskBar param2");
/// If the function succeeds, it returns a value greater than 32.
/// 参数3 必须是一个已经存在的快捷方式 x.lnk
hRc = ::ShellExecute(
NULL,
TEXT("TaskbarPin"),
pcLinkFilePathName,
NULL,
NULL,
SW_SHOW);
return ((int)hRc > 32);
}
BOOL CAppTaskBarPiner::CreateLinkFileToStartMenu(
const WCHAR* pcPePathName,
const WCHAR* pcLinkFileName,
OUT std::wstring& strLinkFilePathName)
{
BOOL bRc = FALSE;
std::wstring strDestPath = L"";
GetDirStartMenu(strDestPath);
bRc = CreateLinkFileTo(pcPePathName, pcLinkFileName, strDestPath.c_str(), strLinkFilePathName);
return bRc;
}
BOOL CAppTaskBarPiner::GetDirStartMenu(std::wstring & strPathName)
{
// CSIDL_STARTUP
return GetDirByCsidl(CSIDL_STARTMENU, strPathName);
}
BOOL CAppTaskBarPiner::GetDirByCsidl(DWORD dwCsidl, std::wstring & strPathName)
{
WCHAR szBuf[MAX_PATH + 1] = { L'\0'};
SHGetSpecialFolderPath(NULL, szBuf, dwCsidl, false);
strPathName = szBuf;
if (!ns_base::IsStringLastCharMatch(strPathName.c_str(), L'\\'))
{
strPathName += L'\\';
}
return TRUE;
}
BOOL CAppTaskBarPiner::CreateLinkFileTo(
const WCHAR* pcPePathName,
const WCHAR* pcLinkFileName,
const WCHAR* pcDirTo,
std::wstring& strLinkFilePathName)
{
int iShowCmd = SW_SHOWNORMAL;
std::wstring strDestPath = L"";
HRESULT hr = S_FALSE;
IShellLink* pLink = NULL; //IShellLink对象指针
IPersistFile* ppf = NULL; //IPersisFil对象指针
strLinkFilePathName = L"";
if (NULL == pcPePathName)
{
return FALSE;
}
if (NULL == pcLinkFileName)
{
return FALSE;
}
if (NULL == pcDirTo)
{
return FALSE;
}
ns_base::CreateFullFilePath(pcDirTo); ///< !
strDestPath = pcDirTo;
if (!ns_base::IsStringLastCharMatch(strDestPath.c_str(), L'\\'))
strDestPath += L'\\';
//创建IShellLink对象
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pLink);
if (FAILED(hr))
return FALSE;
//从IShellLink对象中获取IPersistFile接口
hr = pLink->QueryInterface(IID_IPersistFile, (void**)&ppf);
if (FAILED(hr))
{
pLink->Release();
return FALSE;
}
//目标
pLink->SetPath(pcPePathName);
pLink->SetShowCmd(iShowCmd);
//快捷方式的路径 + 名称
strDestPath += pcLinkFileName;
strLinkFilePathName = strDestPath.c_str();
//保存快捷方式到指定目录下
hr = ppf->Save(strDestPath.c_str(),TRUE);
ppf->Release();
pLink->Release();
return SUCCEEDED(hr);
}
}