PDC热热闹闹的结束了,关于最新技术的讨论也告一段落,回头来看看手头的任务吧。

在dotnet和VB中这个是一件非常容易的事情,在VC中虽然说不上复杂,但是也不简单。

如果可以保证自己的程序安全运行,正常退出。到是可以采用在ini文件和注册表中写状态的办法。笑脸

当时这些都不是正路,万一程序没有响应或者没有正常退出,就没有办法了,而且程序也没有办法启动了悲伤的脸

所以应该用正路,FindWindow 或者 CreateMutex,我当然向大家推荐FindWindow,因为价格便宜量又足。

但是存在一个问题,按照什么方法来实现呢?对于MDI/SDI程序来说,title始终处于变化中,而Dialog用Title又不安全,重复的可能行太大了。所以我建议大家使用Window Class Name 来实现。对于MDI/SDI应用程序,只要简单的加入以下代码即可。

在BOOL CTestSingleinstanceApp::InitInstance() 中增加以下代码

 if(!IsFirstInstance())
            return FALSE;
WNDCLASS wc;

 // Get the info for this class.
         // #32770 is the default class name for dialogs boxes.
 ::GetClassInfo(AfxGetInstanceHandle(), "#32770", &wc);

 // Change the name of the class.
 wc.lpszClassName = "tttttt";

 // Register this class so that MFC can use it.
 AfxRegisterClass(&wc); 

其中IsFirstInstance代码如下

BOOL CTestSingleinstanceApp::IsFirstInstance()
{
 CWnd *pWndPrev, *pWndChild;

        // Determine if another window with your class name exists...
        if (pWndPrev = CWnd::FindWindow(_T("tttttt"),NULL))
        {
          // If so, does it have any popups?
          pWndChild = pWndPrev->GetLastActivePopup();

          // If iconic, restore the main window
          if (pWndPrev->IsIconic())
             pWndPrev->ShowWindow(SW_RESTORE);

          // Bring the main window or its popup to
          // the foreground
          pWndChild->SetForegroundWindow();

          // and you are done activating the previous one.
          return FALSE;
        }
        // First instance. Proceed as normal.
        else
          return TRUE;

}

这段代码不但可以避免程序重复被启动,也可以将原来的程序激活,如同Foxmail那样

但是大家要知道,这样的代码对于Dialog应用程序是不起作用的,因为用Spy++照Dialog的时候,发现Dialog的 Window Class Name 始终是一个常数#32770 (Dialog),经过查找KB文章后终于发现了一个非常郁闷也非常有意思的解决方法。

用文本方式打开Dialog所在的RC文件,做如下修改

IDD_TESTSINGLEINSTANCE_DIALOG DIALOGEX 0, 0, 320, 200
STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION |
    WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "LimitDlgInstance"
CLASS "tttttt" // Add your class name here!

注意这里的Class必须和前面代码中的Class一致,否则程序无法启动。

至此,就完整的解决了在MFC下解决应用程序多次被启动的问题。

 

下面就是闲话时间了,非常感谢开心提醒我,我以前在MS的站点上只知道download和MSDN,现在发现KB也是一个非常不错的技术资源,尤其是身为MVP 还可以访问partner级别的资源,这些天收益不小。

另外,开心问我是不是和molsem较劲?怕molsem抢了我的二把交椅,呵呵有点。不过更应该说是molsem让我有了学习的激情。笑脸

今天又听到了和日本方面的冲突,这样的事情发生在我的母校。我一直以为西北大学就是西部的北大,每次轰轰烈烈的学生运动都离不开这做百年老校的身资,也许是文科特有的政治家的氛围吧

还发现一个非常有意思的地方就是大家似乎对技术类文章没有兴趣,我发现我最受欢迎的随笔是:http://blog.joycode.com/roboo/posts/982.aspx 开心批评我说是因为我的文笔不好,可是我什么时候能够赶得上他的师傅呢?