From: SteveR on
My installer calls FindWindow on my app, using the title parameter, and that
works fine, but I would rather use the class. I have a pretty standard SDI
and have never before had a reason to work with the name app's window class.
How do I know what that is?


From: David Webber on

"SteveR" <maxsrussellatremovethisembarqmail.com> wrote in message
news:%23tma%23QsuIHA.5268(a)TK2MSFTNGP06.phx.gbl...
> My installer calls FindWindow on my app, using the title parameter, and
> that works fine, but I would rather use the class. I have a pretty
> standard SDI and have never before had a reason to work with the name
> app's window class. How do I know what that is?

In an MDI app it works as follows IIRC.

The class name is an element of the CREATESTRUCT which is passed to
CMDIFrameWnd::PreCreateWindow().

I believe MFC defines its own and if you look for windows of that class
you'll pick up almost anything created with MFC.

So the thing to do is override CMDIFrameWnd::PreCreateWindow() with your own
CMainFrame::PreCreateWindow() and replace the class name with your own
before calling CMDIFrameWnd::PreCreateWindow(). Then you can look for your
own application with that class name.

However you must also register your class name - I do it using
AfxRegisterClass()

[I do this so that I can check if my app is already running, and abort a
second instance if it tries to get going, passing its command line
parameters to the already running instance. That way double clicking on a
document file in explorer will open it in an already-running instance if
there is one, rather than launching a second.]

Dave
--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mozartists/mailinglist.htm


From: SteveR on
I'm fishing around for examples for how to register my CMainFrame class.
I'm looking at this right now:

BOOL CSampleApp::InitInstance()
{
/********************************************************************/
// If a previous instance of the application is already running,
// then activate it and return FALSE from InitInstance to
// end the execution of this instance.

CWnd *pWndPrev;

// Determine if another window with your class name exists...
if (pWndPrev = CWnd::FindWindow(_T("WCE_MyNewClass"),NULL))
{
// Bring previous instance to the foreground
pWndPrev->SetForegroundWindow();
return FALSE;
}
WNDCLASS wndcls;

memset(&wndcls, 0, sizeof(WNDCLASS)); // start with NULL defaults

wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.hInstance = AfxGetInstanceHandle();
wndcls.hIcon = LoadIcon(IDR_MAINFRAME); // or load a different icon
wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wndcls.lpszMenuName = NULL;
// Specify your own class name for using FindWindow later
wndcls.lpszClassName = _T("MyNewClass");

// Register the new class and exit if it fails
if(!AfxRegisterClass(&wndcls))
{
AfxMessageBox(_T("Class Registration Failed\n"));
return FALSE;
}
/********************************************************************/
// Other code here...
}

How much of that applies to what I need to do?
------------------
"David Webber" <dave(a)musical-dot-demon-dot-co.uk> wrote in message
news:uxnFklsuIHA.4376(a)TK2MSFTNGP06.phx.gbl...
>
> "SteveR" <maxsrussellatremovethisembarqmail.com> wrote in message
> news:%23tma%23QsuIHA.5268(a)TK2MSFTNGP06.phx.gbl...
>> My installer calls FindWindow on my app, using the title parameter, and
>> that works fine, but I would rather use the class. I have a pretty
>> standard SDI and have never before had a reason to work with the name
>> app's window class. How do I know what that is?
>
> In an MDI app it works as follows IIRC.
>
> The class name is an element of the CREATESTRUCT which is passed to
> CMDIFrameWnd::PreCreateWindow().
>
> I believe MFC defines its own and if you look for windows of that class
> you'll pick up almost anything created with MFC.
>
> So the thing to do is override CMDIFrameWnd::PreCreateWindow() with your
> own CMainFrame::PreCreateWindow() and replace the class name with your own
> before calling CMDIFrameWnd::PreCreateWindow(). Then you can look for
> your own application with that class name.
>
> However you must also register your class name - I do it using
> AfxRegisterClass()
>
> [I do this so that I can check if my app is already running, and abort a
> second instance if it tries to get going, passing its command line
> parameters to the already running instance. That way double clicking on
> a document file in explorer will open it in an already-running instance if
> there is one, rather than launching a second.]
>
> Dave
> --
> David Webber
> Author of 'Mozart the Music Processor'
> http://www.mozart.co.uk
> For discussion/support see
> http://www.mozart.co.uk/mozartists/mailinglist.htm
>
>


From: Joseph M. Newcomer on
There are so many things wrong with this approach, it is amazing that it works at all.

Using FindWindow is already a Bad Idea. If the app is coming up when the installer
launches, you can get a false negative.

If you do not allow more than one copy of your app to run, you can use the same
mutex/semaphore/event object that the standard "only let one application run" uses; but
I'd suggest using an analogous technique that creates a unique name shared between the app
and the installer. If the app comes up when the installer is running, it just terminates
itself; if the installer comes up and an app is running, it can take appropriate action.

Essentially, think of FindWindow as being the worst possible way to solve this problem.
Obviously using the title is a complete failure, because you can't localize easily. But I
wouldn't touch FindWindow as an approach to this problem, not on a bet.
joe

On Tue, 20 May 2008 17:55:47 -0400, "SteveR" <maxsrussellatremovethisembarqmail.com>
wrote:

>My installer calls FindWindow on my app, using the title parameter, and that
>works fine, but I would rather use the class. I have a pretty standard SDI
>and have never before had a reason to work with the name app's window class.
>How do I know what that is?
>
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Scott McPhillips [MVP] on
"SteveR" <maxsrussellatremovethisembarqmail.com> wrote in message
news:exAKpNtuIHA.2068(a)TK2MSFTNGP05.phx.gbl...
> I'm fishing around for examples for how to register my CMainFrame class.
> I'm looking at this right now:
>
> BOOL CSampleApp::InitInstance()
> {
> /********************************************************************/
> // If a previous instance of the application is already running,
> // then activate it and return FALSE from InitInstance to
> // end the execution of this instance.
>
> CWnd *pWndPrev;
>
> // Determine if another window with your class name exists...
> if (pWndPrev = CWnd::FindWindow(_T("WCE_MyNewClass"),NULL))
> {
> // Bring previous instance to the foreground
> pWndPrev->SetForegroundWindow();
> return FALSE;
> }
> WNDCLASS wndcls;
>
> memset(&wndcls, 0, sizeof(WNDCLASS)); // start with NULL defaults
>
> wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
> wndcls.lpfnWndProc = ::DefWindowProc;
> wndcls.hInstance = AfxGetInstanceHandle();
> wndcls.hIcon = LoadIcon(IDR_MAINFRAME); // or load a different icon
> wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
> wndcls.lpszMenuName = NULL;
> // Specify your own class name for using FindWindow later
> wndcls.lpszClassName = _T("MyNewClass");
>
> // Register the new class and exit if it fails
> if(!AfxRegisterClass(&wndcls))
> {
> AfxMessageBox(_T("Class Registration Failed\n"));
> return FALSE;
> }
> /********************************************************************/
> // Other code here...
> }
>
> How much of that applies to what I need to do?


You need all of it. I have a working code very much like this (from several
years ago) and it has this difference:

wndcls.lpfnWndProc = AfxWndProc;

I think you will need that so MFC will receive the messages.

--
Scott McPhillips [VC++ MVP]