お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"不定形なフォーム(Windows2000専用)"





Windows2000で追加された UpdateLayeredWindow と アルファマスクをもった
32BIT BITMAPを使用して、不定形、かつ、アルファマスク処理されたフォー
ムを作成します。
これで端がアルファ処理されて、ジャギーの目立たない不定形フォームがで
きます。2000専用ですけれども(^^;;

TMainForm = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private 宣言 }
    First : boolean;
  protected
    { Protected 宣言 }
    Surface : TBitmap;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure WmDisplayChange(var Msg:TMsg); message WM_DISPLAYCHANGE;
    function  LoadBmp:boolean;
    function  MakeLayer:boolean;
end;

function UpdateLayeredWindow(_hwnd:HWND; dstHDC:HDC; pptDst:PPoint;
         ASize:PSize; srcHDC:HDC; pptSrc:PPoint; crKey:COLORREF;
         var bf : BLENDFUNCTION; dwFlag:DWORD):BOOL; stdcall;

implementation

const
  WS_EX_LAYERED = $80000;
  LWA_COLORKEY  = 1;
  LWA_ALPHA     = 2;
  ULW_COLORKEY  = 1;
  ULW_ALPHA     = 2;
  ULW_OPAQUE    = 4;
  AC_SRC_ALPHA  = 1;

function UpdateLayeredWindow;
  external 'user32.dll' name 'UpdateLayeredWindow';

procedure TMainForm.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do ExStyle := ExStyle or WS_EX_LAYERED;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  First:=true;
  Surface:=TBitmap.Create;
  Surface.PixelFormat:=pf32bit;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  Surface.free;
end;

procedure TMainForm.FormShow(Sender: TObject);
begin
  IF NOT First THEN Exit;
  First:=false;
  IF NOT LoadBmp THEN Close;
  IF NOT MakeLayer THEN Close;
end;

procedure TMainForm.WmDisplayChange(var Msg:TMsg);
begin
  IF NOT MakeLayer THEN Close;
end;

function  TMainForm.LoadBmp:boolean;
begin
  result:=false;
  try
    Surface.LoadFromFile('sample.bmp');
  except
    ON E:Exception DO BEGIN
      ShowMessage(E.Message);  Exit;
    END;
  end;
  IF Surface.PixelFormat<>pf32bit THEN BEGIN
    ShowMessage('not 32bit?'); Exit;
  END;
  result:=true;
end;

function TMainForm.MakeLayer:boolean;
var
  bf : TBlendFunction;
  zerop : TPoint;
  formsz : TSize;
begin
  result:=false;
  WITH bf DO BEGIN
    BlendOp:=AC_SRC_OVER;
    BlendFlags:=0;
    SourceConstantAlpha:=255; // 完全にALPHAをBITMAPに依存する場合
    AlphaFormat:=AC_SRC_ALPHA;
  END;
  zerop.x:=0; zerop.y:=0;
  formsz.cx:=width; formsz.cy:=height;
  IF NOT UpdateLayeredWindow(
        handle, 0,
        nil, // palleteを気にしないならnilでよろし
        @formsz, // フォームの大きさの指定 : 必須!
        Surface.canvas.handle, // サーフェイスを定義するDC
        @zerop, // サーフェイスを定義する画像の開始点
        0, bf, ULW_ALPHA) THEN BEGIN
    ShowMessage(SysErrorMessage(GetLastError));
    Exit;
  END;
  result:=true;
end;

形の元となるビットマップは、以下のことに気をつけてください。
R=255, G=127, B=63 の点を ALPHA=100(0なら透明、255なら不透明)
で抜きたいときは、32BIT BITMAPのその点のデータを
 R = 255 * 100 div 255 = 100
  G = 127 * 100 div 255 =  49
  B =  63 * 100 div 255 =  24
  Alpha = 100
にしてください。単純にR=255,G=127,B=63,ALPHA=100としても予期
した形で描画されません(しばらく私はこれで嵌ってました)。

                      市丸 剛(HGD00106)


 


- FDELPHI  MES(16):玉石混淆みんなで作るSample蔵【見本蓄積】 00/12/31 -

Original document by 市丸 剛    氏 ID:(HGD00106)


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum