我想只启动一个实例,所以在系统初始化的时候通过FindWindow(NULL, "窗口标题")查找是否已经启动了一个实例,如果已经启动了一个实例则将其激活。用这个函数问题时解决了,但是有个问题就是如果运行了一个别的程序,该程序的窗口表题和要查找的窗口标题相同,则系统在启动的时候就会将该窗口激活。有没有什么办法不去查找别的进程的窗口标题

解决方案 »

  1.   

    窗口标题是容易重复,但窗口类名再重就不容易了吧?
    第一个参数请不要用NULL试试。
      

  2.   

    同意思楼上两位同志的说法。
    用findwindow(类名,标题)吧,因该可以了。
    别人就是和你的程序的同一个标题,未必是同一个类吧。如果还怕这样也有相同的。
    要不你干脆自己注册一个自己的类,
    这样就万无一失了。呵呵
      

  3.   

    我觉得应该用CreateMutex互斥量来判断是否已有自己的程序实例在运行
    如果需要激活前实例可以利用全局信号或进程通信来获得前实例的窗口
      

  4.   

    其实,有更多的实例是使用ATOM标记。
      

  5.   

    其实都不是很安全的
    如ATOM,如果在设置后程序出错返回,则下次就起步来了
      

  6.   

    比较标准有效的方法(我也是拷贝来的,呵呵):1、在App类的InitInstance()函数的头部添加:
        HANDLE hSem = CreateSemaphore(NULL, 1, 1, m_pszExeName);//用应用程序名创建信号量;
        //信号量存在,则程序已有一个实例运行
        if (GetLastError() == ERROR_ALREADY_EXISTS)
        {
            CloseHandle(hSem);//关闭信号量句柄;
            //寻找先前实例的主窗口
            HWND hWndPrevious = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
            while (::IsWindow(hWndPrevious))
    {
    // 检查窗口是否有预设的标记?有,则是我们寻找的主窗
    if(::GetProp(hWndPrevious, m_pszExeName))
                {
    if (::IsIconic(hWndPrevious))//主窗口已最小化,则恢复其大小;
    ::ShowWindow(hWndPrevious, SW_RESTORE);
                    
                    ::SetForegroundWindow(hWndPrevious);//将主窗激活
    ::SetForegroundWindow(::GetLastActivePopup(hWndPrevious));//将主窗的对话框激活;
                    
                    return FALSE;//退出本实例;
    }            hWndPrevious = ::GetWindow(hWndPrevious, GW_HWNDNEXT);//继续寻找下一个窗口;
            } return FALSE;//前一实例已存在,但找不到其主窗,可能出错了,退出本实例;
        }2、在MainFrame类的OnCreate()函数的头部添加:
    ::SetProp(m_hWnd, AfxGetApp()->m_pszExeName, (HANDLE)1);//做已启动标记;3、在MainFrame类的OnClose()或者OnDestroy()函数中添加:
             ::RemoveProp(m_hWnd, AfxGetApp()->m_pszExeName);//移去程序启动标志;这样就可以了,当程序打开后,在运行,则将原来的程序激活