BitBtnのGryphにアイコンを描画

解決


スコピョン  2008-09-05 20:18:58  No: 31846

BitBtnのGryphにアイコンを描画する方法を教えてください。
アイコンはXPタイプの、透過・半透過をサポートしているものです。

http://www.geocities.jp/asumaroyuumaro/program/tips/extracticon.html

を参考にやってみましたが、
DrawIconでは BitBtn.GryphのCanvas にはうまく描画できません。

よろしくお願いします。

WinXP、Delphi2007

※usesに  shellapi追加

procedure TForm1.Button1Click(Sender: TObject);
var
  HICO :HICON;//アイコンハンドル
  P    :AnsiString;

begin

 P:='C:\WINDOWS\explorer.exe';

 HICO :=ExtractIcon(hInstance, PChar(P) ,0);

 if HICO <>0  then
 begin

   DrawIcon(BitBtn1.Glyph. Canvas.Handle, 2,2, HICO);//何も描画されない

   DrawIcon(Form1.Canvas.Handle, 5,5, HICO);//これはOK

   DestroyIcon(HICO);

 end;

end;


monaa  2008-09-05 22:53:14  No: 31847

ソースを見てませんが、
TBitBtnとTButtonではイメージの所有の仕方が違うはずです。
windows標準のイメージ付アイコン仕様はTButtonの方でいつからか知りませ
んが実装されています、D2009(FT)で確認しました。
そこにアイコンを割り当ててあげれば半透明アイコンもきれいに描画される
はずです。
Delphiでは未確認ですが、非VCLのButtonコントロールに半透明アイコンを乗
せたことはあります、その時は問題なく描画されてました。


スコピョン  2008-09-05 23:37:59  No: 31848

Gryphは間違いで、Glyphです。

早速の回答ありがとうございます。
ですが、話が高度すぎてついていけません。orz

>windows標準のイメージ付アイコン仕様はTButtonの方でいつからか知りませ
んが実装されています

TButtonにイメージを描画する方法があるんでしょうか?


monaa  2008-09-05 23:42:53  No: 31849

TButton.images
TImageListってプロパティありませんか?
D2009からなのかな?
確認してみてください。


スコピョン  2008-09-05 23:48:15  No: 31850

当方、D2007です。

Buttonにはiで始まるプロパティはなさそうです。
IDEのコード補完で確認・・・って確実なのかな・・・

BitBtnのGlyphには半透過イメージ描画って難しいのでしょうか?
Formはできるんですが・・・


monaa  2008-09-06 02:06:19  No: 31851

TButtonなら
var aIcon : TIcon;
SendMessage(Button1.Handle ,BM_SETIMAGE, IMAGE_ICON ,aIcon.Handle);

でいけます、aIcon.Handleはアイコンハンドルであれば何でも可です。
BitBtnで同じことをしましたが、やはり描画されません。
BitBtnで行うにはVCLを潜らないとわからないと思います。


KHE00221  2008-09-06 02:08:13  No: 31852

Width=0 Height=0 のBitmapに何を描画しても
表示されないのは当然では?


スコピョン  2008-09-06 02:46:07  No: 31853

KHE00221さん
>Width=0 Height=0 のBitmapに何を描画しても表示されないのは当然では?
これはそうかな、とは思ったんですが、デザイン時に適当なbmpを設定しても書き換わりませんでした。

monaaさん
Button2を追加し、
SendMessage(Button2.Handle ,BM_SETIMAGE, IMAGE_ICON , HICO );
でやってみたんですが描画されません・・・すみません、ビギナーで・・
何がいけなかったんでしょうか?


スコピョン  2008-09-06 03:16:46  No: 31854

追加です。

   SetWindowLong(Button2.Handle, GWL_STYLE, GetWindowLong(Button2.Handle, GWL_STYLE) or BS_ICON );
   SendMessage(Button2.Handle ,BM_SETIMAGE, IMAGE_ICON , application.icon.handle );

