【发布时间】:2011-06-29 10:28:12
【问题描述】:
我需要获取任务栏的宽度和高度。我还需要任务栏的位置。我怎样才能得到这个?
【问题讨论】:
标签: delphi
我需要获取任务栏的宽度和高度。我还需要任务栏的位置。我怎样才能得到这个?
【问题讨论】:
标签: delphi
根据您需要该信息的目的,您可能需要查看Forms.TScreen.WorkAreaRect,因为以这种方式标识的工作区不仅减去任务栏,还减去任何其他“栏”这可能会限制可用的桌面空间。
您可以在代码中简单地使用Screen.WorkAreaRect,因为Screen: TScreen 变量在Forms 单元中声明并由VCL 初始化。
【讨论】:
好吧,由于这个问题是关于如何获取任务栏坐标的,所以我决定发布另一个版本,说明如何通过使用 SHAppBarMessage 函数和 ABM_GETTASKBARPOS 消息参数来实现这一点。
我发布了两个版本;一个有一个没有给定的任务栏句柄。请注意,如果您发送ABM_GETTASKBARPOS 消息,您应该在APPBARDATA 结构中指定hWnd 成员,正如ABM_GETTASKBARPOS 描述中提到的那样。所以第一个版本对于这种情况是安全的。第二个虽然有效,但形式上是错误的。
uses ShellAPI;
procedure TForm1.Button1Click(Sender: TObject);
var
Data: TAppBarData;
begin
Data.hWnd := FindWindow('Shell_TrayWnd', nil);
Data.cbSize := SizeOf(TAppBarData);
if Data.hWnd <> 0 then
if SHAppBarMessage(ABM_GETTASKBARPOS, Data) = 1 then
ShowMessage(
'Left: ' + IntToStr(Data.rc.Left) + 'px ; ' +
'Top: ' + IntToStr(Data.rc.Top) + 'px ; ' +
'Width: ' + IntToStr(Data.rc.Right - Data.rc.Left) + 'px ; ' +
'Height: ' + IntToStr(Data.rc.Bottom - Data.rc.Top) + 'px'
);
end;
请注意,此版本(未指定 TAppBarData.hWnd 成员)虽然有效,但根据 MSDN 是错误的。
procedure TForm1.Button2Click(Sender: TObject);
var
Data: TAppBarData;
begin
Data.cbSize := SizeOf(TAppBarData);
if SHAppBarMessage(ABM_GETTASKBARPOS, Data) = 1 then
ShowMessage(
'Left: ' + IntToStr(Data.rc.Left) + 'px ; ' +
'Top: ' + IntToStr(Data.rc.Top) + 'px ; ' +
'Width: ' + IntToStr(Data.rc.Right - Data.rc.Left) + 'px ; ' +
'Height: ' + IntToStr(Data.rc.Bottom - Data.rc.Top) + 'px'
);
end;
【讨论】:
这就是我所拥有的(在 Win95 十年制造的 ;-) 并且仍在工作):
代码如下:
const
W95_EXPLORERCLASSNAME = 'Shell_TrayWnd';
function GetTaskBarBounds : TRect;
begin
GetWindowRect( FindWindow( W95_EXPLORERCLASSNAME, '' ), Result );
end;
function GetTaskBarSize : TPoint;
var
TaskBarBounds : TRect;
begin
TaskBarBounds:=GetTaskBarBounds;
with( TaskBarBounds ) do
Result:=Point( Right - abs( Left ), Bottom - abs( Top ) );
end;
function GetTaskBarAlignment : TAlign;
var
TaskBarBounds : TRect;
begin
Result:=alNone;
if( FindWindow( W95_EXPLORERCLASSNAME, '' ) > 0 ) then
begin
TaskBarBounds:=GetTaskBarBounds;
with( TaskBarBounds ) do
// At Left or at top of screen ?
if( Left <= 0 ) and ( Top <= 0 ) then
begin
if( Bottom >= 480 ) then
Result:=alLeft
else Result:=alTop;
end
else begin
if( Left <= 0 ) then
Result:=alBottom
else Result:=alRight;
end;
end;
end;
【讨论】:
这是获取方向的方法
type
TTaskBarPos = (_TOP, _BOTTOM, _LEFT, _RIGHT, _NONE);
function GetTaskBarPos: TTaskBarPos;
var
hTaskbar: HWND;
T: TRect;
scrW, scrH: integer;
begin
hTaskBar := FindWindow('Shell_TrayWnd', nil);
if hTaskbar <> 0 then
begin
GetWindowRect(hTaskBar, T);
ScrW := Screen.Width;
ScrH := Screen.Height;
if (T.Top > scrH div 2) and (T.Right >= scrW) then
Result := _BOTTOM
else if (T.Top < scrH div 2) and (T.Bottom <= scrW div 2) then
Result := _TOP
else if (T.Left < scrW div 2) and (T.Top <= 0) then
Result := _LEFT
else
if T.Left >= ScrW div 2 then
Result := _RIGHT;
end;
end;
procedure TForm1.Button5Click(Sender: TObject);
var
TaskBarPos: TTaskBarPos;
begin
TaskBarPos := GetTaskBarPos;
case TaskBarPos of
_LEFT: ShowMessage('Left Position');
_TOP: ShowMessage('Top Position');
_RIGHT: ShowMessage('Right Position');
_BOTTOM: ShowMessage('Bottom Position');
end;
end;
【讨论】:
hacky,因为它依赖于FindWindow。如果用户使用非标准任务栏,这将失败,如果有多个“栏”,则会失败,而且我不确定在具有多个监视器的系统上会发生什么。
我从http://www.delphitips.net/2007/08/26/taskbar-position 得到了这个代码,我试过了,效果很好。即使任务栏的大小发生变化,它也能正常工作。
代码放在下面。
procedure TForm1.Button1Click(Sender: TObject);
var
hTaskbar: HWND;
T: TRect;
ScrW, ScrH: Integer;
begin
ScrW := Screen.Width;
ScrH := Screen.Height;
hTaskBar := FindWindow('Shell_TrayWnd', nil);
GetWindowRect(hTaskBar, T);
if (T.Top > ScrH div 2) and (T.Right >= ScrW) then
ShowMessage('Bottom of the screen')
else if (T.Top < ScrH div 2) and (T.Bottom <= ScrW div 2) then
ShowMessage('Top of the screen')
else if (T.left < ScrW div 2) and (T.Top <= 0) then
ShowMessage('Left side of the screen')
else
ShowMessage('Right side of the screen');
end;
【讨论】: