问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

求SHAppBarMessage 这个API的用法

发布网友 发布时间:2022-05-06 20:16

我来回答

1个回答

热心网友 时间:2023-10-02 12:37

这个函数很简单,关键是自己处理消息:
这样用:

function TAppBar.SendAppBarMsg(Msg: DWORD): UINT;
begin
Result := SHAppBarMessage(Msg, FABD);//FABD: TAppBarData;
end;

/////下面是消息处理:
procere TAppBar.WndProc(var M: TMessage);
var
State: UINT;
begin
if M.Msg = AppBarMsg then
begin
case M.WParam of
// Sent when always on top or autohide state has changed.
ABN_STATECHANGE:
begin
// Check to see whether the access bar is still ABS_ALWAYSONTOP.
State := SendAppBarMsg(ABM_GETSTATE);
if ABS_ALWAYSONTOP and State = 0 then
SetTopMost(False)
else
SetTopMost(True);
end;
// A full screen application has started, or the last
// full-screen application has closed.
ABN_FULLSCREENAPP:
begin
// Set the access bar's z-order appropriately.
State := SendAppBarMsg(ABM_GETSTATE);
if M.lParam <> 0 then begin
if ABS_ALWAYSONTOP and State = 0 then
SetTopMost(False)
else
SetTopMost(True);
end
else
if State and ABS_ALWAYSONTOP <> 0 then
SetTopMost(True);
end;
// Sent when something happened which may effect the AppBar position.
ABN_POSCHANGED:
begin
// The taskbar or another access bar
// has changed its size or position.
SetAppBarPos(FABD.uEdge);
end;
end;
end
else
inherited WndProc(M);
end;

这里给出本单元完整代码:
unit AppBars;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ShellAPI, StdCtrls, Buttons, ExtCtrls, Menus;

type
TAppBarEdge = (abeTop, abeBottom, abeLeft, abeRight);

EAppBarError = class(Exception);

TAppBar = class(TForm)
PopupMenu1: TPopupMenu;
Top1: TMenuItem;
Bottom1: TMenuItem;
Left1: TMenuItem;
Right1: TMenuItem;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
SpeedButton4: TSpeedButton;
SpeedButton5: TSpeedButton;
OpenDialog1: TOpenDialog;
N1: TMenuItem;
Exit1: TMenuItem;
procere Top1Click(Sender: TObject);
procere SpeedButton1Click(Sender: TObject);
procere MoveButtons;
procere SpeedButton2Click(Sender: TObject);
procere SpeedButton4Click(Sender: TObject);
procere SpeedButton3Click(Sender: TObject);
procere SpeedButton5Click(Sender: TObject);
procere Exit1Click(Sender: TObject);
private
FABD: TAppBarData;
FEdge: TAppBarEdge;
FTopMost: Boolean;
FLastChecked: TMenuItem;
procere WMActivate(var M: TMessage); message WM_ACTIVATE;
procere WMWindowPosChanged(var M: TMessage); message WM_WINDOWPOSCHANGED;
function SendAppBarMsg(Msg: DWORD): UINT;
procere SetAppBarPos(Edge: UINT);
procere SetAppBarEdge(Value: TAppBarEdge);
protected
procere CreateParams(var Params: TCreateParams); override;
procere SetTopMost(TopMost: Boolean);
procere WndProc(var M: TMessage); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Edge: TAppBarEdge read FEdge write SetAppBarEdge;
property TopMost: Boolean read FTopMost write SetTopMost default True;
end;

var
AppBar: TAppBar;

implementation

{$R *.DFM}

uses Main;

const
DEF_APPBAR_WIDTH = 40;
DEF_APPBAR_HEIGHT = 35;

var
AppBarMsg: UINT = 0;

constructor TAppBar.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// set up the TAppBarData record
with FABD do
begin
cbSize := SizeOf(FABD);
hWnd := Handle;
uCallbackMessage := AppBarMsg;
end;
// Inform the shell of the new AppBar
if SendAppBarMsg(ABM_NEW) = 0 then
raise EAppBarError.Create('Failed to create AppBar');
// Initialize the position
SetAppBarPos(ABE_TOP);
FTopMost := True;
FLastChecked := Top1;
end;

destructor TAppBar.Destroy;
begin
// Must inform shell that the AppBar is going away
SendAppBarMsg(ABM_REMOVE);
inherited Destroy;
end;

procere TAppBar.WMWindowPosChanged(var M: TMessage);
begin
inherited;
// Must inform shell that the AppBar position has changed
SendAppBarMsg(ABM_WINDOWPOSCHANGED);
end;

procere TAppBar.WMActivate(var M: TMessage);
begin
inherited;
// Must inform shell that the AppBar window was activated
SendAppBarMsg(ABM_ACTIVATE);
end;

procere TAppBar.WndProc(var M: TMessage);
var
State: UINT;
begin
if M.Msg = AppBarMsg then
begin
case M.WParam of
// Sent when always on top or autohide state has changed.
ABN_STATECHANGE:
begin
// Check to see whether the access bar is still ABS_ALWAYSONTOP.
State := SendAppBarMsg(ABM_GETSTATE);
if ABS_ALWAYSONTOP and State = 0 then
SetTopMost(False)
else
SetTopMost(True);
end;
// A full screen application has started, or the last
// full-screen application has closed.
ABN_FULLSCREENAPP:
begin
// Set the access bar's z-order appropriately.
State := SendAppBarMsg(ABM_GETSTATE);
if M.lParam <> 0 then begin
if ABS_ALWAYSONTOP and State = 0 then
SetTopMost(False)
else
SetTopMost(True);
end
else
if State and ABS_ALWAYSONTOP <> 0 then
SetTopMost(True);
end;
// Sent when something happened which may effect the AppBar position.
ABN_POSCHANGED:
begin
// The taskbar or another access bar
// has changed its size or position.
SetAppBarPos(FABD.uEdge);
end;
end;
end
else
inherited WndProc(M);
end;

function TAppBar.SendAppBarMsg(Msg: DWORD): UINT;
begin
Result := SHAppBarMessage(Msg, FABD);
end;

procere TAppBar.SetAppBarPos(Edge: UINT);
begin
FABD.uEdge := Edge; // set edage
with FABD.rc do
begin
// set coordinates to full-scren
Top := 0;
Left := 0;
Right := Screen.Width;
Bottom := Screen.Height;
// Send ABM_QUERYPOS to obtain proper rect on edge
SendAppBarMsg(ABM_QUERYPOS);
// re-adjust rect based on that modified by ABM_QUERYPOS
case Edge of
ABE_LEFT: Right := Left + DEF_APPBAR_WIDTH;
ABE_RIGHT: Left := Right - DEF_APPBAR_WIDTH;
ABE_TOP: Bottom := Top + DEF_APPBAR_HEIGHT;
ABE_BOTTOM: Top := Bottom - DEF_APPBAR_HEIGHT;
end;
// Set the app bar position.
SendAppBarMsg(ABM_SETPOS);
end;
// Set the BoundsRect property so that it conforms to the
// bounding rectangle passed to the system.
BoundsRect := FABD.rc;
end;

procere TAppBar.SetTopMost(TopMost: Boolean);
const
WndPosArray: array[Boolean] of HWND = (HWND_BOTTOM, HWND_TOPMOST);
begin
SetWindowPos(Handle, WndPosArray[TopMost], 0, 0, 0, 0, SWP_NOMOVE or
SWP_NOSIZE or SWP_NOACTIVATE);
end;

procere TAppBar.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
Params.Style := WS_VISIBLE or WS_POPUP or WS_THICKFRAME or WS_CLIPCHILDREN;
end;

procere TAppBar.SetAppBarEdge(Value: TAppBarEdge);
const
EdgeArray: array[TAppBarEdge] of UINT = (ABE_TOP, ABE_BOTTOM, ABE_LEFT,
ABE_RIGHT);
begin
if Value <> FEdge then
begin
SetAppBarPos(EdgeArray[Value]);
FEdge := Value;
MoveButtons;
end;
end;

procere TAppBar.Top1Click(Sender: TObject);
begin
FLastChecked.Checked := False;
(Sender as TMenuItem).Checked := True;
case TMenuItem(Sender).Caption[2] of
'T': Edge := abeTop;
'B': Edge := abeBottom;
'L': Edge := abeLeft;
'R': Edge := abeRight;
end;
FLastChecked := TMenuItem(Sender);
end;

procere TAppBar.MoveButtons;
// This method looks complicated, but it really just arranges the buttons
// properly depending on what side the AppBar is docked.
var
DeltaCenter, NewPos: Integer;
begin
if (FEdge = abeTop) or (FEdge = abeBottom) then
begin
DeltaCenter := (ClientHeight - SpeedButton1.Height) div 2;
SpeedButton1.SetBounds(10, DeltaCenter, SpeedButton1.Width, SpeedButton1.Height);
NewPos := SpeedButton1.Width + 20;
SpeedButton2.SetBounds(NewPos, DeltaCenter, SpeedButton1.Width, SpeedButton1.Height);
NewPos := NewPos + SpeedButton1.Width + 10;
SpeedButton3.SetBounds(NewPos, DeltaCenter, SpeedButton1.Width, SpeedButton1.Height);
NewPos := NewPos + SpeedButton1.Width + 10;
SpeedButton4.SetBounds(NewPos, DeltaCenter, SpeedButton1.Width, SpeedButton1.Height);
NewPos := NewPos + SpeedButton1.Width + 10;
SpeedButton5.SetBounds(NewPos, DeltaCenter, SpeedButton1.Width, SpeedButton1.Height);
end;
if (FEdge = abeLeft) or (FEdge = abeRight) then
begin
DeltaCenter := (ClientWidth - SpeedButton1.Width) div 2;
SpeedButton1.SetBounds(DeltaCenter, 10, SpeedButton1.Width, SpeedButton1.Height);
NewPos := SpeedButton1.Height + 20;
SpeedButton2.SetBounds(DeltaCenter, NewPos, SpeedButton1.Width, SpeedButton1.Height);
NewPos := NewPos + SpeedButton1.Height + 10;
SpeedButton3.SetBounds(DeltaCenter, NewPos, SpeedButton1.Width, SpeedButton1.Height);
NewPos := NewPos + SpeedButton1.Height + 10;
SpeedButton4.SetBounds(DeltaCenter, NewPos, SpeedButton1.Width, SpeedButton1.Height);
NewPos := NewPos + SpeedButton1.Height + 10;
SpeedButton5.SetBounds(DeltaCenter, NewPos, SpeedButton1.Width, SpeedButton1.Height);
end;
end;

