【问题标题】:How can get my form to be on top of everything all the time?怎样才能让我的表格始终处于领先地位?
【发布时间】:2010-07-14 02:19:46
【问题描述】:

我有这些小光标形状的表格,我需要一直处于一切之上...
FormStyle 已经是 fsStayOnTop
我使用此代码:

 SetWindowPos(tempCursor.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE );

还有这个(尽管我不完全知道它的作用):

procedure TCursorFrm.CreateParams(var Params: TCreateParams);
const
   WS_EX_NOACTIVATE = $8000000;
begin
   inherited;
   Params.ExStyle := Params.ExStyle + WS_EX_NOACTIVATE;
end;

但我仍然无法让我的表单位于 TMenuItems 的顶部。 如何让我的表单始终处于领先地位?

【问题讨论】:

    标签: delphi


    【解决方案1】:

    这必须是我要发布的终极或最糟糕的黑客作品。

    1. 将您的 FormStyle 设置为 fsStayOnTop(此步骤实际上可能没有必要)
    2. 在表单上放置一个 TTimer 并将其间隔设置为 100
    3. 在 OnTimer 事件中放置以下代码:

      如果可见则 SetWindowPos(Self.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE or SWP_NOACTIVATE);

    我在我的一个项目中使用它,它似乎工作正常。

    【讨论】:

    • 我查了字典,'hacky' 并没有准确地描述这个 hack 的 hacky 程度。为此我们需要一个新词。
    【解决方案2】:

    我认为这与您将获得的一样好。如果您的表单停留在菜单顶部,那么用户在打开菜单时将看不到菜单。做这样的事情,特别是当系统没有通过任何简单的方式使其可用时,接近恶意,或者至少感觉是这样。您不希望您的用户认为您的程序是恶意的,所以我的建议是首先不要尝试这样做。

    【讨论】:

    • 嗯,它应该是一个光标(多个鼠标的多个光标),这就是为什么它应该在顶部。光标在 MenuItems 后面有点奇怪。 :((哦,我不认为用户会认为它是恶意的,因为它看起来根本不像常规形式,它看起来像常规光标)
    • 哦,是光标?在那种情况下,您为什么要尝试使用 form 实现游标? 我敢肯定有更简单的方法。不知道那是什么,但必须有一个......
    • 因为它是在另一个问题中向我建议的,而且公平地说,除了菜单问题外,它运行良好。我的第一次尝试是在屏幕画布上绘制光标,这是一场噩梦(很多很多问题)。除了这两个之外,还没有真正找到其他方法。
    • 嗯...你会在我的全屏游戏上方“光标”吗?那么……诅咒你! :D
    • @亚历山大:哈哈哈!不,光标只会在我的应用程序(这是一个多用户输入和多项选择应用程序)运行时出现。
    【解决方案3】:

    快速、略显老套的修复:从计时器中调用,每秒 10 次:

    BringWindowToTop(Handle)
    

    刚刚试了一下,效果很好!也许您可以找到一种方法来减少“蛮力”,但我不确定如何。

    【讨论】:

    • 用计时器尝试过(如您所建议的)。我无法再访问菜单,当我单击菜单时,项目会出现一瞬间然后就消失了。
    • 什么“项目”?菜单消失了吗?如果是这样,请显示一些代码,也许您以某种方式从菜单中窃取焦点?在我的测试中,我只是制作了一个“留在顶部”窗口并在文本编辑器中单击鼠标右键,从而导致弹出菜单准确显示在表单下方。它按预期工作,菜单没有消失;当然,我并没有尝试模拟辅助鼠标光标...
    • 是的,MenuItems 消失了。将这个:BringWindowToTop(Cursor[I].Handle) 放在每秒执行的 for 循环中。是的,我想我正在从菜单中窃取焦点。
    • 为什么要在 for 循环中这样做?在某处放置一个计时器,将其间隔设置为“100”并从那里调用BringWindowToTop。而焦点问题,如果确实是这样的话,那就是另一个问题了。
    • 这是一个 for 循环,因为游标存储在一个数组中(记录...游标分配给特定用户,因此是特定记录)。是的,它从 Menu 和 MainForm 中窃取了焦点。
    【解决方案4】:

    我认为您可以研究 DirectX。我相信它允许覆盖主图像。您可以在非独占模式下打开它并在桌面上绘制叠加层。但我不确定。只是猜测。

    【讨论】:

      【解决方案5】:

      或者代替 SetWindowPos 命令 - 试试这个:

      if visible then form1.SetFocus;
      

      【讨论】:

        【解决方案6】:

        我在 OnShow 事件处理程序中使用以下指令序列:

        SetForegroundWindow(Handle);
        BringWindowToTop(Handle);
        

        【讨论】:

          猜你喜欢
          • 2011-12-28
          • 2010-12-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-21
          • 1970-01-01
          • 2016-09-19
          相关资源
          最近更新 更多