2017-11-27 10 views
5

標準のウィンドウ情報(警告とエラー)アイコンをpagecontrolのタブのインデックスに塗りたいと思います。しかし、ウィンドウの背景色が白でない場合、結果は悪く見えます。ここで標準ウィンドウの情報アイコンを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. 

はスクリーンショットです: enter image description here

あなたは白の境界線があいまいで見ることができるように、私はそれが理由TImageListのことで、適切なアルファ透明性の欠如であると思いますが、私は修正する方法がわかりませんこの。

解決策はTImageListを使用する必要はありません。他の方法を使用してもうれしいです。キャプションもあり、すべてのインデックスにアイコンが付いているわけではなく、アイコンがコンテキストの変更に応じて変更/追加/削除される可能性があることに注意してください。

私はDelphi XE-2を使用しています。DevExpressコンポーネントもあります。

+0

が、これは非常に広範囲に及ぶことを期待しています。画像そのものがどのように作成されたかという性質は、それらが明るい背景で使用されることを前提としています。問題は実際の画像にあります。それほど多くのコードではこれを解決できません。この修正は、暗い背景で使用するために最適化された画像を提供することです。あるいは、私たちはソフトウェアのすべてのボタンとアイコンをこの正確な理由のベクタフォントに更新するのに半年を費やしました。今、私たちはどんな背景でも私たちが望むものを色付けできます。 –

答えて

6

@SertacはあなたがSHGetStockIconInfo機能を使用することができるのWindows Vistaで始まる回避策として、32×32から16×16にWindowsシェルのアイコンのサイズを変更する効果で見るもの言うように。 SM_CXSMICONSM_CYSMICONで指定されているように、SHGSI_SMALLICONフラグを渡してアイコンの小さなバージョンを取得します。

SM_CXSMICONSM_CYSMICONの値は、現在のDPI設定に依存します。 DPI96については、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; 
3

アルファ透明度の問題ではなく、サイズ変更のアーティファクトが原因です。

documentedとして、アイコン​​のデフォルトサイズは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または を使用しなければならないを文書化し、残念ながら非標準的なサイズのシステムアイコンをロードすることはできません関数はリソースをロードできません。あなたがする必要がどのような


デフォルトのサイズと共有アイコンをロードして、より良いアルゴリズムを使用して自分自身を16×16してサイズを変更することです。 StretchBltHALFTONEとすると、おそらくより優れていますが、より高度なグラフィックスライブラリを使用すると最良の結果が得られます。

リソースを置く場所から直接リソースを読み込むことを強くお勧めします。 LR_SHAREDフラグを使用しないと、要求されたサイズが与えられます。これは文書化されていないので、あなたはアイコンの実際のインデックスを見つけるためにいくつかの研究を行う必要があります。また、インデックスやその場所が時間の経過とともに変化する可能性があることを考慮する必要があります。この場合、システムは共有されていないリソースのためにそれをしないので、あなた自身がアイコンを破壊することを忘れないでください。

icon.Handle := LoadImage(GetModuleHandle(user32), Pointer(104), IMAGE_ICON, 16, 16, 0); 
関連する問題