Mutley2003
asked on
2 shortcuts, 1 instance
I asked a variant of this question at
"A single hotkey doing wakeup and global duty"
https://www.experts-exchange.com/questions/21122673/A-single-hotkey-doing-wakeup-and-global-duty.html
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?
Thanks
"A single hotkey doing wakeup and global duty"
https://www.experts-exchange.com/questions/21122673/A-single-hotkey-doing-wakeup-and-global-duty.html
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?
Thanks
oh yea, , It is my impression that if you never call the
Application.Initialize;
Application.CreateForm(TFo rm1, 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
Application.Initialize;
Application.CreateForm(TFo
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
ASKER
hi Slick812
https://www.experts-exchange.com/questions/20623659/PostMessage-returns-wierd-string.html
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.Initialize;
Application.CreateForm(TFo rm1, 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?
https://www.experts-exchange.com/questions/20623659/PostMessage-returns-wierd-string.html
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.Initialize;
Application.CreateForm(TFo
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?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Oh this DOES not set a Mutex if there is Not one, so you will still need to set the mutex in your MegaApp
ASKER
Slick812,
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
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
????
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);
var
i: Integer;
PrePc, ScanPc: PChar;
Str1: String;
begin
// 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.CopyDataS truct^.lpD ata)) > 0 then
begin
Msg.Result := 17;
if msg.CopyDataStruct^.dwData = 1 then
begin
Str1 := PChar(msg.CopyDataStruct^. lpData);
Form1.Label3.Caption := Str1;
end
end;
end;
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);
var
i: Integer;
PrePc, ScanPc: PChar;
Str1: String;
begin
// 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.CopyDataS
begin
Msg.Result := 17;
if msg.CopyDataStruct^.dwData
begin
Str1 := PChar(msg.CopyDataStruct^.
Form1.Label3.Caption := Str1;
end
end;
end;
ASKER
thanks Slick812 .. I have plenty to work with now
"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! -
https://www.experts-exchange.com/questions/20623659/PostMessage-returns-wierd-string.html
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,