簡體   English   中英

如何將標准窗口信息圖標很好地繪制到pagecontrol選項卡的索引

[英]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_CXSMICONSM_CYSMICON指定的圖標的小版本。

SM_CXSMICONSM_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM