Delphi Programming / Object Pascal      
                [掲載 2008年08月30日] [更新 2019年08月27日] Delphi サンプルプログラム集  
             
           
        
        
        
          
            
              910_Glyph 用ビットマップの作成  
             
            
               動作確認等  
              Windows 7 U64(SP1) + Delphi XE(UP1) Pro  
             
           
        
        
          
            
               
               910_DisableBitmap.zip [3,413 KB] 2019年08月27日版 (EXE 同梱)  
             
           
        
         
         
        
         
        
          
            
              
                
                  2014年06月30日 
                  ビットマップの減色とグレイスケール化の記事を,新規にページを作成して移動 
                 
                
                  2018年01月24日 (これより前の履歴は省略) 
                  コンポーネントのアイコン作成支援プログラムに Glyph 用ビットマップ作成の機能を追加したので,関係記事とサンプルの掲載を中止 
                  
             
           
        
         
         
         
         
        
          
            
              Glyph 用ビットマップと Disable 用のグレイスケールビットマップ 
             
           
        
         
         
        
          
            
               
                本ページで扱っている Glyph (グリフ) は,TSpeedButton, TBitBtn 等の Glyph プロパティのことです.この Glyph プロパティは TBitmap 型です.
              
                
                   Glyph のビットマップは,正方のビットマップを複数格納する形式になっていて,最大 4 つまで格納できます.Glyph にビットマップを設定すると TSpeedButton, TBitBtn 等に画像を表示できます.2 番目の画像があると,それらのコントロールの Enabled プロパティを False にした時の画像となります.2 番目のビットマップ画像が存在しない場合は Enabled プロパティの値を False にしても画像は表示されません.
                
                
                  下図は Delphi に付属している Glyph 用の 16 x 16 サイズのビットマップの例です. 
                透過処理はビットマップのデフォルトの設定で行われます.各々の正方のビットマップ画像の左下のピクセルの色が透過色となります.
                
 
             
           
        
         
        
         
        
          
            
               
              図1  
                Delphi  に付属の Glyph 用ビットマップ画像の例 
             
            
               
              図2  
                透過状態を確認した画像 
             
           
        
         
        
          
            
              
                  [備考 1] 
                  Delphi 7 等の旧い Delphi には各種の形式の画像が作成,編集可能なイメージエディタが付属していましたが,現在の Delphi にはこのようなイメージエディタは付属していません.
                   
             
           
        
         
        
          
            
              
                  [備考 2] 
              TToolBar では,Glyph 用のビットマップを作成しなくても Images, DisabledImages, HotImages プロパティで個別のビットマップが設定できるようになっています.これらは TImageList 型のプロパティです. 
             
           
        
         
        
         
         
         
        
          
            
              01_ Glyph 用ビットマップは正方サイズの画像を結合して作成する 
             
           
        
         
         
        
          
            
               
                前項の説明,あるいはオンラインヘルプの説明で分かるように,Glyph 用のビットマップ画像は,正方サイズのビットマップを複数結合したビットマップです. 
              結合する画像の数に応じた幅と高さのビットマップを作成して,そこに表示するビットマップを描画して作成します.以下はその例です.
              
                
                このサンプルでは 4 つのビットマップ画像を結合した Glyph 用のビットマップを作成しています.元となるビットマップ画像はディスクから読み込みます.元の画像は 32 x 32 の 24 ビットのビットマップなので,作成した Glyph 用ビットマップは 128 x 32
                のサイズとなります. 
              フォームには TBitBtn と TSpeedButton を各々 1 
                つづつ配置して,作成したビットマップを Glyph プロパティのビットマップとしています.
                
                
                Glyph 用ビットマップの 4 番目の画像は TSpeedButton の Down プロパティ用ですが,このサンプルでは使われません.
                
 
             
           
        
         
        
          
            
              
                  [備考 1] 
              Glyph 用のビットマップに 2 番目の画像がないと Enabled プロパティが False の時に画像は表示されません.3, 4 番目の画像がない場合は,代わりに 1 番目の画像が表示されます. 
              3 番目の画像が無効の場合,4 番目の画像が有効でも 3, 4 番目共に無効となります. 
             
           
        
         
        
          
            
              
                  [備考 2] 
                  本テストで使用しているビットマップ画像は,添付の PNG 画像から以下のプログラムを使用して作成しています.
                   
             
           
        
         
         
        
          
            
               
              図3  
                設計時画面
                  
                  [Glyph 作成] ボタンの下が TBitBtn 
                  その下が TSpeedButton 
                  
             
            
               
              図4  
                EXE を実行して [Glyph 作成] をクリック
                  
                  1 番目の画像が表示される 
                  右が作成した Glyph 用のビットマップ画像 
                  元の画像は 32 x 32 の 24 ビットのビットマップ 
                  
             
            
               
              図5  
                TSpeedButton でマウスの左ボタンを押下した状態
                   
             
            
               
              図6  
                マウスの左ボタンを離した状態
                   
             
            
               
              図7  
                Enabled プロパティの値を False にした状態
                   
             
           
        
         
        
copy code 
unit  Unit1; 
interface  
uses  
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, Buttons, ExtCtrls; 
type  
  TForm1 = class (TForm) 
    BitBtn1: TBitBtn; 
    Button1: TButton; 
    CheckBox1: TCheckBox; 
    Image1: TImage; 
    SpeedButton1: TSpeedButton; 
    procedure  FormCreate(Sender: TObject); 
    procedure  Button1Click(Sender: TObject); 
    procedure  CheckBox1Click(Sender: TObject); 
  private  
    { Private 宣言 }  
  public  
    { Public 宣言 }  
  end ; 
var  
  Form1: TForm1; 
implementation  
{$R *.dfm}  
// ============================================================================= 
//   フォーム生成時の処理 
// ============================================================================= 
procedure  TForm1.FormCreate(Sender: TObject); 
begin  
  CheckBox1.Checked := True; 
  Image1.Center := True; 
end ; 
// ============================================================================= 
//   Glyph用ビットマップを作成して表示,保存 
//   添付の4つのビットマップ画像から作成する 
//   添付のビックマップ画像は 32x32の24ビットのビットマップ画像ファイル 
// ============================================================================= 
procedure  TForm1.Button1Click(Sender: TObject); 
var  
  LStrList : TStringList; 
  LGlyphBmp : TBitmap; 
  LBitmap  : TBitmap; 
  LWidh    : Integer; 
  LHeight  : Integer; 
  LIndex   : Integer; 
  LRect    : TRect; 
begin  
  LWidh   := 0 ; 
  LHeight := 0 ; 
  LStrList  := TStringList.Create; 
  LGlyphBmp := TBitmap.Create; 
  LBitmap   := TBitmap.Create; 
  try  
    // Glyph用ビットマップ画像ファイルのパス名を設定 
    LStrList.Add('EMOTION_1_UP.bmp' ); 
    LStrList.Add('EMOTION_2_DISABLE.bmp' ); 
    LStrList.Add('EMOTION_3_CLICK.bmp' ); 
    LStrList.Add('EMOTION_4_DOWN.bmp' ); 
    for  LIndex := 0  to  LStrList.Count - 1  do  begin  
      LBitmap.LoadFromFile(LStrList[LIndex]); 
      if  LBitmap.PixelFormat = pf32bit then  begin  
        LBitmap.AlphaFormat := afDefined; 
        LBitmap.Transparent :=False; 
      end  else  begin  
        LBitmap.Transparent :=True; 
      end ; 
      // 最初のビットマップ画像の情報を取得 
      // 全てのビットマップのサイズは同じでなければならない 
      if  LIndex = 0  then  begin  
        LWidh   := LBitmap.Width; 
        LHeight := LBitmap.Height; 
        // Glyph用ビットのマップのサイズを決定 
        LGlyphBmp.AlphaFormat := LBitmap.AlphaFormat; 
        LGlyphBmp.Transparent := LBitmap.Transparent; 
        LGlyphBmp.SetSize(LWidh * LStrList.Count, LHeight); 
      end ; 
      // Glyph用ビットマップのCanvasに読み込んだビットマップ画像を描画する 
      // 左から順番にCopyRectメソッドを使用してコピー 
      LRect := Rect(LWidh * LIndex, 0 , LWidh * (LIndex + 1 ), LHeight); 
      LGlyphBmp.Canvas.CopyRect(LRect, 
                               LBitmap.Canvas, 
                               Rect(0 , 0 , LBitmap.Width, LBitmap.Height)); 
    end ; 
    // TBitBtnの設定 
    BitBtn1.NumGlyphs := LStrList.Count; 
    BitBtn1.Glyph.Assign(LGlyphBmp); 
    // TSpeedButtonの設定 
    SpeedButton1.NumGlyphs := LStrList.Count; 
    SpeedButton1.Glyph.Assign(LGlyphBmp); 
    Image1.Picture.Assign(LGlyphBmp); 
    // Glpy用ビットマップの保存 
    LGlyphBmp.SaveToFile('emotion_glyph.bmp' ); 
  finally  
    FreeAndNil(LStrList); 
    FreeAndNil(LGlyphBmp); 
    FreeAndNil(LBitmap); 
  end ; 
end ; 
// ============================================================================= 
//   Enabledプロパティの切り換え 
// ============================================================================= 
procedure  TForm1.CheckBox1Click(Sender: TObject); 
begin  
  BitBtn1.Enabled      := CheckBox1.Checked; 
  SpeedButton1.Enabled := CheckBox1.Checked; 
