This is a good example of the writer not quite understanding what the code is doing and not seeing a specific situation where a bug would present itself. In this case from glancing at the code on the page, Mr. Gajic seems to not notice that the method he is using involves file mapping, which depends on the path the program is in.
Anyhow...(one of those "I hate API Windows manipulation" things coming up) I'll post in pieces to explain what is going on:
Code:
program semtest;
uses
Forms,
Dialogs,
Sysutils,
Windows,
Messages,
semunit in 'semunit.pas' {Form1};
This is obviously the main source module of the project. We would have to put code here, since we need to stop running the standard VCL inits (Application.*) if we find another copy of the program is running. "semunit" is a VCL form, which has a button that quits the program, but it really doesn't matter for our example.
Code:
{$R *.RES}
var
MySem: THandle; // semaphore address
WinHandle: HWND; // window handle address
begin
Code:
{ Create semaphore, check for previous program existence, end if there }
MySem := CreateSemaphore(nil,0,1,'MySemTest');
if ((MySem <> 0) and (GetLastError = ERROR_ALREADY_EXISTS)) then
begin
MessageDlg('Program is already running', mtError, [mbOK], 0);
Here's what's doing the job. When you start your program, you set up a semaphore with whatever name you want. In the process of creating it, you can error-check for whether one already exists. The if statement is what is doing that.
Code:
WinHandle := FindWindow(PChar('TApplication'), PChar('semtest'));
if IsWindowVisible(WinHandle) then
SendMessage(WinHandle, WM_SYSCOMMAND, SC_RESTORE, 0);
Now this is what is bringing the window to foreground. The first statement is to locate the window handle of the other program. (This is where the "I hate API window manipulation" comes in) Each window has an associated class name and window name. Hopefully, they are relatively unique, or this code falls apart.
Of course, if you browse windows (using GetWindow or EnumWindows), you'll find that there are windows with pretty wierd class and window names. This necessitates browsing for them if you are uncertain or using a program like
Windowse. The standard for Delphi apps seems to be "TApplication" for class name and the caption name for the minimized window for the window name.
(of course if there's a much better way to do this, I would love to know.)
2nd line: Does it have a window associated with it?
3rd line: sends a message to the window to restore it.
Code:
CloseHandle(MySem);
end
else
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
CloseHandle(MySem);
end.
else block of the code contains the Application.* calls.
HTH some.
----------
Measurement is not management.