🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
8 messages
8 total messages Started by Nate Lockwood Fri, 24 Feb 2006 20:54
Mutex troubles?
#4374
Author: Nate Lockwood
Date: Fri, 24 Feb 2006 20:54
62 lines
2884 bytes
I'm trying to have my program detect that another instance is running, 
send a "Show" message to the already running instance, and then return. 
I'm using Builder 6.

It appears that I always get a non null mutex so the message is never 
sent.  Here's some code.

Thanks

UINT WM_MYMSG;
HANDLE CheckForInstance(const UINT WM_MYMSG);

<snip>
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
         HANDLE mutex;
         try
         {
                  String sTitle = "Google Earth (C) Tool";
                  String sMessage = 
"USDA.FS.FireScience.GooleEarthTool.Awake";
                  Application->Title = sTitle + " Temporary";
                  WM_MYMSG = RegisterWindowMessage(sMessage.c_str());
                  if((mutex = CheckForInstance(WM_MYMSG)) == NULL)
                     return 0 ;    //  second instance
                  Application->Title = sTitle;
                  Application->Initialize();
                  Application->CreateForm(__classid(TFormMain), &FormMain);
                  Application->CreateForm(__classid(TAboutBox), &AboutBox);
                  Application->Run();
         }
</snip>

//---------------------------------------------------------------------------
HANDLE CheckForInstance(const UINT WM_MYMSG)
{
   SetLastError(0) ;
   char * m_Name = "USDA.FS.FireScience.GooleEarthTool";
   HANDLE m_Handle = CreateMutex(NULL, false, m_Name);
   if(m_Handle != NULL)
     return m_Handle;      // this is the first instance
   if(GetLastError() == ERROR_ALREADY_EXISTS)
     PostMessage(HWND_BROADCAST, WM_MYMSG, NULL, NULL);
   return NULL;     //  NULL handle
}


<snip>
        if (mutex != NULL)
            ReleaseMutex(mutex);
</snip>

-- In TFormMain

//----------------------------------------------------------------------------
void __fastcall TFormMain::WndProc(TMessage& message)
{
    if(message.Msg == WM_MYMSG)
      FormMain->Show();
    else
       TForm::WndProc(message); //pass on to parent
}
Re: Mutex troubles?
#4375
Author: Bruce Salzman
Date: Fri, 24 Feb 2006 20:59
17 lines
1480 bytes
"Nate Lockwood" <RNLockwoodREMOVE@attglobal.net> wrote in message 
news:43ff726e$1@newsgroups.borland.com...
> I'm trying to have my program detect that another instance is 
> running, send a "Show" message to the already running instance, and 
> then return. I'm using Builder 6.
>
> It appears that I always get a non null mutex so the message is 
> never sent.  Here's some code.
>

You *should* get the handle to the existing mutex. You have to call 
GetLastError() after CreateMutex() to see if it returns 
ERROR_ALREADY_EXISTS.

-- 
Bruce 
Re: Mutex troubles?
#4373
Author: Nate Lockwood
Date: Fri, 24 Feb 2006 21:03
24 lines
1733 bytes
  Bruce Salzman wrote:


> You *should* get the handle to the existing mutex. You have to call 
> GetLastError() after CreateMutex() to see if it returns 
> ERROR_ALREADY_EXISTS.

Thanks, I got that thought after I posted and changed my code to that 
below.  The first instance is detected but the message doesn't get through.

Nate

HANDLE CheckForInstance(const UINT WM_MYMSG)
{
   SetLastError(0) ;
   char * m_Name = "USDA.FS.FireScience.GooleEarthTool";
   HANDLE m_Handle = CreateMutex(NULL, false, m_Name);
   if(m_Handle != NULL)
     if(GetLastError() != ERROR_ALREADY_EXISTS)
       return m_Handle;      // this is the first instance

   PostMessage(HWND_BROADCAST, WM_MYMSG, NULL, NULL);
   return NULL;     //  NULL handle
}
Re: Mutex troubles?
#4376
Author: Nate Lockwood
Date: Fri, 24 Feb 2006 22:28
1 lines
1085 bytes
I'll start another thread now that I have the mutex problem fixed.
Re: Mutex troubles?
#4378
Author: Remy Lebeau (TeamB)
Date: Fri, 24 Feb 2006 23:29
91 lines
3260 bytes
"Nate Lockwood" <RNLockwoodREMOVE@attglobal.net> wrote in message
news:43ff726e$1@newsgroups.borland.com...

