2 shortcuts, 1 instance

Posted on 2004-09-17
Last Modified: 2010-04-05
I asked a variant of this question at

"A single hotkey doing wakeup and global duty"

and accepted the answer - that it was basically a matter of using a mutex to enforce a single instance and passing through an indication of which shortcut key was used via SendMessage.

However, I started thinking <g> and it seems to me that enforcing a single instance via a mutex is inefficient.  My concern is that a second copy of the exe (MyMegaApp) is actually loaded into memory BEFORE it gets killed (after detecting the mutex).

How about this. The shortcut keys actually call a small "loader" app. It is that app which then "spawns" MyMegaApp but ONLY if needed (ie no mutex). Some sort of WinExecAndWait or is CreateProcess what I need?. We still use a SendMessage to send the arguments.. hmm, would it be better to use a more general interprocess communications approach (so I can send more stuff).

Anyone care to look at the previous answer and improve on it, given these ideas?


Question by:Mutley2003
  • 5
  • 3
LVL 34

Expert Comment

ID: 12090373
hello  Mutley2003, , I am not sure that I am getting what you want or need to have done? you say something about -
"is actually loaded into memory BEFORE it gets killed"
and why do you have a problem with this? are you getting complaints form users about system error of running out of memory when your program loads? or some memory problems?
anyway, here is a EE question that shows a better (in my opinion) mutex for single instance  PLUS it sends the first parameter to the running program! -

if you think you need a "Small Program" to run and  do the mutext thing and then launch your program, I could do an API program of 20 Kb or so to test the mutext, and then run your other program, but I can not at this point see any need for a  WinExecAndWait or a CreateProcess and a wait. . . you should just use a shellexecute if there is no mutext, but it seems, like this could cause other problems, if you need one program inorder to launch another (the main) program,
LVL 34

Expert Comment

ID: 12090387
oh yea, , It is my impression that if you never call the

  Application.CreateForm(TForm1, Form1);

the Application and "Form" are not loaded into a Memory block, so none of the Form's class is ever given any memory for functioning

Author Comment

ID: 12090783
hi Slick812

does a nice job of passing string data via WM_COPYDATA, thanks.

I guess I don't understand enough about how windows loads an exe .. you say

"It is my impression that if you never call the

  Application.CreateForm(TForm1, Form1);

the Application and "Form" are not loaded into a Memory block, so none of the Form's class is ever given any memory for functioning"

well, there would not be any dynamic memory allocations obviously, but I would have thought that all the code and data gets loaded ... that is, an "image" of the exe.

How to test this?

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

LVL 34

Accepted Solution

Slick812 earned 500 total points
ID: 12091956
Yea, I spoke to soon, sleepy I guess :-) , the exe is loaded into the programs Instance on start of program , , , Sorry

so you want some way to NOT load your program, if a Mutex is up??
I think I would have a "Small" GUI program (only code for the basic Form) and then move all of my "Large Code" or whatever makes your program into a MegaApp into several DLL's and then if your program Runs, you then load the DLLs (this would make "Updating" your App easier also). .  However, It would probally take alot of work to do this. . . .

If you just want a "Small" do nothing app that ONLY tests for the Mutex, you might try something like this, Here is some code for a .DPR  file in delphi, there is NO GUI, no windows are created, the user sees NOTHING (well and error message is it craps out), all it does is Open a mutex and if there is no mutex then it starts a program. . . . . . .

program preMutex;

  ShellApi, Windows;

hMutex: Cardinal;
i: Integer;
StartApp, ParamS1: String;

hMutex := OpenMutex(MUTEX_ALL_ACCESS,False,'h8J3Cn90?%x7');
if hMutex = 0 then
  for i := 1 to ParamCount do
    ParamS1 := ParamS1+'"'+ParamStr(i)+'" ';
  StartApp := ExtractFilePath(ParamStr(0))+'WesThumbs.exe';
  if ShellExecute(0,'open',PChar(StartApp),PChar(ParamS1),nil,SW_SHOWDEFAULT) < 33 then
    MessageBox(0, PChar('ERROR - Could NOT start program'#10+StartApp),
               'ERROR Program was NOT Started', MB_ICONERROR or MB_TOPMOST);;
  end else

this DOES NOT send the parameters to an already running program,
if you need that, you can get the code for that at the other EE question
LVL 34

Expert Comment

ID: 12091959
Oh this DOES not set a Mutex if there is Not one, so you will still need to set the mutex in your MegaApp

Author Comment

ID: 12094187
maybe I am sleepy too (or just thick<g>).. but you have shown me how to start an app if there is no mutex, cool.

If there is a mutex, then OK we send stuff to the already running instance (via WM_COPYDATA) .  There is still the issue of how to "wake up" that instance. Maybe it is just something in the WM_COPYDATA event handler to make a form visible/active

LVL 34

Expert Comment

ID: 12094229
OK, I have NO IDEA what your program may or may not be doing. . .I don't know if it is minimized or hidden or whatever. So when you get the WM_COPYDATA message you can use the parameters in the TWmCopyData to indicate "Different" types of WM_COPYDATA data, if you need to do that,, , , ,
 but as for your "Wake Up" the main app, , well yes, you can do code to do whatever you need if minimized or hidden or small or whatever

procedure TForm1.GetCopyData(var Msg: TWmCopyData);
i: Integer;
PrePc, ScanPc: PChar;
Str1: String;
// add a test and then a change when you get a WM_COPYDATA message

if  not Visible then Show;
if mininized then Maximize;
if IsSmall then MakeBig;

Msg.Result := 0;
if StrLen(PChar(msg.CopyDataStruct^.lpData)) > 0 then
              Msg.Result := 17;
              if msg.CopyDataStruct^.dwData = 1 then
                Str1 := PChar(msg.CopyDataStruct^.lpData);
                Form1.Label3.Caption := Str1;


Author Comment

ID: 12094341
thanks Slick812 .. I have plenty to work with now

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question