end ; 
end . 
 
         
        
         
         
         
        
          
            
              02_ Glyph 用ビットマップと TSpeedButton の Down プロパティ 
             
           
        
         
         
        
          
            
               
                Glyph 用ビットマップの 4 番目の画像は TSpeedButton の Down プロパティ用です.
              
                
                TSpeedButton の GroupIndex プロパティの値を 1 以上にすると,GroupIndex プロパティの値が同じボタンは,1 つだけが Down プロパティの値を True にできます.この機能により,どの TSpeedButton が押されているかを判定することが可能になります.同じ GroupIndex のボタンであれば,クリックしたボタンが自動的に Down プロパティが True になり,他のボタンは全て False になります. 
                Down プロパティの値が True の時に使われるのが Glyph 用ビットマップの 4 番目の画像です.
                
                
  本サンプルはこのことを確認するためのテスト用です. 
  TSpeedButton を 2 つ配置し,どちらも GroupIndex の値を 1 にしています.
 
                
 
             
           
        
         
        
          
            
              
                  [備考] 
              GroupIndex の値が 0 の TSpeedButton は Down プロパティの値を True にできません. 
              TBitBtn には Down プロパティはありません. 
             
           
        
         
         
        
          
            
               
              図8  
               	TSpeedButton でマウスの左ボタンを押下した状態
                   
             
            
               
              図9  
                マウスの左ボタンを離した状態
                  
                  4 番目の画像が表示される 
                  他の TSpeedButton には 1 番目の画像が表示される 
                  
             
            
               
              図10  
                下の TSpeedButton をクリックした状態
                  
                  下のボタンには 4 番目の画像が表示される 
                  その他のボタンには 1 番目の画像が表示される 
                  
             
            
               
              図11  
               	Enabled プロパティの値を False にした状態
                  
                  Down プロパティの値に関係なく,2 番目の画像が表示される 
                  
             
           
        
         
        
          
            
               
                Down プロパティは,ボタンが Down (ダウン) していることを意味しますが,上の図ではグラデーション描画となっていてフレームが太くなっているだけになっています. 
              下図はテーマを無効にして実行した結果ですが.テーマという概念がない Windows の時代には,実際に下図のように下がった状態になりました.
              
 
             
           
        
         
         
        
          
            
               
              図12  
               	 テーマを無効にした時の Dwon プロパティが True のボタンの表示状態 
             
           
        
         
        
          
            
              リスト2  
                Glyph 用ビットマップと TSpeedButton の Down プロパティ 
             
           
        
copy code 
unit  Unit1; 
interface  
uses  
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, Buttons, ExtCtrls; 
type  
  TForm1 = class (TForm) 
    Button1: TButton; 
    CheckBox1: TCheckBox; 
    Image1: TImage; 
    SpeedButton1: TSpeedButton; 
    SpeedButton2: TSpeedButton; 
    procedure  FormCreate(Sender: TObject); 
    procedure  Button1Click(Sender: TObject); 
    procedure  CheckBox1Click(Sender: TObject); 
  private  
    { Private 宣言 }  
  public  
    { Public 宣言 }  
  end ; 
var  
  Form1: TForm1; 
implementation  
{$R *.dfm}  
// ============================================================================= 
//   フォーム生成時の処理 
// ============================================================================= 
procedure  TForm1.FormCreate(Sender: TObject); 
begin  
  CheckBox1.Checked := True; 
  Image1.Center := True; 
end ; 
// ============================================================================= 
//   Glyph用ビットマップを作成して表示,保存 
//   TSpeedButtonのDownプロパティの動作確認 
//  
//   添付の4つのビットマップ画像から作成する 
//   添付のビックマップ画像は 32x32の24ビットのビットマップ画像ファイル 
// ============================================================================= 
procedure  TForm1.Button1Click(Sender: TObject); 
var  
  LStrList  : TStringList; 
  LGlyphBmp : TBitmap; 
  LBitmap   : TBitmap; 
  LWidh     : Integer; 
  LHeight   : Integer; 
  LIndex    : Integer; 
  LRect     : TRect; 
begin  
  LWidh   := 0 ; 
  LHeight := 0 ; 
  // GroupIndexの値が1以上でないとDownプロパティは機能しない 
  SpeedButton1.GroupIndex := 1 ; 
  SpeedButton2.GroupIndex := 1 ; 
  LStrList  := TStringList.Create; 
  LGlyphBmp := TBitmap.Create; 
  LBitmap   := TBitmap.Create; 
  try  
    // Glyph用ビットマップ画像ファイルのパス名を設定 
    LStrList.Add('EMOTION_1_UP.bmp' ); 
    LStrList.Add('EMOTION_2_DISABLE.bmp' ); 
    LStrList.Add('EMOTION_3_CLICK.bmp' ); 
    LStrList.Add('EMOTION_4_DOWN.bmp' ); 
    for  LIndex := 0  to  LStrList.Count - 1  do  begin  
      // ビットマップ画像ファイルを読み込む 
      LBitmap.LoadFromFile(LStrList[LIndex]); 
      if  LBitmap.PixelFormat = pf32bit then  begin  
        LBitmap.AlphaFormat := afDefined; 
        LBitmap.Transparent :=False; 
      end  else  begin  
        LBitmap.Transparent :=True; 
      end ; 
      // 最初のビットマップ画像の情報を取得 
      // 全てのビットマップのサイズは同じでなければならない 
      if  LIndex = 0  then  begin  
        LWidh   := LBitmap.Width; 
        LHeight := LBitmap.Height; 
        // Glyph用ビットのマップのサイズを決定 
        LGlyphBmp.AlphaFormat := LBitmap.AlphaFormat; 
        LGlyphBmp.Transparent := LBitmap.Transparent; 
        LGlyphBmp.SetSize(LWidh * LStrList.Count, LHeight); 
      end ; 
      // Glyph用ビットマップのCanvasに読み込んだビットマップ画像を描画する 
      // 左から順番にCopyRectメソッドを使用してコピー 
      LRect := Rect(LWidh * LIndex, 0 , LWidh * (LIndex + 1 ), LHeight); 
      LGlyphBmp.Canvas.CopyRect(LRect, 
                               LBitmap.Canvas, 
                               Rect(0 , 0 , LBitmap.Width, LBitmap.Height)); 
    end ; 
    // TSpeedButtonの設定 
    // GroupIndexの値は0でない値にしないとDownプロパティは機能しない 
    SpeedButton1.NumGlyphs  := LStrList.Count; 
    SpeedButton1.Glyph.Assign(LGlyphBmp); 
    SpeedButton2.NumGlyphs := LStrList.Count; 
    SpeedButton2.Glyph.Assign(LGlyphBmp); 
    Image1.Picture.Assign(LGlyphBmp); 
    // Glpy用ビットマップの保存 
    LGlyphBmp.SaveToFile('emotion_glyph.bmp' ); 
  finally  
    FreeAndNil(LStrList); 
    FreeAndNil(LGlyphBmp); 
    FreeAndNil(LBitmap); 
  end ; 
end ; 
// ============================================================================= 
//   TSpeedButtonのEnabledプロパティの切り換え 
// ============================================================================= 
procedure  TForm1.CheckBox1Click(Sender: TObject); 
begin  
  SpeedButton1.Enabled := CheckBox1.Checked; 
  SpeedButton2.Enabled := CheckBox1.Checked; 
end ; 
end . 
 
         
        
         
         
         
        
          
            
              03_ Glyph 用ビットマップとアルファチャンネル付きビットマップ 
             
           
        
         
         
        
          
            
               
                ここまでのサンプルでは 24 ビットのビットマップで Glyph 用ビットマップを作成しています. 
                Glyph 用のビットマップとしては,32 ビットのアルファチャンネル付きの半透明のビットマップ画像も使用できます.ただし,透明色は「黒」になります.また,半透明のピクセルは半透明ではなくなります.つまり,アルファチャンネルの値は無視されます.下図はその実際の結果です.使用している元のビットマップは 32 x 32 の 32 ビットのアルファチャンネル付きのビットマップです.
              
 
             
           
        
         
         
        
          
            
              
                  [備考] 
              TToolBar ではボタンを追加して使用します.このボタンのクラス名は TToolButton です.それらのボタンの画像は TImageList で設定します.Delphi 2009 以降の TmageList では,アルファチャンネル付きの PNG 画像やアルファチャンネル付きビットマップ画像も指定でき,TToolButton にアルファチャンネル付きの画像として描画できます. 
              Delphi 2009 からは TImage もアルファチャンネル付きの画像の描画が可能となっています.下図の結果でも,Glyph 用ビットマップの半透明ピクセルが半透明で描画されています.
               
             
           
        
         
         
        
          
            
               
              図13  
               	 アルファチャンネルの値は無視される
                  
                  右の TImage では,アルファチャンネル付きの画像が正常に描画されている 
                  
             
           
        
         
        
          
            
               
              32 ビットのビットマップを,以下のように 24 ビットのビットマップすれば,これまでのサンプルとほぼ同じ結果になります.24 ビットと 32 ビットのビットマップの違いは,アルファチャンネルを使用するかしないかの違いてす. 
              アルファチャンネルを使用したビットマップ画像には半透明のピクセルがあります.TBitmap.PixelFormat プロパティによる減色は簡易的なものです.画質を考慮するのであれば他の減色処理が必要です.
 
             
           
        
         
      // ビットマップ画像ファイルを読み込む 
      LBitmap.LoadFromFile(LStrList[LIndex]); 
      if  LBitmap.PixelFormat = pf32bit then  begin  
        LBitmap.PixelFormat := pf24bit; 
        LBitmap.Transparent := True; 
      end  else  begin  
        LBitmap.Transparent :=True; 
      end ; 
 
         
         
        
          
            
               
              図14  
               	  24 ビットのビットマップにした場合 
             
           
        
         
        
         
         
         
        
          
            
              04_ アイコン画像編集ソフトを使用した Glyph 用ビットマップ作成 
             
           
        
         
         
        
          
            
               
                Glyph 用のビットマップ画像の 2 番目の画像は一般的にグレイスケールの画像です. 
                この Disable な画像としてのグレイスケールな画像も含めて,Glyph 用のビットマップ画像はアイコン画像の作成編集用のソフトでも作成できます.画像編集ソフトの多くには画像のグレイスケール化の機能が実装されています.
                
                まず,元の画像を作成します.その画像をグレイスケール化した画像を作成します.必要に応じて明るさやコントラストを調整します.次に高さが同じで幅が元の画像の 2 倍の画像を新規に作成します.その画像に元の画像とグレイスケール化した画像をコピーして貼り付けます.
                   
                保存する時はビットマップ形式で保存します.
                
                
                  下記の GIGAZINE で紹介しているサイトからダウンロードしたアイコン集には,Disable な画像に使用できるグレイスケールのアイコンが含まれています.それらは PNG 形式の画像です.
              
 
             
           
        
         
        
         
        
          
            
               
              図15  
               	 KH IconStudio を使用しても Glyph 用のビットマップ画像が作成できる 
             
           
        
         
        
          
            
              
                [備考] 
                  手元の  	 KH IconStudio では [グレイスケール 256 色] を選択してもグレイスケールにできませんでした.上の図は,[ツール] [色相・彩度・明度調整] のダイアログで [彩度] の値を 0 % にして作成しています.
 
             
           
        
         
        
         
         
         
        
          
            
              05_ 実行時における Glyph プロパティの設定と取得と無効化 
             
           
        
         
         
        
          
            
               
                Glyph プロパティの型は TBitmap です. 
                したがって,例えば以下のようなコードで実行時に設定したり取得できます.
              
                
                  テストで使用したビットマップ画像は,上のサンプルで作成した Glyph 画像です.円の内部の一部が透過色と同じ色になってしまい,透過状態になっています.テスト使用したような単色に近い色で構成されていて,使用している色数が少ない画像の時はこのような現象が発生することがあります. 
                  このような場合は背景を別の色で塗り潰せば透過しなくなります.背景のピクセルは必ずしも連続しているとは限らないので,自動で処理するのは難しそうです.
                
 
             
           
        
         
         
        
          
            
               
              図16  
                設計時画面
                   
             
            
               
              図17  
                [Glyph 設定] ボタンクリック
                   
             
            
               
              図18  
                [Glyph 取得] ボタンをクリック
                   
             
            
               
              図19  
                Enabled プロパティの値を Flase にした状態
                  
                  TBitBtn に Glyph の 2 番目のビットマップ画像が表示される 
                  2 番目の画像がない場合は,画像は表示されない 
                  この画像の場合,円の内部の一部が透過色と同じ色になってしまい,透過している 
                  
             
            
               
              図20  
                Glyph プロパティを無効にした状態 
             
           
        
         
        
          
            
              リスト3  
                Glyph プロパティを実行時に設定または取得あるいは無効にする 
             
           
        
copy code 
unit  Unit1; 
interface  
uses  
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, Buttons, ExtCtrls; 
type  
  TForm1 = class (TForm) 
    Button1: TButton; 
    Button2: TButton; 
    Button3: TButton; 
    BitBtn1: TBitBtn; 
    CheckBox1: TCheckBox; 
    Image1: TImage; 
    procedure  FormCreate(Sender: TObject); 
    procedure  Button1Click(Sender: TObject); 
    procedure  Button2Click(Sender: TObject); 
    procedure  CheckBox1Click(Sender: TObject); 
    procedure  Button3Click(Sender: TObject); 
  private  
    { Private 宣言 }  
  public  
    { Public 宣言 }  
  end ; 
var  
  Form1: TForm1; 
implementation  
{$R *.dfm}  
// ============================================================================= 
//   フォーム生成時の処理 
// ============================================================================= 
procedure  TForm1.FormCreate(Sender: TObject); 
begin  
  CheckBox1.Checked := True; 
end ; 
// ============================================================================= 
//   Glyphプロパティを設定 
// ============================================================================= 
procedure  TForm1.Button1Click(Sender: TObject); 
var  
  LFilePath : string ; 
  LBitmap   : TBitmap; 
begin  
  LFilePath := ExpandFileName('..\Images\Test_Glyph.bmp' ); 
  LBitmap := TBitmap.Create; 
  try  
    LBitmap.LoadFromFile(LFilePath); 
    BitBtn1.Glyph.Assign(LBitmap); 
  finally  
    FreeAndNil(LBitmap); 
  end ; 
end ; 
// ============================================================================= 
//   Glyphのビットマップを取得 
// ============================================================================= 
procedure  TForm1.Button2Click(Sender: TObject); 
begin  
  Image1.Picture.Bitmap := BitBtn1.Glyph; 
end ; 
// ============================================================================= 
//   Glyphプロパティのビットマップを削除 
//   ボタンにGlyphの画像を表示しなくする 
// ============================================================================= 
procedure  TForm1.Button3Click(Sender: TObject); 
begin  
  BitBtn1.Glyph.Assign(nil ); 
end ; 
// ============================================================================= 
//   TBitBtnのEnabledプロパティの切り換え 
// ============================================================================= 
procedure  TForm1.CheckBox1Click(Sender: TObject); 
begin  
  BitBtn1.Enabled := CheckBox1.Checked; 
end ; 
end . 
 
         
        
         
         
         
        
          
            
              06_ TImageList を使用した Glyph 用ビットマップの設定 
             
           
        
         
         
        
          
            
               
                TImageList を使用する方法です.
                     
              設計時に TImageList に必要なビットマップ画像をセットしておいて,実行時に,それらの画像を取り出して Glyph 用のビットマップを作成します.この方法は,あらかじめ Glyph 用としてのビットマップを作成しておく必要がありません
              
                
                 最初の TImageList には通常表示用の画像を格納します.次の TImageList には Disable な状態を表示するための画像を格納します.このようにすると,TToolBar で TToolButton の画像を設定する方法と設計時の手順が同じになり,TToolBar で使用する TImageList と共有することも可能になります.また,TToolButton への移行も容易になります.
                
                
                TImageList には PNG 形式,ICO 形式の画像も格納できますが,TBitBtn, TSpeedButton ではアルファチャンネル付きの画像は正常に描画できません.
                
                
                  Glyph 用のビットマップを作成しなくても,Enabled プロパティ等が変更された時に,TImageList から必要なビットマップ画像を Glyph プロパティに,以下のようにセットすることもできます. 
              このコードでは ImageList1 の Lindex 番目 (0 ベース) の画像を取得して SpeedButton.Glyph のビットマップとして設定します.
                
 
             
           
        
         
      ImageList1.GetBitmap(LIndex, SpeedButton1.Glyph); 
 
 
        
         
        
          
            
               
              図21  
                設計時画面
                  
                  TSpeedButton を 2 つ配置 
                  TImageList を 2 つ配置 
                  
             
            
               
              図22  
                TImageList の設定
                  
                  サイズと ColorDepth を使用するビットマップと同じにする 
                  
             
           
        
         
        
          
            
               
                上の図で示すような設定をしたら,TImageList に必要なビットマップ画像をセットします.画像を読み込んでからサイズや色数 ( ColorDepth) を変更すると,読み込んだ画像が消去されてしまいます.
              
 
             
           
        
         
         
        
          
            
               
              図23  
                ImaeList1 に通常表示用としてのビットマップ画像を読み込む 
             
            
               
              図24  
                ImaeList2 に Disable な画像としてグレイスケールのビットマップ画像をセットする 
             
           
        
         
        
         
         
        
          
            
               
              図25  
                実行結果 
             
            
               
              図26  
                Enabled プロパティの値を False にした状態 
             
           
        
         
        
          
            
              リスト4  
                TImageList を使用して Glyph 用ビットマップを設定する 
             
           
        
copy code 
unit  Unit1; 
interface  
uses  
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, Buttons, ExtCtrls, ImgList; 
type  
  TForm1 = class (TForm) 
    CheckBox1: TCheckBox; 
    SpeedButton1: TSpeedButton; 
    SpeedButton2: TSpeedButton; 
    ImageList1: TImageList; 
    ImageList2: TImageList; 
    procedure  FormCreate(Sender: TObject); 
    procedure  CheckBox1Click(Sender: TObject); 
  private  
    { Private 宣言 }  
    procedure  SetGlyphFromTImageList(AImgListUp, AImgListDisable, AImgListClick, 
      AImgListDown: TImageList; AButton: TObject; AImgIndex: Integer); 
  public  
    { Public 宣言 }  
  end ; 
  procedure  SetBitmapAlpha(ABitmap: TBitMap); 
var  
  Form1: TForm1; 
implementation  
{$R *.dfm}  
// ============================================================================= 
//   フォーム生成時の処理 
//   TImageListに格納したビットマップをGlyph用のビットマップして使用する方法 
// ============================================================================= 
procedure  TForm1.FormCreate(Sender: TObject); 
begin  
  CheckBox1.Checked := True; 
  // 背景色は元のビットマップにはない色にする 
  ImageList1.BkColor := clBlue; 
  ImageList2.BkColor := clBlue; 
  SetGlyphFromTImageList(ImageList1, ImageList2, nil , nil , SpeedButton1, 0 ); 
  SetGlyphFromTImageList(ImageList1, ImageList2, nil , nil , SpeedButton2, 1 ); 
end ; 
// ============================================================================= 
//   TSpeedButtonのEnabledプロパティの切り換え 
// ============================================================================= 
procedure  TForm1.CheckBox1Click(Sender: TObject); 
begin  
  SpeedButton1.Enabled := CheckBox1.Checked; 
  SpeedButton2.Enabled := CheckBox1.Checked; 