だと描画されます。SetWindowLong・・・が必要なんでしょうか。
但しボタンのデザインがクラッシクスタイルになっちゃいます。

   SetWindowLong(Button2.Handle, GWL_STYLE, GetWindowLong(Button2.Handle, GWL_STYLE) or BS_ICON );
   SendMessage(Button2.Handle ,BM_SETIMAGE, IMAGE_ICON , HICO );

は描画されません。application.icon と HICO には何か違いがあるんでしょうね・・・


monaa  2008-09-06 03:42:48  No: 31855

サンプル見ました。
アイコンハンドル解放してませんか?
Form1のprivateもしくはpublicで宣言して、
解放はアプリケーション終了時に行ってください。

procedure TForm1.Button1Click(Sender: TObject);
begin
  myIco :=ExtractIcon(hInstance, PChar('C:\WINDOWS\explorer.exe'), 0);
  SendMessage(Button1.Handle ,BM_SETIMAGE, IMAGE_ICON ,myIco);
end;


KHE00221  2008-09-06 04:18:56  No: 31856

>これはそうかな、とは思ったんですが、デザイン時に適当なbmpを設定しても書き換わりませんでした。

デザイン時にロードせず

   BitBtn1.Glyph.SetSize(32,32);
   DrawIcon(BitBtn1.Glyph. Canvas.Handle, 2,2, HICO);

で表示できる


monaa  2008-09-06 05:32:28  No: 31857

すみません!
VistaとXPで挙動が異なるようです。
今、調べなおします。


monaa  2008-09-06 06:39:26  No: 31858

私の方法では半透明できませんでした。
申し訳ございません。
Vista専用でした。


スコピョン  2008-09-08 18:54:51  No: 31859

monaaさん、 KHE00221さんありがとうございます。

   BitBtn1.Glyph.SetSize(32,32);
   DrawIcon(BitBtn1.Glyph. Canvas.Handle, 2,2, HICO);

で表示できました。半透過・・・は無理なんですね。

何か情報をお持ちの方、よろしくお願いします。


KHE00221  2008-09-08 21:08:58  No: 31860

BitBtn1.Glyph に直接描画しないで、一旦ビットマップに描画して
それをBitBtn1.Glyphにロードするようにすればできるかなと

var
  Bitmap : TBitmap;

procedure TForm8.Button1Click(Sender: TObject);
var
   HICO :HICON;//アイコンハンドル
   P    :AnsiString;
begin
   P:='C:\WINDOWS\explorer.exe';
    HICO :=ExtractIcon(hInstance, PChar(P) ,0);
    if HICO <>0  then
    begin
      DrawIcon(Bitmap. Canvas.Handle, 2,2, HICO);//何も描画されない
      BitBtn1.Glyph.Assign(Bitmap);
      DestroyIcon(HICO);
    end;
end;

procedure TForm8.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    Bitmap.Free;
end;

procedure TForm8.FormCreate(Sender: TObject);
begin
    Bitmap := TBitmap.Create;
    Bitmap.PixelFormat := pf32bit;
    Bitmap.SetSize(32,32);
    Bitmap.Canvas.Brush.Style := bsClear;
    Bitmap.Canvas.Brush.Color := clBtnFace;
    Bitmap.Canvas.FillRect(Rect(0,0,32,32));
end;


スコピョン  2008-09-08 22:12:43  No: 31861

KHE00221さん、何度もありがとうございます。

 Bitmap.Canvas.Brush.Color := clBtnFace;
 Bitmap.Canvas.FillRect(Rect(0,0,32,32));

成る程・・・そんなに簡単な方法でできるとは。色々と指南ありがとうございました。
解決とさせていただきます。


スコピョン  2008-09-08 22:13:14  No: 31862

解決です。


Mr.XRAY  2008-09-09 02:00:40  No: 31863

解決済みというこですが,
おそらく,Glyph用のイメージは,アルファチャンネルをサポートしていなのでは
ないでしょうか.
すくなくともDelphi2007までは.
TImageListは使えるようです(確認済み).


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加