> It appears that I always get a non null mutex

As you should be.  That is what CreateMutex() does.  You are not taking into
account that the returned pointer is always non-NULL even if the pointer
belongs to another existing mutex.  The only time CreateMutex() returns NULL
is when a real error occurs (out of resources, etc).

> Here's some code.

Use something more like the following code instead:

    --- Project .cpp---

    UINT WM_MYMSG = 0;

    WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
        WM_MYMSG =
RegisterWindowMessage("USDA.FS.FireScience.GooleEarthTool.Awake");

        HANDLE mutex = ::CreateMutex(NULL, TRUE,
"USDA.FS.FireScience.GooleEarthTool");
        if( m_Handle == NULL )
            return 0;

        if( ::GetLastError() == ERROR_ALREADY_EXISTS )
        {
            if( WM_MYMSG != 0 )
            {
                Application->Title = "";
                HWND hWnd = ::FindWindow("TApplication", "Google Earth (C)
Tool");
                if( hWnd )
                    ::PostMessage(hWnd, WM_MYMSG, NULL, NULL);
            }
        }
        else
        {
            try
            {
                Application->Title = "Google Earth (C) Tool";
                Application->Initialize();
                Application->CreateForm(__classid(TFormMain), &FormMain);
                Application->CreateForm(__classid(TAboutBox), &AboutBox);
                Application->Run();
            }
            catch(Exception &exception)
            {
                SysUtils::ShowException(&exception);
            }
        }

        if( mutex )
            ::CloseHandle(mutex);

        return 0;
    }


    --- Form.cpp ---

    extern UINT WM_MYMSG;

    __fastcall TFormMain::TFormMain(TComponent *Owner)
        : TForm(Owner)
    {
        Application->OnMessage = AppMessage;
    }

    __fastcall TFormMain::~TFormMain()
    {
        Application->OnMessage = NULL;
    }

    void __fastcall TFormMain::AppMessage(MSG &Msg, bool &Handled)
    {
        if( (Msg.message == WM_MYMSG) && (WM_MYMSG != 0) )
        {
            Handled = true;
            Show();
        }
        else
            Handled = false;
    }


Gambit
Re: Mutex troubles?
#4379
Author: Remy Lebeau (TeamB)
Date: Fri, 24 Feb 2006 23:30
17 lines
1477 bytes
"Nate Lockwood" <RNLockwoodREMOVE@attglobal.net> wrote in message
news:43ff748a$1@newsgroups.borland.com...

> The first instance is detected but the message doesn't get through.

You are not catching the message properly.  You are trying to catch it at
from TForm, but you are doing a broadcast post which means the TApplication
will catch the message instead.  See my other reply.

>    PostMessage(HWND_BROADCAST, WM_MYMSG, NULL, NULL);
>    return NULL;     //  NULL handle

You are not freeing the mutex before returning.


Gambit
Re: Mutex troubles?
#4382
Author: Nate Lockwood
Date: Fri, 24 Feb 2006 23:42
10 lines
1245 bytes
Remy Lebeau (TeamB) wrote:


> You are not freeing the mutex before returning.
> 

Thanks for the warning, I did free is some lines later.  Forgot to 
mention it.

Nate
Re: Mutex troubles?
#4383
Author: Nate Lockwood
Date: Sat, 25 Feb 2006 01:27
7 lines
1256 bytes
Thanks very much, I learned a lot and it works just as I wanted it to 
after I changed the Show to Application->Restore(). <G>

I'd like to pass a string, too, do I understand correctly that I can 
create a string in the heap and pass it by reference?

Nate
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads