Click here to Skip to main content
15,894,646 members
Articles / Desktop Programming / MFC
Article

Dialog based single instance applications

Rate me:
Please Sign up or sign in to vote.
3.05/5 (16 votes)
8 Mar 2006CPOL2 min read 62.2K   482   8   13
Limiting dialog based programs to single instance by modifying the dialog template – my way.

Introduction

Sometimes it is necessary to limit your program to only one running instance. For example, you create an Internet program that listens to a particular TCP/IP port on the user’s computer, or you create a program that works in the background and puts an icon in the system tray (near the clock).

There are several good articles on CodeProject and CodeGuru discussing different techniques that you can use. For example, you can use named kernel mode objects (mutex, event, etc.), or use Tokens, or you can search for your executable name in the running programs list (EnumProcesses or CreateToolhelp32Snapshot).

In this article, I will discuss using FindWindow for dialog based programs. The problem is that Windows, by default, uses a special (non unique) class name “#32770 (Dialog)” to create dialog boxes. We need to create the dialog box with our unique class name instead of this standard class name.

I will show you:

  1. How you can create a dialog box with your own class name.
  2. How you can use FindWindow to find your dialog box by its class name.

Although I use MFC in this sample, it is not limited to MFC programs only. You can do the same for ATL/WTL based programs as well as for generic Win32 applications.

Implementation

  1. Create a MFC dialog based project.
  2. Open the Resource Script file (.rc), find your main dialog template, and add the following line:
    CLASS "SINGLE_INSTANCE_APP"

    You should have something like this:

    IDD_SINGLEINSTANCE_DIALOG DIALOGEX 0, 0, 320, 200
        STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE |
        WS_CAPTION | WS_SYSMENU
        EXSTYLE WS_EX_APPWINDOW
        CLASS "SINGLE_INSTANCE_APP"
        CAPTION "Single Instance Application"
        ...

    This will instruct Windows to use our own Windows class "SINGLE_INSTANCE_APP" instead of the standard dialog class.

  3. Now, we have to register the "SINGLE_INSTANCE_APP" windows class. The best place for this is InitInstance().
    WNDCLASS wc = {0}; 
    wc.style = CS_BYTEALIGNWINDOW|CS_SAVEBITS|CS_DBLCLKS; 
    wc.lpfnWndProc = DefDlgProc; 
    wc.cbWndExtra = DLGWINDOWEXTRA; 
    wc.hInstance = m_hInstance; 
    wc.hIcon = LoadIcon(IDR_MAINFRAME); 
    wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); 
    wc.lpszClassName = _T("SINGLE_INSTANCE_APP"); 
    ATOM cls = RegisterClass(&wc);
  4. After this, we can find our main dialog box by its class name. A non-NULL pointer means that our program is already running. We will simply activate it and exit.
    CWnd* pWnd = CWnd::FindWindow(_T("SINGLE_INSTANCE_APP"), NULL); 
    if (pWnd) 
    {
         pWnd->ShowWindow(SW_SHOW); 
         pWnd->SetForegroundWindow(); 
         return FALSE; 
    }

Recommendations

Well, there are a few limitations with using FindWindow that you should know about. If you execute some initialization code (that takes a long time) after calling FindWindow but before creating your main dialog box (by calling CDialog::DoModal() or CDialog::Create()), then this technique may fail.

So, you should avoid executing any code that may take a long time between the FindWindow call and creating your main dialog box, and avoid using initialization code in the PreCreateWindow(), OnCreate(), etc. handlers. The OnInitDialog() is the best place for them.

Conclusion

I hope this article was useful for you. I have used this technique in different free and commercial software programs, and it works quite well for me.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Ukraine Ukraine

Comments and Discussions

 
Questionhow to work in a generic Win32 application Pin
daxue14-Oct-07 3:06
daxue14-Oct-07 3:06 
QuestionExternal DLL ressource Pin
VirginF25-Apr-06 3:11
VirginF25-Apr-06 3:11 
AnswerRe: External DLL ressource Pin
pkhach25-Apr-06 4:10
pkhach25-Apr-06 4:10 
GeneralProbably won't work. Pin
RandomMonkey9-Mar-06 19:25
RandomMonkey9-Mar-06 19:25 
GeneralRe: Probably won't work. Pin
pkhach9-Mar-06 22:34
pkhach9-Mar-06 22:34 
GeneralRe: Probably won't work. Pin
RandomMonkey10-Mar-06 4:45
RandomMonkey10-Mar-06 4:45 
GeneralRe: Probably won't work. Pin
pkhach10-Mar-06 7:35
pkhach10-Mar-06 7:35 
GeneralRe: Probably won't work. Pin
RandomMonkey10-Mar-06 8:48
RandomMonkey10-Mar-06 8:48 
GeneralRe: Probably won't work. Pin
pkhach10-Mar-06 21:47
pkhach10-Mar-06 21:47 
GeneralResource Editor won't keep your manual changes Pin
Jun Du9-Mar-06 6:11
Jun Du9-Mar-06 6:11 
Hey,

My concern is that next time when you modify the dialog and regnerate .rc file, you'll lose your code again. I wouldn't recommend manually changing Resource-Editor generated files. I do recall there is a way to ask the RE to include external contents automatically, but I gota run now.

Best,

GeneralRe: Resource Editor won't keep your manual changes Pin
pkhach9-Mar-06 7:00
pkhach9-Mar-06 7:00 
GeneralRe: Resource Editor won't keep your manual changes Pin
Jun Du9-Mar-06 7:58
Jun Du9-Mar-06 7:58 
GeneralRe: Resource Editor won't keep your manual changes Pin
pkhach9-Mar-06 8:23
pkhach9-Mar-06 8:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.