windows – 如何停止在任务栏上显示我的应用程序?
我的应用程序可以让用户只在系统托盘中运行它,而不是在任务栏中运行它.当我的应用程序由Delphi 6构建时,这很好用.切换到Delphi XE2后,它不再起作用.
我已经搞砸了一些,我有这个适用于Windows 7,但在Windows XP上运行时我仍然有问题.应用程序正确隐藏在任务栏中,并显示在系统托盘中.但是当我创建并显示任何其他表单时,该图标将显示在Windows XP中. procedure TfrmAppointment.HideWindowFromTaskbar; var TaskbarList: ITaskbarList; begin Application.MainFormOnTaskBar := False; // Windows 7 seems to behave differently. This seems to fix it. if (CheckWin32Version(6,1)) then begin // We are in Win7,and we requested the tray. TaskbarList := CreateComObject(CLSID_TaskbarList) as ITaskbarList; TaskbarList.HrInit; TaskbarList.DeleteTab(Application.Handle); end else begin // Previous code from D6 days ShowWindow(Application.Handle,SW_HIDE); SetWindowLong(Application.Handle,GWL_EXSTYLE,GetWindowLong(Application.Handle,GWL_EXSTYLE) or WS_EX_TOOLWINDOW); ShowWindow(Application.Handle,SW_SHOWNOACTIVATE); end; end; 如果用户选择在系统托盘中显示应用程序的选项,则运行该代码.它适用于我测试过的所有Windows版本.但是,在Windows XP上,当我显示任何子窗体时,应用程序会立即显示在任务栏中.在Windows 7中一切都很好. 我缺少什么想法? 我应该补充一点,我知道这可能是与Hide the Main Form in a Delphi 2009 Application相同的问题,但是我已经设置了MainFormOnTaskBar,所以答案似乎不适用. [编辑:]更具体地说,我在这里添加其他信息.此应用程序有两种模式:在任务栏中显示,并在系统托盘中显示. 第一种模式与任何普通应用程序相同.该应用程序仅存在于任务栏中.它最小化到任务栏.它从任务栏恢复. 第二种模式的行为完全相同,但任务栏图标仅存在于系统托盘中.因此,当用户最小化应用程序时,我拦截该消息,抓取TRect为’Shell_TrayWnd’/’TrayNotifyWnd’,并调用DrawAnimatedRects()来模拟托盘的最小化.然后我隐藏了主表格.在来自系统托盘的消息中,我反向绘制相同的动画,并使其再次可见.表单可见时,它不会显示在任务栏中. 这一切都适用于所有Windows版本. 我遇到的具体问题是,当显示任何其他表单时,Windows XP正在任务栏中创建应用程序图标. Windows 7不会这样做.因此,如果Windows XP用户仅使用应用程序主表单,则不会出现任何问题,并且两种查看模式都可以正常工作.如果他们打开另一个窗口,则会出现应用程序图标,即使在该窗口关闭后也会停留在那里. Windows 7不会这样做,图标仍然消失. 解决方法
你应该设置
Application.MainFormOnTaskBar := True; 在.dpr文件中,然后永远不会修改该设置. 然后,当您想从任务栏中删除主窗体时,您只需编写 MainForm.Hide; 当你需要将主表格从隐藏处再次写入时 MainForm.Show; 就是这样. 当然,您需要显示和隐藏您的通知区域图标,以隐藏和显示主窗体. HideWindowFromTaskbar中的代码不是必需的,您应该删除它.当应用程序在MainFormOnTaskBar中等于True模式时,主窗体是一个非拥有的顶级窗口.因此,只要它可见,它就会出现在任务栏上.因此,您可以从任务栏中删除主窗体,只需将其隐藏即可. 您的应用程序中的其他表单将属于顶级窗口.通常,它们将由您的主表单拥有.由于是所有者,它们不会出现在任务栏上. 总的来说,你应该尽量避免摆弄窗口样式.您通常可以使应用程序以您需要的方式运行而不执行此操作.更重要的是,如果您必须调整窗口样式,则必须在CreateParams中执行此操作.这样,窗口样式将在窗口重新创建时保持不变.但我重新迭代,避免在可能的地方修改窗口样式. 密钥MSDN参考是: > Window Features. 这是我能制作的最小程序,证明了这一点: program MainFormHiding; uses Forms,StdCtrls; var MainForm,OtherForm: TForm; Button: TButton; type TEventHandlerClass = class class procedure ToggleMainFormVisible(Sender: TObject); end; class procedure TEventHandlerClass.ToggleMainFormVisible(Sender: TObject); begin MainForm.Visible := not MainForm.Visible; end; begin Application.MainFormOnTaskbar := True; Application.CreateForm(TForm,MainForm); OtherForm := TForm.Create(Application); MainForm.Caption := 'Main Form'; OtherForm.Visible := True; OtherForm.Caption := 'Other Form'; Button := TButton.Create(OtherForm); Button.Caption := 'Toggle'; Button.Parent := OtherForm; Button.OnClick := TEventHandlerClass.ToggleMainFormVisible; Application.Run; end. 在评论中,您清楚地表明您希望能够隐藏任务栏窗口而不隐藏主窗体.在这种情况下,我建议您将MainFormOnTaskbar设置为False.这意味着Application.Handle将成为与任务栏按钮关联的窗口.然后,您可以隐藏该窗口以将其从任务栏中删除. 您现在需要为任何辅助表单显式设置PopupParent.如果您希望这些窗口归主窗体所有,则可以进行设置. 这是我为此场景调整的示例: program MainFormHiding; uses Forms,StdCtrls,Windows; var MainForm,OtherForm: TForm; Button: TButton; type TEventHandlerClass = class class procedure ToggleTaskbarButton(Sender: TObject); end; class procedure TEventHandlerClass.ToggleTaskbarButton(Sender: TObject); begin if IsWindowVisible(Application.Handle) then ShowWindow(Application.Handle,SW_HIDE) else ShowWindow(Application.Handle,SW_SHOW); end; begin Application.MainFormOnTaskbar := False; Application.CreateForm(TForm,MainForm); OtherForm := TForm.Create(Application); OtherForm.PopupParent := MainForm; MainForm.Caption := 'Main Form'; Application.Title := MainForm.Caption; OtherForm.Visible := True; OtherForm.Caption := 'Other Form'; Button := TButton.Create(OtherForm); Button.Caption := 'Toggle'; Button.Parent := OtherForm; Button.OnClick := TEventHandlerClass.ToggleTaskbarButton; Application.Run; end. 运行此程序并单击切换按钮.现在您将看到主要表单和其他表单.任务栏中没有任何内容.我包含了切换按钮,表示您可以在程序运行时在两种操作模式之间切换.无需重启. 这里的关键是使可见窗体以外的窗口成为与任务栏关联的窗口.完成后,您可以通过显示和隐藏该窗口再次控制任务栏的存在.在这种情况下,该窗口是应用程序窗口Application.Handle.因为这是任务栏上的窗口,您需要设置其Title属性来控制其文本. 最后,我再次强调,与任务栏的交互最好用窗口所有者和可见性来控制.始终使用这些方法而不是ITaskbarList,扩展窗口样式等搜索解决方案. 更新 希望关于这个主题的最后一句话.正如您所注意到的,当主窗体最小化时,上面的代码行为很差.当发生这种情况时,应用程序窗口再次可见,因此再次出现在任务栏中. 在抑制这种行为方面我不太确定自己.由于TApplication.Minimize中的代码显示了主窗体最小化时的应用程序句柄,因此出现了这种行为.我拥有的最佳解决方案是将主窗体最小化转换为隐藏. procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND; .... procedure TMainForm.WMSysCommand(var Msg: TWMSysCommand); begin if (Msg.CmdType and $FFF0)=SC_MINIMIZE then begin Hide; exit; end; inherited; end; 或者另一种方法是通过TApplication的OnMinimize事件处理程序来抑制应用程序窗口显示. class procedure TEventHandlerClass.ApplicationMinimize(Sender: TObject); begin ShowWindow(Application.Handle,SW_HIDE); end; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows – 如何在嵌入串行密钥的情况下安装Office 2010?
- virtualbox – 无法安装DHCP服务器,磁盘空间不足
- 在Windows 7上启用MySQL 5查询日志
- windows – 从C#调用MsiEnumRelatedProducts正在崩溃
- 如何在Windows XP / 7上的Python 3中将文件打印到纸上?
- windows-server-2003 – DNS服务器解析服务器名称但不是完全
- windows – LoadLibrary引用计数
- 如何在Windows DNS服务器上注册Linux服务器
- winapi – 使用Windows SetTimer()函数
- winapi – 使用Windows API调用打开CD / DVD门?