end ; 
// ----------------------------------------------------------------------------- 
//   TImageListに格納されている画像からGlyph用のビットマップを作成してセットする 
//  
//   AImgListUp      : 通常表示する画像を格納したTImageList 
//   AImgListDisable : Disableな状態を表す画像を格納したTImageList 
//   AImgListClick   : マウスの左ボタン押下時に表示示する画像を格納したTImageList 
//   AImgListDown    : DownプロパティがTrueの時に表示する画像を格納したTImageList 
//   AButtton        : TSpeedButtonまたはTBitBtn 
//   AImgIndex       : TimageListの何番目の画像を使用するかの指定(0ベース) 
// ----------------------------------------------------------------------------- 
procedure  TForm1.SetGlyphFromTImageList(AImgListUp, AImgListDisable, AImgListClick, 
  AImgListDown: TImageList; AButton: TObject; AImgIndex: Integer); 
  procedure  CopyTImgListBmpToGlyphCanvas(AImgList : TImageList; AGlyph: TBitmap; 
    ANo: Integer); 
  var  
    LBitmap : TBitmap; 
    LRect   : TRect; 
  begin  
    if  AImgList = nil  then  exit; 
    LBitmap := TBitmap.Create; 
    try  
      //  GetBitmap は 透明ピクセルを処理しない (TBitmap として取得する場合) 
      //  そこで TBitmap を完全に透明なビットマップにしておく 
      if  AImgList.ColorDepth = cd32Bit then  begin  
        LBitmap.AlphaFormat := afDefined; 
        LBitmap.SetSize(AImgList.Width, AImgList.Height); 
        SetBitmapAlpha(LBitmap); 
      end ; 
      if  AImgList.GetBitmap(AImgIndex, LBitmap) then  begin  
        // Glyph用ビットマップのCanvasにビットマップとして取得した画像を描画する 
        LRect := Rect(LBitmap.Width * ANo, 0 , LBitmap.Width * (ANo + 1 ), LBitmap.Height); 
        AGlyph.Canvas.CopyRect(LRect, 
                               LBitmap.Canvas, 
                               Rect(0 , 0 , LBitmap.Width, LBitmap.Height)); 
      end ; 
    finally  
      FreeAndNil(LBitmap); 
    end ; 
  end ; 
var  
  LGlphBmp  : TBitmap; 
  LImgCount : Integer; 
begin  
  if  AImgListUp = nil  then  exit; 
  LGlphBmp := TBitmap.Create; 
  try  
    // Glyph用ビットマップのサイズを設定 
    LImgCount := 1 ; 
    if  AImgListDisable <> nil  then  LImgCount := 2 ; 
    if  AImgListClick <> nil    then  LImgCount := 3 ; 
    if  AImgListDown <> nil     then  LImgCount := 4 ; 
    LGlphBmp.SetSize(AImgListUp.Width * LImgCount, AImgListUp.Height); 
    LGlphBmp.Canvas.FillRect(LGlphBmp.Canvas.ClipRect); 
    // TImageListの画像をビットマップとして取得して,GlyphのCanvasに追加していく 
    CopyTImgListBmpToGlyphCanvas(AImgListUp,      LGlphBmp, 0 ); 
    CopyTImgListBmpToGlyphCanvas(AImgListDisable, LGlphBmp, 1 ); 
    CopyTImgListBmpToGlyphCanvas(AImgListClick,   LGlphBmp, 2 ); 
    CopyTImgListBmpToGlyphCanvas(AImgListDown,    LGlphBmp, 3 ); 
    // Glyphプロパティを設定 
    if  AButton is  TSpeedButton then  begin  
     TSpeedButton(AButton).Glyph :=  LGlphBmp; 
    end ; 
    if  AButton is  TBitBtn then  begin  
     TBitBtn(AButton).Glyph :=  LGlphBmp; 
    end ; 
  finally  
    FreeAndNil(LGlphBmp); 
  end ; 
end ; 
// ---------------------------------------------------------------------------- 
//   透明なビットマップ画像の作成 
//   アルファチャンネルのビットマップのピクセル値のクリア 
//   Red,Gree, Blue, Alphi 値を全て0 にしたビットマップにする 
// ---------------------------------------------------------------------------- 
procedure  SetBitmapAlpha(ABitmap: TBitMap); 
type  
  TRGBQArray = array  [0 ..High(Integer) div  4  - 1 ] of  RGBQUAD; 
  PRGBQArray = ^TRGBQArray; 
var  
  LPosY      : Integer; 
  LPosX      : Integer; 
  LScanArray : PRGBQArray; 
