【老生常谈】求一个可用的Delphi窗体置顶的代码......

yct0605 2014-10-14 03:00:28
系统环境:win7(32/64位系统)+D7,D7开发只有一个窗体
功能要求:窗体实现置顶显示,具体:
1.可以置顶于任务管理器之上(任务管理器最大化时,窗体可以置顶于任务管理器之上)
2.可以置顶于全屏运行的程序窗体显示
3.窗体失去焦点时置顶于桌面其他窗体显示(貌似是废话)
4.其他还没有想好...
...全文
377 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
aboutyych 2014-10-23
  • 打赏
  • 举报
回复
引用 5 楼 yct0605 的回复:
[quote=引用 3 楼 aboutyych 的回复:] SetWindowPos,定时检查自己的窗体是否在最顶层,如不是则重新设置。 在你的程序之后再至顶显示的话肯定是要在你的程序上面。
这个是视图图像,如果用定时器的话会影响图像的传输,视频图像会卡的[/quote] 不用Timer组件,用线程定时检查应该不会吧。 很容易实现的。

unit frm_Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TTopMostThread = class(TThread)
  protected
    FMainHandle: HWND;
    procedure Execute; override;
  public
    constructor Create(AMainHandle: HWND);  
  end;

  TfrmMain = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    FSetTop: TTopMostThread;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

{ TTopMostThread }

constructor TTopMostThread.Create(AMainHandle: HWND);
begin
  FreeOnTerminate := True;
  FMainHandle := AMainHandle;
  inherited Create(False);
end;

procedure TTopMostThread.Execute;
begin
  while not Terminated do
    begin
      SetWindowPos(FMainHandle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE);
      Sleep(100);    //可适当调整此值
    end;   
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  FSetTop := TTopMostThread.Create(Self.Handle);
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  FSetTop.Terminate;
end;

end.
踏雪无痕 2014-10-18
  • 打赏
  • 举报
回复
Application.NormalizeTopMosts;  
SetWindowPos(self.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or  SWP_NOSIZE);  
XE的Form有一个styleform属性就可以搞定
yct0605 2014-10-18
  • 打赏
  • 举报
回复
引用 8 楼 hnlg81004 的回复:
var
  WindowList: Pointer;
  ActiveWindow: HWnd;
begin
  ActiveWindow := GetActiveWindow;
  WindowList := DisableTaskWindows(ActiveWindow);
  {*显示进程对话框*}
  try
    if dlgProgress = nil then
      dlgProgress := TdlgProgress.Create(Application);
    dlgProgress.FormStyle:=fsStayOnTop;
    dlgProgress.Show;   //CSH
    dlgProgress.MessageText.Caption := msg_calculactioning;
    dlgProgress.Update; 
  finally
    EnableTaskWindows(WindowList);
    if ActiveWindow <> 0 then SetActiveWindow(ActiveWindow);
  end;
end;
这段代码怎么使用?dlgProgress?
yct0605 2014-10-18
  • 打赏
  • 举报
回复
引用 9 楼 lyhoo163 的回复:
从windows的机制来说,你的要求很难实现。 1、桌面上只通用一个置顶(焦点)。 2、当窗体置顶后,随时被其它窗体迭代。 3、其它窗体置顶后,重新置顶,需要击发机制。 解决方案: 1、SetWindowPos(handle,HWND_TOPMOST,Left,Top,Width,Height,SWP_SHOWWINDOW) 消息置顶 2、form1.FormStyle:=fsStayOnTop 设置窗体置顶类型,打开才能置顶 3、在窗体中定时检查,不断发出消息置顶。 4、深层次不允许其它程序置顶。
看来还是不好实现啊,如果在窗体内定时检查,频率快的话,会影响其他程序的输入状态。 D7这一点和C#.Net的窗体比起来还是有点不足的,C#.Net的窗体事件比D7的要多,而且对焦点控制的也比较好。
doloopcn 2014-10-17
  • 打赏
  • 举报
回复
引用 9 楼 lyhoo163 的回复:
从windows的机制来说,你的要求很难实现。 1、桌面上只通用一个置顶(焦点)。 2、当窗体置顶后,随时被其它窗体迭代。 3、其它窗体置顶后,重新置顶,需要击发机制。 解决方案: 1、SetWindowPos(handle,HWND_TOPMOST,Left,Top,Width,Height,SWP_SHOWWINDOW) 消息置顶 2、form1.FormStyle:=fsStayOnTop 设置窗体置顶类型,打开才能置顶 3、在窗体中定时检查,不断发出消息置顶。 4、深层次不允许其它程序置顶。
加上一个事件应该差不多了onlostfocus 就是在窗口失去焦点的时候,把1.SetWindowPos函数运行一次
lyhoo163 2014-10-17
  • 打赏
  • 举报
回复
从windows的机制来说,你的要求很难实现。 1、桌面上只通用一个置顶(焦点)。 2、当窗体置顶后,随时被其它窗体迭代。 3、其它窗体置顶后,重新置顶,需要击发机制。 解决方案: 1、SetWindowPos(handle,HWND_TOPMOST,Left,Top,Width,Height,SWP_SHOWWINDOW) 消息置顶 2、form1.FormStyle:=fsStayOnTop 设置窗体置顶类型,打开才能置顶 3、在窗体中定时检查,不断发出消息置顶。 4、深层次不允许其它程序置顶。
aniugee 2014-10-17
  • 打赏
  • 举报
回复
找个合适的事件判断,如果有窗体覆盖,马上再置顶
CCC的 2014-10-16
  • 打赏
  • 举报
回复
var
  WindowList: Pointer;
  ActiveWindow: HWnd;
begin
  ActiveWindow := GetActiveWindow;
  WindowList := DisableTaskWindows(ActiveWindow);
  {*显示进程对话框*}
  try
    if dlgProgress = nil then
      dlgProgress := TdlgProgress.Create(Application);
    dlgProgress.FormStyle:=fsStayOnTop;
    dlgProgress.Show;   //CSH
    dlgProgress.MessageText.Caption := msg_calculactioning;
    dlgProgress.Update; 
  finally
    EnableTaskWindows(WindowList);
    if ActiveWindow <> 0 then SetActiveWindow(ActiveWindow);
  end;
end;
levonsoft 2014-10-15
  • 打赏
  • 举报
回复
可以置顶于任务管理器之上(任务管理器最大化时,窗体可以置顶于任务管理器之上) 这个还分是否程序是否在激活状态 如果管理器最大化,并且当前焦点在管理器的时候,这时候要求你的窗体还在任务管理器之上(只有disactive 状态) 这种应该应该是比较难做到的。
yct0605 2014-10-15
  • 打赏
  • 举报
回复
大家顶起来啊
yct0605 2014-10-14
  • 打赏
  • 举报
回复
引用 3 楼 aboutyych 的回复:
SetWindowPos,定时检查自己的窗体是否在最顶层,如不是则重新设置。 在你的程序之后再至顶显示的话肯定是要在你的程序上面。
这个是视图图像,如果用定时器的话会影响图像的传输,视频图像会卡的
Blessed_Chuan 2014-10-14
  • 打赏
  • 举报
回复

SetWindowPos(handle,HWND_TOPMOST,Left,Top,Width,Height,SWP_SHOWWINDOW)
form1.FormStyle:=fsStayOnTop
aboutyych 2014-10-14
  • 打赏
  • 举报
回复
SetWindowPos,定时检查自己的窗体是否在最顶层,如不是则重新设置。 在你的程序之后再至顶显示的话肯定是要在你的程序上面。
yct0605 2014-10-14
  • 打赏
  • 举报
回复
人气不旺啊
yct0605 2014-10-14
  • 打赏
  • 举报
回复
SetWindowPos(handle,HWND_TOPMOST,Left,Top,Width,Height,SWP_SHOWWINDOW) form1.FormStyle:=fsStayOnTop 实现的不是很好
具体内容请参考我的BLOG:http://blog.csdn.net/smallwhiteyt/archive/2009/11/08/4784771.aspx 如果你耐心仔细看完本文,相信以后再遇到导出EXCLE操作的时候你会很顺手觉得SO EASY,主要给新手朋友们看的,老鸟可以直接飘过了,花了一晚上的时间写的很辛苦,如果觉得对你有帮助烦请留言支持一下,我会写更多基础的原创内容来回报大家。 C#导出数据到EXCEL表格是个老生常谈的问题了,写这篇文章主要是给和我一样的新手朋友提供两种导出EXCEL的方法并探讨一下导出的效率问题,本文中的代码直接就可用,其中部分代码参考其他的代码并做了修改,抛砖引玉,希望大家一起探讨,如有不对的地方还请大家多多包涵并指出来,我也是个新手,出错也是难免的。 首先先总结下自己知道的导出EXCEL表格的方法,大致有以下几种,有疏漏的请大家补充。 1.数据逐条逐条的写入EXCEL 2.通过OLEDB把EXCEL做为数据源来写 3.通过RANGE范围写入多行多列内存数据到EXCEL 4.利用系统剪贴板写入EXCEL 好了,我想这些方法已经足够完成我们要实现的功能了,方法不在多,在精,不是么?以上4中方法都可以实现导出EXCEL,方法1为最基础的方法,意思就是效率可能不是太高,当遇到数据量过大时所要付出的时间也是巨大的,后面3种方法都是第一种的衍生,在第一种方法效率低下的基础上改进的,这里主要就是一个效率问题了,当然如果你数据量都很小,我想4种方法就代码量和复杂程度来说第1种基本方法就可以了,或当你的硬件非常牛逼了,那再差的方法也可以高效的完成也没有探讨的实际意义了,呵呵说远了,本文主要是在不考虑硬件或同等硬件条件下单从软件角度出发探讨较好的解决方案。

16,748

社区成员

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

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