如何为 `TBitBtn` 设置 `ElevationRequired`
How to set `ElevationRequired` for `TBitBtn`
我需要标记一个 TBitBtn
(不是 TButton
),按钮操作需要提升。我将 ElevationRequired
设置为 True,但我没有看到盾牌图标。
要复制,请在表格上放置 TButton
和 TBitBtn
:
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.ElevationRequired := True;
BitBtn1.ElevationRequired := True;
end;
Button1
显示盾牌图标,BitBtn1
不显示。
这是不可能的。
一个 VCL TBitBtn
is an owner-drawn Win32 BUTTON 控件。你可以在这里看到:
procedure TBitBtn.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do Style := Style or BS_OWNERDRAW;
end;
因此,TBitBtn
不是 由 Windows 绘制,而是由 Vcl.Buttons.pas
中的 Pascal 代码手动绘制。具体来说,TBitBtn.DrawItem(const DrawItemStruct: TDrawItemStruct)
作画。
而这里你可以看到没有提到ElevationRequired
。
因此,TBitBtn
不支持这个。
一般情况下,不要使用TBitBtn
;使用 TButton
获取本机 Win32 按钮。
因为 ElevationRequired
没有为 TBitBtn
实现(参见 )。我最终通过此过程 (Vista+) 绘制了盾牌图标:
procedure MarkElevationRequired(ABitBtn: TBitBtn);
var
Icon: TIcon;
begin
Assert(Assigned(ABitBtn));
//---
try
Icon := TIcon.Create;
try
Icon.Handle := GetSystemIcon(SIID_SHIELD, TSystemIconSize.Small); //see WinApi.ShellApi
ABitBtn.Glyph.Assign(Icon);
finally
Icon.Free;
end;
except
//CreateSystemIcon throws an exception for <WinVista
end;
end;
和
/// Get system icon for SIID, see https://docs.microsoft.com/de-de/windows/win32/api/shellapi/ne-shellapi-shstockiconid
/// Works for Win Vista or better
/// see https://community.idera.com/developer-tools/b/blog/posts/using-windows-stock-icons-in-delphi
function GetSystemIcon(Id: integer; Size: TSystemIconSize = TSystemIconSize.Large;
Overlay: Boolean = False; Selected: Boolean = False): HICON;
var
Flags: Cardinal;
SSII: TSHStockIconInfo;
ResCode: HResult;
begin
if not TOSVersion.Check(6, 0) then
raise Exception.Create('SHGetStockIconInfo is only available in Win Vista or better.');
case Size of
TSystemIconSize.Large: Flags := SHGSI_ICON or SHGSI_LARGEICON;
TSystemIconSize.Small: Flags := SHGSI_ICON or SHGSI_SMALLICON;
TSystemIconSize.ShellSize: Flags := SHGSI_ICON or SHGSI_SHELLICONSIZE;
end;
if Selected then
Flags := Flags OR SHGSI_SELECTED;
if Overlay then
Flags := Flags OR SHGSI_LINKOVERLAY;
SSII.cbSize := SizeOf(SSII);
ResCode := SHGetStockIconInfo(Id, Flags, SSII);
if ResCode <> S_OK then
begin
if ResCode = E_INVALIDARG then
raise Exception.Create(
'The stock icon identifier [' + IntToStr(id) + '] is invalid')
else
raise Exception.Create(
'Error calling GetSystemIcon: ' + IntToStr(ResCode));
end
else
Result := SSII.hIcon;
end;
我需要标记一个 TBitBtn
(不是 TButton
),按钮操作需要提升。我将 ElevationRequired
设置为 True,但我没有看到盾牌图标。
要复制,请在表格上放置 TButton
和 TBitBtn
:
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.ElevationRequired := True;
BitBtn1.ElevationRequired := True;
end;
Button1
显示盾牌图标,BitBtn1
不显示。
这是不可能的。
一个 VCL TBitBtn
is an owner-drawn Win32 BUTTON 控件。你可以在这里看到:
procedure TBitBtn.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do Style := Style or BS_OWNERDRAW;
end;
因此,TBitBtn
不是 由 Windows 绘制,而是由 Vcl.Buttons.pas
中的 Pascal 代码手动绘制。具体来说,TBitBtn.DrawItem(const DrawItemStruct: TDrawItemStruct)
作画。
而这里你可以看到没有提到ElevationRequired
。
因此,TBitBtn
不支持这个。
一般情况下,不要使用TBitBtn
;使用 TButton
获取本机 Win32 按钮。
因为 ElevationRequired
没有为 TBitBtn
实现(参见
procedure MarkElevationRequired(ABitBtn: TBitBtn);
var
Icon: TIcon;
begin
Assert(Assigned(ABitBtn));
//---
try
Icon := TIcon.Create;
try
Icon.Handle := GetSystemIcon(SIID_SHIELD, TSystemIconSize.Small); //see WinApi.ShellApi
ABitBtn.Glyph.Assign(Icon);
finally
Icon.Free;
end;
except
//CreateSystemIcon throws an exception for <WinVista
end;
end;
和
/// Get system icon for SIID, see https://docs.microsoft.com/de-de/windows/win32/api/shellapi/ne-shellapi-shstockiconid
/// Works for Win Vista or better
/// see https://community.idera.com/developer-tools/b/blog/posts/using-windows-stock-icons-in-delphi
function GetSystemIcon(Id: integer; Size: TSystemIconSize = TSystemIconSize.Large;
Overlay: Boolean = False; Selected: Boolean = False): HICON;
var
Flags: Cardinal;
SSII: TSHStockIconInfo;
ResCode: HResult;
begin
if not TOSVersion.Check(6, 0) then
raise Exception.Create('SHGetStockIconInfo is only available in Win Vista or better.');
case Size of
TSystemIconSize.Large: Flags := SHGSI_ICON or SHGSI_LARGEICON;
TSystemIconSize.Small: Flags := SHGSI_ICON or SHGSI_SMALLICON;
TSystemIconSize.ShellSize: Flags := SHGSI_ICON or SHGSI_SHELLICONSIZE;
end;
if Selected then
Flags := Flags OR SHGSI_SELECTED;
if Overlay then
Flags := Flags OR SHGSI_LINKOVERLAY;
SSII.cbSize := SizeOf(SSII);
ResCode := SHGetStockIconInfo(Id, Flags, SSII);
if ResCode <> S_OK then
begin
if ResCode = E_INVALIDARG then
raise Exception.Create(
'The stock icon identifier [' + IntToStr(id) + '] is invalid')
else
raise Exception.Create(
'Error calling GetSystemIcon: ' + IntToStr(ResCode));
end
else
Result := SSII.hIcon;
end;