Board index » delphi » Delphi 2.0 tip: hPrevInst doesn't work!

Delphi 2.0 tip: hPrevInst doesn't work!

        Folks,
        For those who write program which only allow themselves to be run once,
and use the "hPrevInst" variable from the project source to determine this,

you may be surprised to find out that Win32 apps (and by extension all
programs written with Delphi 2.0) *always* see hPrevInst=0.  This foils
the traditional test of:

{ in project source }
begin
        if hPrevInst = 0 then begin
                { this program isn't running elsewhere... but in Win32
                  it may be! }
        end
        else
                messagedlg('I''m already running!', mtinformation, [mbok], 0);
end;

This was pretty frustrating in my screen saver, which performs this test
successfully in Win31, but winds up getting run several time in Win32
because each instance thinks that it's the only one.
        If you search the Win32 help files (using the grossly obese Find
function) for "hprevinstance" you'll find a Knowledge Base article which
discusses this and provides some suggestions.  Rather than quote the
article which doesn't give too much guidance, I'll provide my version of
their Win32 solution:

program foobar;

uses
  windows;      { needed for declarations of ATOM functions }

{$R *.RES}

var
   hMyAtom  :longint;
begin
        { look for a unique string ATOM }
        hMyAtom := GlobalFindAtom('MyUniqueString');

        if hMyAtom = 0 then begin
                { the ATOM wasn't found so run the program }

                { create the ATOM so that other instances won't load }
                hMyAtom := globaladdatom('MyUniqueString');

                {
                do something, such as running the program
                }

                { delete the ATOM so that this program can be run again }
                globaldeleteatom(hMyAtom);
   end;
end.

This works pretty well under all Win32 systems.  Any other suggestions
along these lines would be welcome.

                                                Fritz

"I'll gently raise and softly call,    | Fritz Lowrey
 Goodnight my friends, and joy to all."| Internet: jlow...@ucs.usc.edu
   "A Parting Glass", Irish Traditional|

 

Re:Delphi 2.0 tip: hPrevInst doesn't work!


On Tue, 12 Mar 1996 19:29:45 GMT, jlow...@ucs.usc.edu (Fritz Lowrey)
wrote:

Quote
>    Folks,
>    For those who write program which only allow themselves to be run once,
>and use the "hPrevInst" variable from the project source to determine this,

>you may be surprised to find out that Win32 apps (and by extension all
>programs written with Delphi 2.0) *always* see hPrevInst=0.  This foils
>the traditional test of:

>{ in project source }
>begin
>    if hPrevInst = 0 then begin
>            { this program isn't running elsewhere... but in Win32
>              it may be! }
>    end
>    else
>            messagedlg('I''m already running!', mtinformation, [mbok], 0);
>end;

>This was pretty frustrating in my screen saver, which performs this test
>successfully in Win31, but winds up getting run several time in Win32
>because each instance thinks that it's the only one.
>    If you search the Win32 help files (using the grossly obese Find
>function) for "hprevinstance" you'll find a Knowledge Base article which
>discusses this and provides some suggestions.  Rather than quote the
>article which doesn't give too much guidance, I'll provide my version of
>their Win32 solution:

>program foobar;

>uses
>  windows;  { needed for declarations of ATOM functions }

>{$R *.RES}

>var
>   hMyAtom  :longint;
>begin
>    { look for a unique string ATOM }
>    hMyAtom := GlobalFindAtom('MyUniqueString');

>    if hMyAtom = 0 then begin
>            { the ATOM wasn't found so run the program }

>            { create the ATOM so that other instances won't load }
>            hMyAtom := globaladdatom('MyUniqueString');

>            {
>            do something, such as running the program
>            }

>            { delete the ATOM so that this program can be run again }
>            globaldeleteatom(hMyAtom);
>   end;
>end.

>This works pretty well under all Win32 systems.  Any other suggestions
>along these lines would be welcome.

>                                            Fritz

>"I'll gently raise and softly call,    | Fritz Lowrey
> Goodnight my friends, and joy to all."| Internet: jlow...@ucs.usc.edu
>   "A Parting Glass", Irish Traditional|

This is how I've been doing it...

procedure tmyclass.create(sender:tobject);
var
        tempcaption:string;
begin
        tempcaption:=caption;
        caption:=''; {do this to keep from finding yourself}
        if findwindow(myclass,tempcaption) then halt;
        caption:=tempcaption;
end;

Zane Rathwick
Indigo Software
Za...@aol.com

Re:Delphi 2.0 tip: hPrevInst doesn't work!


Quote
Zane Rathwick wrote:

> On Tue, 12 Mar 1996 19:29:45 GMT, jlow...@ucs.usc.edu (Fritz Lowrey)
> wrote:

> >       Folks,
> >       For those who write program which only allow themselves to be run once,
> >and use the "hPrevInst" variable from the project source to determine this,

> >you may be surprised to find out that Win32 apps (and by extension all
> >programs written with Delphi 2.0) *always* see hPrevInst=0.  This foils
> >the traditional test of:

> >{ in project source }
> >begin
> >       if hPrevInst = 0 then begin
> >               { this program isn't running elsewhere... but in Win32
> >                 it may be! }
> >       end
> >       else
> >               messagedlg('I''m already running!', mtinformation, [mbok], 0);
> >end;

> >This was pretty frustrating in my screen saver, which performs this test
> >successfully in Win31, but winds up getting run several time in Win32
> >because each instance thinks that it's the only one.
> >       If you search the Win32 help files (using the grossly obese Find
> >function) for "hprevinstance" you'll find a Knowledge Base article which
> >discusses this and provides some suggestions.  Rather than quote the
> >article which doesn't give too much guidance, I'll provide my version of
> >their Win32 solution:

> >program foobar;

> >uses
> >  windows;     { needed for declarations of ATOM functions }

> >{$R *.RES}

> >var
> >   hMyAtom  :longint;
> >begin
> >       { look for a unique string ATOM }
> >       hMyAtom := GlobalFindAtom('MyUniqueString');

> >       if hMyAtom = 0 then begin
> >               { the ATOM wasn't found so run the program }

> >               { create the ATOM so that other instances won't load }
> >               hMyAtom := globaladdatom('MyUniqueString');

> >               {
> >               do something, such as running the program
> >               }

> >               { delete the ATOM so that this program can be run again }
> >               globaldeleteatom(hMyAtom);
> >   end;
> >end.

> >This works pretty well under all Win32 systems.  Any other suggestions
> >along these lines would be welcome.

> >                                               Fritz

> >"I'll gently raise and softly call,    | Fritz Lowrey
> > Goodnight my friends, and joy to all."| Internet: jlow...@ucs.usc.edu
> >   "A Parting Glass", Irish Traditional|

> This is how I've been doing it...

> procedure tmyclass.create(sender:tobject);
> var
>         tempcaption:string;
> begin
>         tempcaption:=caption;
>         caption:=''; {do this to keep from finding yourself}
>         if findwindow(myclass,tempcaption) then halt;
>         caption:=tempcaption;
> end;

> Zane Rathwick
> Indigo Software
> Za...@aol.com

This is the way I solved the problem in a program I wrote with VC++ for windows NT.

BOOL CCronApp::InitInstance()
{
    // Get out of here if Application already loaded
    if( !::EnumWindows(LookForCron, 0) )
    {
        AfxMessageBox("CRON is already running");
        return FALSE;
    }

    (more stuff here...)

"LookForCron" is a callback function:

BOOL CALLBACK LookForCron(HWND hwnd, LPARAM lParam)
{
    CString WinName;
    if( ::GetWindowText(hwnd, WinName.GetBuffer(5), 5) > 0 )
    {
        WinName.ReleaseBuffer();
        WinName.MakeUpper();
        if( WinName == "CRON" )
            return FALSE;
    }
    return TRUE;

Quote
}

In other words, I use the Windows API functioon "EnumWindows" to look for a particular windows
(though is title, or part of it).

--
Gabriel Beccar-Varela
E-Mail gabr...@emf.net

______

Other Threads