3

The Delphi application checks if a form instance is already open this way:

  form := FindWindow(PAnsiChar(FormClassName), nil);
  if form > 0 then
  begin
    SendMessage(form, WM_ACTIVATEAPP, 0, 0);
    Result := True;
  end else
    Result := False

The problem is that when the form is open as a Delphi Designer windows it says that the form is open. I've just lost some working hours because when I opened a form and clicked to breakpoint a method, the application stopped to work:-(

How do I make this function return false if the form class instance is created in the Designer?


Answer:
opc0de's suggestion below leaded me to a good solution, so I'm accepting his comment as the answer. I needed to change the code to iterate through all open forms. Here is the final version of the code for the happiness of the copy'n pasters of the world :

function VerifyFormIsOpen(formClass: String): Boolean;
var
  windowHndl, windowOld: HWND;
  processId: Cardinal;
begin
  windowOld := 0;
  windowHndl := 0;
  Result := False;
  repeat
    windowHndl :=  Windows.FindWindowEx(0, windowOld,
                                    PAnsiChar(formClass), nil);
    if (windowHndl > 0) then
    begin
      Windows.GetWindowThreadProcessId(windowHndl, processId);
      if processId = Windows.GetCurrentProcessId() then
      begin
        Windows.SendMessage(windowHndl, Messages.WM_ACTIVATEAPP, 0, 0);
        Result := True;
        break;
      end;
    end;
    windowOld := windowHndl;
  until windowHndl = 0;
end;
neves
  • 33,186
  • 27
  • 159
  • 192
  • Is this for a form in the current application or another? If another: are you indeed searching for a "singleton" solution for your application like @Cosmin Prund asked in his answer? – NGLN Jul 20 '11 at 10:26
  • @NGLN: It is another application, the IDE. The FindWindow checks all windows open in the system. The solution checks if the form is from the same process that is checking. – neves Jul 22 '11 at 20:35

2 Answers2

5

If you're doing this so only one instance of your application runs, do it right: Use a Mutex. See my answer to this question for a way to create and use the Mutex, or see the accepted answer to that question for the Jedi implementation.

If you can manage to create the Mutex then don't look for the window: even if you do find it, it's either from the IDE or from a different application that just happens to have the same name.

Community
  • 1
  • 1
Cosmin Prund
  • 25,498
  • 2
  • 60
  • 104
  • It is a nice solution, but the code above is in a library class that is used by dozens of company internal applications. I can't change the code everywhere. – neves Jul 20 '11 at 14:19
3

Use Getwindowthreadprocessid to get the process id of the window if that Id equals your process that means that is a valid window.sorry i can't post an example but i am writing from my mobile

opc0de
  • 11,557
  • 14
  • 94
  • 187
  • 1
    I would use EnumProcesses() to check if the window process ID belongs to an IDE instance, rather than the current process. That way, the code can check for windows that belong to other instances of the app, if that is desired. – Remy Lebeau Jul 20 '11 at 00:39
  • opc0de's suggestion leaded me to the correct solution. I'm accepting his comment as the answer and I'll put the complete solution in the question. – neves Jul 20 '11 at 20:47