Peter Below 的线程启动屏幕和模态对话框

Ken*_*ite -2 delphi winapi

我正在使用Peter Below 的 PBThreadedSplashForm在应用程序启动期间显示。在创建数据模块期间(就在创建主窗体之前),它会随着各种数据库的打开而更新。

问题是我们要检查在创建数据模块期间所做的某些事情是否存在。如果缺少任何这些项目,则会显示一个模式对话框,以便可以创建该项目或关闭应用程序。(缺少的项目通常是索引,该对话框主要在我们重新索引数据库时使用,因此它针对的是开发人员而不是普通用户。)但是,模式对话框显示在启动屏幕后面;随着标题的变化,它似乎是焦点窗口,但它显示在启动屏幕后面。

启动屏幕是使用 Windows API CreateWindowEx() 从与主进程不同的线程创建的,使用以下代码:

procedure TPBSplashThread.CreateSplashWindow;
const
  TopmostStyle: Array [Boolean] of DWORD = (0, WS_EX_TOPMOST );
  NoActivateStyle : Array [Boolean] of DWORD = (0, WS_EX_NOACTIVATE );
var
  wsize: TSize;
begin
  wsize.cx := FSurface.Width + GetSystemMetrics( SM_CXEDGE ) * 2;
  wsize.cy := FSurface.Height + GetSystemMetrics( SM_CYEDGE ) * 2;
  FWnd := CreateWindowEx(
            TopmostStyle[ FTopmost ] or WS_EX_TOOLWINDOW
            or WS_EX_STATICEDGE or WS_EX_CLIENTEDGE
            or NoActivateStyle[ Win32MajorVersion >= 5 ],
            MakeIntResource( FWndClass ),
            nil,
            WS_POPUP or WS_BORDER,
            Forigin.x, Forigin.y,
            wsize.cx, wsize.cy,
            0, 0, hInstance, self );
  If FWnd = 0 Then
    raise exception.create('TPBSplashThread.CreateSplashWindow: CreateWindowEx failed');
end;
Run Code Online (Sandbox Code Playgroud)

FTopmost 是一个从未设置过的属性(具有明显的含义),因此由于类构造期间的默认初始化,它为 False。(我还尝试将其显式设置为 False,以防万一,但没有效果。)我还尝试在模式对话框的 OnShow 事件期间使用 SetForegroundWindow() 和 SetWindowPos() ,但没有效果。

有谁知道可能是什么原因造成的?

Ken*_*ite 5

好的。终于把问题解决了。它似乎是由调用 CreateWindowEx() 中的 WS_EX_NOACTIVATE 标志引起的。将其更改为删除似乎可以解决问题;模式对话框显示在启动屏幕上方,并且由于它是模式对话框,因此无法将启动屏幕置于其上方。

工作代码是:


  FWnd := CreateWindowEx(
            TopmostStyle[ FTopmost ] or WS_EX_TOOLWINDOW
            or WS_EX_STATICEDGE or WS_EX_CLIENTEDGE,
            MakeIntResource( FWndClass ),
            nil,
            WS_POPUP or WS_BORDER,
            Forigin.x, Forigin.y,
            wsize.cx, wsize.cy,
            0, 0, hInstance, self );
Run Code Online (Sandbox Code Playgroud)

感谢罗布和克雷格的努力。