您的位置:首页 > 其它

允许单一实例运行的方法

2008-04-27 16:28 141 查看
1.基于对话框运行的情况,即只允许单一对话框运行的情况.
使用互斥变量.
在CWinApp::InitInstance()的重载函数中,加入如下语句.
HANDLEhMutex=::CreateMutex(NULL,TRUE,m_pszAppName);if(::GetLastError()==ERROR_ALREADY_EXISTS)returnFALSE;
如果已经有实例运行,则会返回ERRO_ALREADY_EXISTS值.
2.基于SDI,MDI的程序运行的情况!
上述利用互斥量的方法仍然适用于只允许SDI/MDI的单一实例运行.
但可以使用注册窗口方法来实际单一的SDI/MDI的实例运行!
这个程序的单一实例运行比较困难,MFC4.0之前的版本是注册窗口方法与MFC4.0后的
版本是不同的,所以这个方法只能在MFC4.0后的版本运行.
首先要重载CWinApp::InitInstance()的方法.在这里会搜索已经运行的实例,并激活
这个实例!
//首先标识一个全局BOOL变量,以便在退出实例时使用它.
staticBOOLbClassRegistered=FALSE;BOOLCOneSampleApp::InitInstance()
{
//检测是否已有实例运行,如果已运行,
//则激活已存在实例,否则注册这个实例的窗口类if(!FirstInstance())returnFALSE;WNDCLASSwndcls;
memset(&wndcls,0,sizeof(WNDCLASS));
wndcls.style=CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
wndcls.lpfnWndProc=::DefWindowProc;
wndcls.hInstance=AfxGetInstanceHandle();
wndcls.hIcon=LoadIcon(IDR_MAINFRAME);
wndcls.hCursor=LoadCursor(IDC_ARROW);
wndcls.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wndcls.lpszMenuName=NULL;wndcls.lpszClassName=_T("MyNewClass");if(!AfxRegisterClass(&wndcls)){TRACE("ClassRegistrationFailed");returnFALSE;}bClassRegistered=TRUE;//RestofInitInstancegoeshere.........
}
FirstInstance()的方法如下.
BOOLCOneSampleApp::FirstInstance()
{
CWnd*pWndPrev,*pWndChild;
//Determineifanotherwindowwithyourclassnameexists...
if(pWndPrev=CWnd::FindWindow(_T("MyNewClass"),NULL))
{
//Ifso,doesithaveanypopups?
pWndChild=pWndPrev->GetLastActivePopup();
//Ificonic,restorethemainwindow
if(pWndPrev->IsIconic())
pWndPrev->ShowWindow(SW_RESTORE);
//Bringthemainwindoworitspopupto
//theforeground
pWndChild->SetForegroundWindow();
//andyouaredoneactivatingthepreviousone.
returnFALSE;
}
//Firstinstance.Proceedasnormal.
else
returnTRUE;
}
重载CWinApp::ExitInstance()的方法,如果是新注册的窗口类,则unregister()
intCOneSampleApp::ExitInstance()
{
if(bClassRegistered)
::UnregisterClass(_T("MyNewClass"),AfxGetInstanceHandle());
returnCWinApp::ExitInstance();
}
跟着重载CFrameWnd::PreCreateWindow()方法,在这儿使用你自已注册时的窗口类,
从而避免使用MFC使用的窗口类,
BOOLCMainFrame::PreCreateWindow(CREATESTRUCT&cs)
{
//Usethespecificclassnameyouestablishedearlier.
cs.lpszClass=_T("MyNewClass");
//Changethefollowinglinetocall.
//CFrameWnd::PreCreateWindow(cs)假如为SDI则使用这个,切记!!
returnCMDIFrameWnd::PreCreateWindow(cs);
}
[/code]
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: