003-如何将窗体置入任务栏

问题来源

最近在写一个播放器,想到以前其他平台的播放器,在隐藏主界面后,如最小化为MiniBox或隐藏到托盘后,切换歌曲操作很麻烦,快捷键经常被这个那个软件占有,不方便,而且MiniBox又在我本就不大的屏幕上晃来晃去,碍眼,于是有了这样的想法。

经过搜索一番,发现实现起来很简单,于是写了一些代码,实现了这个功能,以下为效果图:
在这里插入图片描述

任务栏分析

本次要操作的,是将包含了一些控件的窗体置入任务栏,实际上,任务栏分了很多区域,包括时钟区,窗口最小化的区,托盘区等等,这次计划置入的是窗口切换区。

任务栏最外层的壳A,壳A包含了以上说的区域。
在这里插入图片描述
其下再有窗口切换区的壳B
在这里插入图片描述
壳B下再有一个区为窗口最小化存放的位置C,就像俄罗斯套娃一样,分为一层又一层
在这里插入图片描述
我们的窗口F,就要放在和C平级的位置,也就是说,窗口是放在B上面的,B是窗口F的承载容器。
这里注意,B和C在我的截图里看起来差不多,其实不一样,因为B是C的容器,而此时只有C一个子类,因此看起来差不多,但是我们可以把C的大小进行调整,留出一些位置给我们的窗口F。

这样我们得到的结构就可以如下图一样:
在这里插入图片描述
首先获取A,B,C三个层的句柄,记为:MainH, FirH, SecH,类型为THandle。
然后获取A,B,C三个层的区域,记为:MainR, FirR, SecR,类型为TRect。
然后使用MoveWindow函数,调整层次C的宽度,预留一部分位置放置窗口F。
然后将窗体置入,并调整位置。
最后,在程序退出时候,将C层宽度调整回来,恢复正常状态。

代码如下

unit Unit1;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  MainH, FirH, SecH: THandle;
  MainR, FirR, SecR: TRect;
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  MainH := FindWindow(PChar('Shell_TrayWnd'), nil); //Shell_TaryWnd句柄,A层
  FirH := FindWindowEX(MainH, 0, 'ReBarWindow32', nil); //ReBarWindow32句柄,B层
  SecH := FindWindowEX(FirH, 0, 'MSTaskSwWClass', nil); //MSTaskSwWClass最小化窗口层句柄,C层
  GetWindowRect(MainH, MainR);
  GetWindowRect(FirH, FirR);
  GetWindowRect(SecH, SecR);
  MoveWindow(SecH, 0, 0, SecR.Right - SecR.Left - Self.Width, SecR.Bottom - SecR.Top, True); //预留放置窗口的位置
  Self.ParentWindow := FirH;
  MoveWindow(Self.Handle, SecR.Right - SecR.Left - Self.Width + 1, (FirR.Bottom - FirR.Top - Self.Height) div 2, Self.Width, Self.Height, True);
  Self.Visible := True;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  MoveWindow(SecH, 0, 0, SecR.Right - SecR.Left, SecR.Bottom - SecR.Top, True);
  Application.Terminate;
end;
 
end.

设计期界面如下

在这里插入图片描述

运行效果如下

在这里插入图片描述
为了让程序透明化显示,用了窗体的穿透属性,窗体配置如下:

object Form1: TForm1
  Left = 0
  Top = 0
  BorderStyle = bsNone
  Caption = 'Form1'
  ClientHeight = 30
  ClientWidth = 100
  Color = clFuchsia
  TransparentColor = True
  TransparentColorValue = clFuchsia
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 4
    Top = 5
    Width = 40
    Height = 20
    Caption = 'DO'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 56
    Top = 5
    Width = 40
    Height = 20
    Caption = 'Close'
    TabOrder = 1
    OnClick = Button2Click
  end
end

以上便是Delphi中对于置入窗体到任务栏的基本方法,希望对后来者有用

【参考文章】
https://blog.csdn.net/Factor_/article/details/84799332
https://www.cnblogs.com/luoshupeng/archive/2011/08/23/2151081.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值