[英]How to paint standard windows information icon nicely to the index of a pagecontrol's tab
我想將標准窗口信息(和警告和錯誤)圖標繪制到pagecontrol的選項卡的索引。 但是,如果窗口背景顏色不是白色,則結果看起來很糟糕。
program Project111;
uses
Vcl.Forms,
Vcl.Controls,
Vcl.Graphics,
Winapi.Windows,
Vcl.ComCtrls,
Vcl.ImgList;
{$R *.res}
var
mainForm: TForm;
imageList: TImageList;
icon: TIcon;
pageControl: TPageControl;
tabSheet: TTabSheet;
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm, mainForm);
imageList := TImageList.Create(mainForm);
imageList.ColorDepth := cd32bit;
icon := TIcon.Create;
try
icon.Handle := LoadImage( 0, IDI_INFORMATION, IMAGE_ICON, 16, 16, {LR_DEFAULTSIZE or} LR_SHARED );
imageList.AddIcon(icon);
finally
icon.Free;
end;
pageControl := TPageControl.Create(mainForm);
pageControl.Parent := mainForm;
pageControl.Images := imageList;
tabSheet := TTabSheet.Create(mainForm);
tabSheet.Parent := pageControl;
tabSheet.PageControl := pageControl;
tabSheet.ImageIndex := 0;
Application.Run;
end.
正如你可以看到白色邊框模糊,我想這是因為TImageList缺乏正確的alpha透明度,但我不知道如何解決這個問題。
解決方案不必使用TImageList,我很樂意使用任何其他方法。 請注意,還會有字幕,並且並非所有索引都有圖標,並且隨着上下文的更改,圖標可能會更改/添加/刪除。
我正在使用Delphi XE-2,如果有幫助,我也有DevExpress組件。
正如@Sertac所說,你看到的是將windows shell圖標的大小從32x32調整為16x16的效果,從Windows Vista開始,你可以使用SHGetStockIconInfo
函數。 傳遞SHGSI_SMALLICON
標志以檢索SM_CXSMICON
和SM_CYSMICON
指定的圖標的小版本。
SM_CXSMICON
和SM_CYSMICON
的值取決於當前的DPI設置。 對於DPI 96是16x16 。
樣品
LIcon := TIcon.Create;
try
LIcon.Handle := 0;
if TOSVersion.Check(6, 0) then
begin
ZeroMemory(@LSHStockIconInfo, SizeOf(LSHStockIconInfo));
LSHStockIconInfo.cbSize := sizeof(LSHStockIconInfo);
if SHGetStockIconInfo(SIID_INFO, SHGSI_ICON or SHGSI_SMALLICON, LSHStockIconInfo) = S_OK then
begin
LIcon.Handle := LSHStockIconInfo.hIcon;
imageList.AddIcon(LIcon);
end;
end;
finally
LIcon.Free;
end;
你看到的不是因為alpha透明度損壞而是因為調整大小的神器。
如文檔所述 , LoadImage
加載的圖標的默認大小為SM_CXICON
x SM_CYICON
,通常為32x32。 由於您正在請求系統共享的圖標,因此這將是將給出的圖標的大小。
您可以驗證代碼中是否包含這種情況:
..
try
icon.Handle := LoadImage( 0, IDI_INFORMATION, IMAGE_ICON, 16, 16, {LR_DEFAULTSIZE or} LR_SHARED );
Assert(icon.Width = GetSystemMetrics(SM_CXICON));
Assert(GetSystemMetrics(SM_CXICON) <> 16);
..
接下來是圖標調整大小以適應圖像列表可能沒有比使用COLORONCOLOR
模式的StretchBlt
更好。
遺憾的是,無法加載具有非標准大小的系統圖標,因為,如同記錄的那樣,
加載系統圖標或光標時,必須使用LR_SHARED,否則該函數將無法加載資源。
您需要做的是以默認大小加載共享圖標,然后使用更好的算法將其大小調整為16x16。 使用HALFTONE
StretchBlt
可能會更好,但使用更高級的圖形庫可以產生最佳效果。
強烈反對的替代方法是直接從它所在的位置加載資源。 如果您不使用LR_SHARED
標志,您將獲得所需的大小。 您需要進行一些研究才能找到圖標的實際索引,因為這沒有記錄。 並且需要考慮指數或其居住地可能會及時發生變化。 在這種情況下,不要忘記自己銷毀圖標,因為系統不會為非共享資源執行此操作。
icon.Handle := LoadImage(GetModuleHandle(user32), Pointer(104), IMAGE_ICON, 16, 16, 0);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.