procere TAppBar.SpeedButton1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
MainForm.FileName := OpenDialog1.FileName;
end;

procere TAppBar.SpeedButton2Click(Sender: TObject);
begin
MainForm.memEditor.Lines.SaveToFile(MainForm.FileName);
end;

procere TAppBar.SpeedButton3Click(Sender: TObject);
begin
MainForm.memEditor.CutToClipboard;
end;

procere TAppBar.SpeedButton4Click(Sender: TObject);
begin
MainForm.memEditor.CopyToClipboard;
end;

procere TAppBar.SpeedButton5Click(Sender: TObject);
begin
MainForm.memEditor.PasteFromClipboard;
end;

procere TAppBar.Exit1Click(Sender: TObject);
begin
Application.Terminate;
end;

initialization
AppBarMsg := RegisterWindowMessage('DDG AppBar Message');
end.
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
艾芙洛洗发水为什么不在商场销售商 艾芙洛洗发水是英国的吗 毕业生刚刚签了三方协议,想毁,怎么办 适合夫妻干的生意有哪些 新生蜜蜂多久出巢试飞 新生蜜蜂什么时候进行首次试飞? 蜜蜂几月几日出生外貌和颜色? 当脚模一定要脚趾修长吗 脚长成这样,能当脚膜吗 固话遇忙记存呼叫业务有什么特点? 什么是固话遇忙记存呼叫业务? 按键精灵 setappspeed 能加速普通app吗 百度输入法皮肤安装不了安装失败怎么办 按键精灵脚本如何加速? 坚果g3 pro 怎么拆机清灰 六爻 看看以后丈夫的特征与能力。高手帮帮忙解卦 六爻三合局怎么解释?合局的时候应该看哪三爻? 六爻 看我何时能离开这里? 六爻看感情 懂六爻的大师请进:本人在2014年6月16号.用三个铜钱摇了-卦.-爻得-个背.二爻得二个背.三爻 帮忙解六爻,谢! 六爻问健康。 请教六爻中本卦与变卦的问题 算命的是不是骗人 六爻为什么算的那么准 六爻用神太弱和太强的断挂方法 请懂得六爻算卦的帮我解个挂,我是在街上算卦的帮我算的,可是他说话太过模棱两可,的不清,感觉被骗了, 中国移动发福利!新款5G套餐价格优惠流量多,网友:给我开十年 六爻八卦上,说一个人,太过浪荡不检点,是什么……是临青龙,还是青龙临官鬼 六爻之中物极必反,过旺反断,怎么样才算过旺 六爻的太过卦适用范围是什么? 10年的Q5车险一年最低多少钱 想报名自考不知道什么时候可以报名是不是直接去教育局报名就可以啊有没有时间*啊有没有要带的东西我是 参加自考怎么报名想上的学校? 谁知道八叶草的用途啊? 八叶轮生的是什么植物 这是什么植物?公园里的,开花吗? 什么是乳腺导管上皮轻-中度普通型增生,部分导管扩张?是否严重? 乳腺及导管增生 乳腺导管上皮增生怎么办啊? 小伙伴们能告诉我工程造价的培训费大概要多少吗? 乳腺导管扩张伴上皮组织增生活跃 新盛电锤 z1c-xs-26D怎么加润滑油 土建施工技能培训班费用是多少? 什么叫乳腺增生?说一下 双侧乳腺增生样改变,双侧乳腺导管局部增宽,这个严重吗 乳腺增生五年左右,现在乳腺导管扩张,我该怎么办! 乳腺增生,导管增粗 乳腺增生会导致乳腺导管局部扩张吗 乳腺腺病伴局灶性导管增生是怎么回事? 给老师送花送什么花合适 送老师什么礼物最特别 乳腺增生,还有导管扩张