关于程序单例模式的设计
学过设计模式的人肯定都学过类的单例模式。而我这里要总结的是关于程序的单例模式
1.首先建立一个CRunOnce类如下所示:
class CRunOnce { class CParameter { public: HWND m_hWnd; CString m_str; }; public: BOOL IsFirstRun(); void CallInMainFrm(const CDialog *pFrm); void SetPropName(const CString &strPropName); private: CString m_strPropName; static BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lParam); };
这里存储了自己设定的唯一的名字m_strPropName
1.在Dlg的构造函数中设定CRunOnce的唯一名字
2.在OnInitDialog中属性中SetProp(); 名字和handle值(这个值随意给个)
3.在App的InitInstance中判断这个程序是否在Windows中运行了。
if (!dlg.m_RunOnce.IsFirstRun())
{
return FALSE;
}
2.了解每个函数的设置
enumwndProc(hwnd, lparam)这个函数在里面通过GetProp(hwnd, CParameter.m_str)来获取设定的handle,即在属性中SetProp的handle值,如果和自己设置的一样就说明已经该成语已经在运行了。否则对应的hwnd不是本程序。
IsFirstRun()该函数查找本程序是否已经在运行了通过枚举每个已经在运行的Windows
EnumWindows(EnumWndProc, lparam); lparam是EnumwndProc中的第二个参数
进行检测是否本程序也在运行。
BOOL CALLBACK CRunOnce::EnumProcWindow( HWND hWnd, LPARAM lParam ) { Cparameter *pParam = (Cparameter *)lParam; HANDLE hIns = GetProp(hWnd, pParam->m_str); if ((HANDLE)1 == hIns) { pParam->m_hWnd = hWnd; return FALSE; } return TRUE; } void CRunOnce::SetProcWindow( CWindow *pWindow ) { SetProp(pWindow->m_hWnd, m_strProcName, (HANDLE)1); } void CRunOnce::SetProcName( const CString &rProcName ) { m_strProcName = rProcName; } BOOL CRunOnce::IsRunOnce() { Cparameter par; par.m_str = m_strProcName; par.m_hWnd = NULL; EnumWindows(CRunOnce::EnumProcWindow, (LPARAM)&par); if (par.m_hWnd != NULL) { ::ShowWindow(par.m_hWnd, SW_SHOWNORMAL); ::SetForegroundWindow(par.m_hWnd); return TRUE; } return FALSE; }