我的程序需要只是启动一个实例,所以我在APP的InitInstance里面添加
    //获取是否只启动一个实例的参数
    m_bStartOnce=ini.GetBool("StartOnlyOnce",FALSE,"ApplicationConfig");    
    // The one and only window has been initialized, so show and update it.
    EnumWindows(EnumWndProc,(LPARAM)&m_OldHWnd);    //枚举所有运行的窗口
    //如果已经找到一个启动的实例,并且程序配置没有要求只启动一个实例
    //那就把当前的文件信息传递给他,并且激活它
    if(m_OldHWnd != NULL&&m_bStartOnce)
    {
//        AfxMessageBox("本程序已经在运行了");
        if(*m_lpCmdLine==0)
            return false;
        COPYDATASTRUCT    cpdata;
        cpdata.lpData=(PVOID)m_lpCmdLine;
        cpdata.cbData=strlen(m_lpCmdLine);
        cpdata.dwData=0;
        SendMessage(m_OldHWnd,WM_COPYDATA,(WPARAM)m_pMainWnd->GetSafeHwnd(),(LPARAM)&cpdata);
//        ::ShowWindow(m_OldHWnd,SW_SHOWMAXIMIZED);          //激活找到的前一个程序
        ::SetForegroundWindow(m_OldHWnd);                //把它设为前景窗口
        return false;                                  //退出本次运行
    }
    
(这个也是看到vckbase上面的文章学的)
然后在Mainframe的OnCopyData里面
BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
{//为了只打开一个实例,所以需要接受来自新的实例文件路径
    CHAR*    pString=(CHAR*)pCopyDataStruct->lpData;
    DWORD    dataSize=pCopyDataStruct->cbData;
    ASSERT(pString);
    pString[dataSize]='\0';
    //测试是否在不从APP的状态下启动可以解决打开图像的时候先打开在最大化这个问题
    extern    CImageLoadApp        theApp;
    theApp.OpenDocumentFile(pString);
        XTRACE("CMainFrame Open document  %s in CMainFrame::OnCopyData\r\n",pString);
    return CFrameWnd::OnCopyData(pWnd, pCopyDataStruct);
}
可是每次点击我的程序关联的文件的时候我的应用程序会先restore然后再最大化(我的程序一直都保持最大化的状态)。怎样才能消除这种现象呢!

解决方案 »

  1.   

    single instance的推荐方法是用MSDN中的方法,
    http://support.microsoft.com/kb/q243953/
    How to limit 32-bit applications to one instance by using Visual C++
      

  2.   

    启动一个实例用Mutex互斥来实现
      

  3.   

    两个方法,用Mutex互斥和原子量,参考代码如下:判该程序是否运行, 初始化函数里创建互斥量,判断返回值
    BOOL CYourApp::InitInstance()
    {
       HANDLE Handle;
       Handle = CreateMutex(NULL,FALSE,_T("MakeSheet3.0"));
       if(Handle==NULL)
    return FALSE;
       if(GetLastError() == ERROR_ALREADY_EXISTS)
       {
    AfxMessageBox("MakeSheet3.0已运行!",MB_ICONSTOP);
    return FALSE;
       }
       ........
    }
    使用原子:#define AtomName "MyProgramNameAtom" //这个字串可以自己取,尽量取得特殊些int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpCmdLine, int nCmdShow)
    {
        ATOM Atom;
        // 程序一开始,判断原子是否存在
        if (GlobalFindAtom(AtomName))
            return 1;  // 程序已经运行,这儿直接退出
        Atom = GlobalAddAtom(AtomName);
        //...... 你的代码
        // 程序退出前,删除原子
        GlobalDeleteAtom(Atom);  return 1;
    }
      

  4.   

    对你的方法,可以试试
    //在ParseCommandLine之后,ProcessShellCommand之前,添加这句:
    m_nCmdShow = SW_SHOWMAXIMIZED;
      

  5.   

    To laiyiling(※最熟悉的陌生人 V2.0※) :
    果然可以!
    我马上结贴