如何检查打开的表单实例是否来自设计师?

时间:2011-07-19 22:25:53

标签: delphi winapi

Delphi应用程序检查表单实例是否已经以这种方式打开:

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

问题是,当表单作为Delphi Designer窗口打开时,它表示表单是打开的。我刚刚失去了一些工作时间,因为当我打开一个表单并单击断点一个方法时,应用程序停止工作:-(

如果在Designer中创建表单类实例,如何使此函数返回false?


答案:
opc0de的建议下面给了我一个很好的解决方案,所以我接受他的评论作为答案。我需要更改代码以遍历所有打开的表单。这是世界上副本的快乐代码的最终版本:

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;

2 个答案:

答案 0 :(得分:5)

如果您这样做,只运行一个应用程序实例,请执行以下操作:使用互斥锁。有关创建和使用互斥锁的方法,请参阅my answerthis question,或查看针对Jedi实施的该问题的已接受答案。

如果您可以设法创建互斥锁,那么就不要寻找窗口:即使您找到了它,也可以来自IDE或恰好具有相同名称的其他应用程序。

答案 1 :(得分:3)

使用Getwindowthreadprocessid来获取窗口的进程ID,如果该Id等于你的进程,这意味着它是一个有效的window.sorry我不能发布一个例子,但我正在从我的手机上写