方法太多了单实例运行方案 方案一: 查找窗口类 方案二: 设置窗口属性 方案三: 使用文件映像 方案四: 使用原子 方案五: 使用同步对象 
方案一: 使用注册类查找的方法实现单实例运行 例: ①C???App::InitInstance BOOL C???App::InitInstance()
{

    if (!FirstInstance())
       return FALSE;

beRegisted=TRUE; m_pMainWnd =new CMainWnd();
m_pMainWnd->CreateEx(0,"fmdmainwnd",
_T("CodeHelper"),WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,NULL);
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}其中beRegisted为C???App成员 public:
BOOL beRegisted;②C???App::FirstInstance BOOL CMainApp::FirstInstance()
{

     CWnd *PrevCWnd, *ChildCWnd;     // Determine if another window with our class name exists...
     if (PrevCWnd = CWnd::FindWindow("fmdmainwnd",NULL))
     {
       // if so, does it have any popups?
       ChildCWnd=PrevCWnd->GetLastActivePopup();       // Bring the main window to the top.
       PrevCWnd->BringWindowToTop();       // If iconic, restore the main window.
       if (PrevCWnd->IsIconic())
          PrevCWnd->ShowWindow(SW_RESTORE);       // If there was an active popup, bring it along too
       if (PrevCWnd != ChildCWnd)
          ChildCWnd->BringWindowToTop();       // Return FALSE. This isn't the first instance
       // and you finished activating the previous one.
       return FALSE;
     }
     else
       return TRUE;  // First instance. Proceed as normal.
   }③C???App::InitApplication BOOL CMainApp::InitApplication() 
{
CWinApp::InitApplication(); WNDCLASS wndcls;
//注册自定义类
    memset(&wndcls, 0, sizeof(WNDCLASS));
//窗口基本类型
    wndcls.style=CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc=::DefWindowProc;
    wndcls.hInstance=AfxGetInstanceHandle();
    wndcls.hIcon=LoadIcon(IDR_MAIN);
    wndcls.hCursor=LoadStandardCursor(IDC_ARROW);
    wndcls.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
    wndcls.lpszMenuName=MAKEINTRESOURCE(IDR_MAIN);
    wndcls.lpszClassName="fmdmainwnd";
return AfxRegisterClass(&wndcls);
}④C???App::ExitInstance int CMainApp::ExitInstance() 
{
// TODO: Add your specialize code here and/or call the base class
if(beRegisted)
::UnregisterClass("fmdmainwnd", AfxGetInstanceHandle());
return CWinApp::ExitInstance();
}
方案二:设置窗口附加属性 int C???Dlg::OnCreate(LPCREATESTRUCT lpCreateStruct) {
......
::SetProp(m_hWnd, AfxGetApp()->m_pszExeName, (HANDLE)1);
......
}
void C???Dlg::OnDestroy() 
{
......
::RemoveProp(m_hWnd, AfxGetApp()->m_pszExeName);
......
}
BOOL CEllipseWndApp::InitInstance()
{
// Create a Semaphore with a name of application exename
HANDLE hSem = CreateSemaphore(NULL, 1, 1, m_pszExeName);
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
// close the semaphore handle
CloseHandle(hSem); // find the provious instance main window
HWND hWndPrevious = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
while (::IsWindow(hWndPrevious))
{
// if the window has our tag?
if (::GetProp(hWndPrevious, m_pszExeName))
{
if (::IsIconic(hWndPrevious))
::ShowWindow(hWndPrevious, SW_RESTORE);
::SetForegroundWindow(hWndPrevious);
::SetForegroundWindow(::GetLastActivePopup(hWndPrevious));

return FALSE;
} // continue find next window
hWndPrevious = ::GetWindow(hWndPrevious, GW_HWNDNEXT);
} // the previous instance is exist, but can not be found
// somthing wrong?
return FALSE;
}
C????Dlg dlg;
m_pMainWnd = &dlg; int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
//  dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
//  dismissed with Cancel
}
return FALSE;
}
方案三:使用文件映像 参见《精彩例程》 方案四:使用原子 BOOL C???App::InitInstance()
{
.....
if(GlobalFindAtom("AdBreaker"))  //找原子
return false;
ATOM GlobalAtom=GlobalAddAtom("AdBreaker"); //添加原子 CAdBreakerDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
.....
GlobalDeleteAtom(GlobalAtom);
return FALSE;
}方案五:使用同步对象 InitInstance中  HANDLE m_hMutex = 
    CreateMutex(NULL,TRUE,m_pszAppName);
if (GetLastError()==ERROR_ALREADY_EXISTS){
return FALSE;
}

解决方案 »

  1.   

    // 下面是我的笔记, 我不解释了
    BOOL CBookSqlApp::InitInstance()
    { HWND FirsthWnd,FirstChildhWnd;
    static char *title="书店信息管理系统"; if(FirsthWnd = FindWindow(NULL,title))
    {
    MessageBox(NULL,"您已经启动的书店信息管理系统程序 !    ","提示 ",MB_ICONINFORMATION);
    FirstChildhWnd=GetLastActivePopup(FirsthWnd);
    BringWindowToTop(FirsthWnd); if(FirsthWnd != FirstChildhWnd)
    BringWindowToTop(FirstChildhWnd); ShowWindow(FirsthWnd,SW_SHOWNA);
    return(FALSE);
    } ...
    }
      

  2.   

    用一个共享数据段,定义一个用来计数的长整形
    #pragma data_seg(".OnlyOne")
        long 1Count=-1;
    #pragma data_seg()用DEF文件定义共享属性
    SECTIONS
         .OnlyOne READ WRITE SHARED在初始化阶段,如InitInstance开始处,加入
    BOOL bFirstInit=(InterlockedIncrement($1InstanceCount)==0)
    if(!bFirstInit)
    {
          AfxMessageBox("该程序已经运行",MB_OK|MB_ICONSTOP);
          InterlockedDecrement($1InstanceCount);
          return FALSE;
    }
    程序结束后,调用:
    InterlockedDecrement(&1InstanceCount);
      

  3.   

    补充:
    对于一般程序在ExitInstance中调用InterlockedDecrement(&1InstanceCount); 
    对话框程序在InitInstance最后调用本方法再无窗口函数中也适用
      

  4.   

    to liuqiannan(二迷糊)能不能讲讲共享数据区到底有什么特点呢?