begin  
  ABitmap.Canvas.Lock; 
  ABitmap.PixelFormat := pf32bit; 
  for  LPosY := 0  to  ABitmap.Height - 1  do  begin  
    LScanArray := ABitmap.ScanLine[LPosY]; 
    for  LPosX  := 0  to  ABitmap.Width - 1  do  begin  
      LScanArray[LPosX].rgbRed      := 0 ; 
      LScanArray[LPosX].rgbGreen    := 0 ; 
      LScanArray[LPosX].rgbBlue     := 0 ; 
      LScanArray[LPosX].rgbReserved := 0 ; 
    end ; 
  end ; 
  ABitmap.Canvas.Unlock; 
end ; 
end . 
 
         
        
         
         
         
        
          
            
              07_ 単独の TSpeedButton で Down 状態のトグル機能 
             
           
        
         
         
        
          
            
               
                TSpeedButton の Down プロパティは GroupIndex の値が 1 以上の時に有効となります. 
                複数の TSpeedButton をグループ化して,その 1 だけを Down プロパティを True に,つまり押したままの状態にすることができます.以下のサンプルは,複数の TSpeedButton を配置している状態で各々の TSpeedButton 単独で Down プロパティを有効にする方法です.この動作は TCheckBox と同じように,クリックする度に状態が入れ換わるトグル機能です.
              
                
                配置した各々の GroupIndex のそれぞれ異なる値にします.そして AllowAllUp の値を True にします.これらのプロパティの値はオブジェクト・インスペクタで設定できます.
              
 
             
           
        
         
        
         
        
          
            
              
                  [備考] 
              本サンプルでの TSpeedButton は,クリックする度に Down プロパティの値が自動で変わります. 
              TCheckBox はクリックする度にチェックマークを表示したり非表示にしますが,TSpeedButton では下がった状態と上がった状態で色が変わります. 
              上の方に図を掲載していますが,昔は本当に下がった状態になりました. 
             
           
        
         
         
        
          
            
               
              図27  
                サンプルの EXE を実行した画面<
                  
                  全ての TSpeedButto.Dow が False の状態 
                  
             
            
               
              図28  
                全ての TSpeedButton を押した状態
                  
                  各々の TSpeedButton をクリックした結果 
                  全ての TSpeedButton.Down の値が True の状態 
                  右のボタンでも Down 状態のトグル操作が可能 
                  
             
            
               
              図29  
                上の図の状態で真ん中の TSpeedButton をクリック 
             
           
        
         
        
          
            
              リスト5  
                TSpeedButton 単独で Down 状態のトグル機能を実現する 
             
           
        
copy code 
unit  Unit1; 
interface  
uses  
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, Buttons, StdCtrls; 
type  
  TForm1 = class (TForm) 
    SpeedButton1: TSpeedButton; 
    SpeedButton2: TSpeedButton; 
    SpeedButton3: TSpeedButton; 
    Button1: TButton; 
    Button2: TButton; 
    Button3: TButton; 
    procedure  FormCreate(Sender: TObject); 
    procedure  Button1Click(Sender: TObject); 
    procedure  Button2Click(Sender: TObject); 
    procedure  Button3Click(Sender: TObject); 
    procedure  SpeedButton1Click(Sender: TObject); 
  private  
    { Private 宣言 }  
  public  
    { Public 宣言 }  
  end ; 
var  
  Form1: TForm1; 
implementation  
{$R *.dfm}  
// ============================================================================= 
//   フォーム生成時の処理 
// ============================================================================= 
procedure  TForm1.FormCreate(Sender: TObject); 
begin  
  SpeedButton1.GroupIndex := 1 ; 
  SpeedButton2.GroupIndex := 2 ; 
  SpeedButton3.GroupIndex := 3 ; 
  SpeedButton1.AllowAllUp := True; 
  SpeedButton2.AllowAllUp := True; 
  SpeedButton3.AllowAllUp := True; 
end ; 
// ============================================================================= 
//   TSpeedButtonのクリックイベント 
// ============================================================================= 
procedure  TForm1.SpeedButton1Click(Sender: TObject); 
begin  
  if  TSpeedButton(Sender).Down then  begin  
    // DownプロパティがTrueになった時の処理 
    // ボタンが下がった状態になった時の処理 
  end  else  begin  
    // DownプロパティがFalseになった時の処理 
    // ボタンが上がった状態になった時の処理 
  end ; 
end ; 
// ============================================================================= 
//   SpeedButton1のDown状態の変更 
//   トグル操作 
// ============================================================================= 
procedure  TForm1.Button1Click(Sender: TObject); 
begin  
  SpeedButton1.Down := not  SpeedButton1.Down; 
end ; 
// ============================================================================= 
//   SpeedButton2のDown状態の変更 
//   トグル操作 
// ============================================================================= 
procedure  TForm1.Button2Click(Sender: TObject); 
begin  
  SpeedButton2.Down := not  SpeedButton2.Down; 
end ; 
// ============================================================================= 
//   SpeedButton3のDown状態の変更 
//   トグル操作 
// ============================================================================= 
procedure  TForm1.Button3Click(Sender: TObject); 
begin  
  SpeedButton3.Down := not  SpeedButton3.Down; 
end ; 
end .