Delphi7如何让一个窗口永远置前?

zzyhost 2015-10-22 12:42:15
比如一个窗口跟QQ窗口比,当它被QQ窗口覆盖时立马让它跑到前面来



这样写不管用啊
...全文
2159 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
一本假正经 2017-10-09
  • 打赏
  • 举报
回复
引用 8 楼 yangb0803 的回复:
額, 我就有一个程序,让窗口一直置顶,并且焦点也不移出去的。就用到了 GetForegroundWindow , 从xp 到win7 目前沒发现失效的情况。

procedure Tfrm.GetFromFouce(Sender: TObject);
var
  TopHandle: HWND ;
begin
  TopHandle := FindWindow(nil,ShowHintInfo);
  if not (GetParent(TopHandle) = frm.Handle) then
     WindowActive(frm.Handle);  
end;

function Tfrm.WindowActive(hwnd: THandle): boolean;
const
  SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;
  SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;
var
  ForegroundThreadID: DWORD;
  ThisThreadID : DWORD;
  timeout : DWORD;
begin
  if IsIconic(hwnd) then ShowWindow(hwnd, SW_RESTORE);  //如果窗口最小化,激活窗口
  if GetForegroundWindow = hwnd then Result := true     //焦点为本窗口
  else
  begin
    if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion > 4))
      or((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and
        ((Win32MajorVersion > 4) or ((Win32MajorVersion = 4) and
          (Win32MinorVersion > 0)))) then
    begin
      Result := false;
      ForegroundThreadID :=
      GetWindowThreadProcessID(GetForegroundWindow,nil);
      ThisThreadID := GetWindowThreadPRocessId(hwnd,nil);
      if AttachThreadInput(ThisThreadID, ForegroundThreadID, true) then
      begin
        BringWindowToTop(hwnd);
        SetForegroundWindow(hwnd);
        AttachThreadInput(ThisThreadID, ForegroundThreadID, false);
        Result := (GetForegroundWindow = hwnd);
      end;
      if not Result then
      begin
        SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout, 0);
        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(0),SPIF_SENDCHANGE);
        BringWindowToTop(hwnd);
        SetForegroundWindow(hWnd);
        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,TObject(timeout), SPIF_SENDCHANGE);
      end;
    end
    else
    begin
      BringWindowToTop(hwnd);
      SetForegroundWindow(hwnd);
    end;
    Result := (GetForegroundWindow = hwnd);
  end;
end;
请问这里面的 ShowHintInfo 是什么意思呢?
nextop88 2017-06-19
  • 打赏
  • 举报
回复
procedure TForm1.FormCreate(Sender: TObject); begin with form1 do begin { Position form } Top := 0 ; Left := 0 ; { Go full screen} BorderStyle := bsDialog ; WindowState := wsmaximized; ClientWidth := Screen.Width ; ClientHeight := Screen.Height; Refresh; SetForegroundWindow(Handle) ; SetActiveWindow(Application.Handle) ; end; end; end.
浩南_哥 2015-10-23
  • 打赏
  • 举报
回复
引用 5 楼 u013402605 的回复:
[quote=引用 4 楼 lyhoo163 的回复:] 通过Timer定时检测,设置自己在最顶层,是一个好办法。
我觉得最好的办法是timer里不断的检测发现最顶层窗口不是自己时才设置一下,说到底还是不知道怎么判断自己是否在顶层[/quote] 不用检测自己是不是在最顶层,只用在Timer里设置自己在最顶层就行了,不管自己是不是已经在最顶层
tcmakebest 2015-10-23
  • 打赏
  • 举报
回复
要求不要太高,置顶就行了: self.FormStyle:=fsStayOnTop;
道玄希言 2015-10-23
  • 打赏
  • 举报
回复
通过timer事件执行。 GetFromFouce 为 timer 事件。
道玄希言 2015-10-23
  • 打赏
  • 举报
回复
額, 我就有一个程序,让窗口一直置顶,并且焦点也不移出去的。就用到了 GetForegroundWindow , 从xp 到win7 目前沒发现失效的情况。

procedure Tfrm.GetFromFouce(Sender: TObject);
var
  TopHandle: HWND ;
begin
  TopHandle := FindWindow(nil,ShowHintInfo);
  if not (GetParent(TopHandle) = frm.Handle) then
     WindowActive(frm.Handle);  
end;

function Tfrm.WindowActive(hwnd: THandle): boolean;
const
  SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;
  SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;
var
  ForegroundThreadID: DWORD;
  ThisThreadID : DWORD;
  timeout : DWORD;
begin
  if IsIconic(hwnd) then ShowWindow(hwnd, SW_RESTORE);  //如果窗口最小化,激活窗口
  if GetForegroundWindow = hwnd then Result := true     //焦点为本窗口
  else
  begin
    if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion > 4))
      or((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and
        ((Win32MajorVersion > 4) or ((Win32MajorVersion = 4) and
          (Win32MinorVersion > 0)))) then
    begin
      Result := false;
      ForegroundThreadID :=
      GetWindowThreadProcessID(GetForegroundWindow,nil);
      ThisThreadID := GetWindowThreadPRocessId(hwnd,nil);
      if AttachThreadInput(ThisThreadID, ForegroundThreadID, true) then
      begin
        BringWindowToTop(hwnd);
        SetForegroundWindow(hwnd);
        AttachThreadInput(ThisThreadID, ForegroundThreadID, false);
        Result := (GetForegroundWindow = hwnd);
      end;
      if not Result then
      begin
        SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout, 0);
        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(0),SPIF_SENDCHANGE);
        BringWindowToTop(hwnd);
        SetForegroundWindow(hWnd);
        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,TObject(timeout), SPIF_SENDCHANGE);
      end;
    end
    else
    begin
      BringWindowToTop(hwnd);
      SetForegroundWindow(hwnd);
    end;
    Result := (GetForegroundWindow = hwnd);
  end;
end;
lyhoo163 2015-10-22
  • 打赏
  • 举报
回复
这是QQ比你的软件,获取最低层的权限,它在 First Top 的原故。 只在你 First Top(始终保持焦点),才能达到你的要求。
zzyhost 2015-10-22
  • 打赏
  • 举报
回复
引用 4 楼 lyhoo163 的回复:
通过Timer定时检测,设置自己在最顶层,是一个好办法。
我觉得最好的办法是timer里不断的检测发现最顶层窗口不是自己时才设置一下,说到底还是不知道怎么判断自己是否在顶层
lyhoo163 2015-10-22
  • 打赏
  • 举报
回复
通过Timer定时检测,设置自己在最顶层,是一个好办法。
浩南_哥 2015-10-22
  • 打赏
  • 举报
回复
QQ是自己开了一个Timer不断检测,在Timer里面去设置自己在最顶层
zzyhost 2015-10-22
  • 打赏
  • 举报
回复
找到两个api函数,但是都不行,所以别说了 GetActiveWindow GetForegroundWindow 当窗体失去焦点时即使仍在最前面这俩函数返回句柄也不是自己了,不信可以测试一下 if GetActiveWindow <> Self.Handle then memo1.Text :=Memo1 .Text +'s';

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