ホーム >プログラム >Delphi 6 ローテクTips

Windows APIメモ GetIconInfo

Windows APIのメモ。
GetIconInfo


type
  PIconInfo = ^TIconInfo;
  {$EXTERNALSYM _ICONINFO}
  _ICONINFO = packed record
    fIcon    : BOOL;
    xHotspot : DWORD;
    yHotspot : DWORD;
    hbmMask  : HBITMAP;
    hbmColor : HBITMAP;
  end;
  TIconInfo = _ICONINFO;
  {$EXTERNALSYM ICONINFO}
  ICONINFO = _ICONINFO;

function GetIconInfo(hIcon: HICON; var piconinfo: TIconInfo): BOOL; stdcall;

参考サイト

引用にあるようにGetIconInfo APIは二つのビットマップを作ります。
それがTIconInfo構造体のhbmMaskとhbmColorです。
このビットマップは使い終わったら削除しなければならないのですが、その責任はGetIconInfo APIを呼び出したアプリケーション側にあります。
ということでGetIconInfo APIを呼び出したら必ずDeleteObject APIを使ってこの二つのビットマップを解放しないとなりません。

サンプル

procedure gpcMouseCursorDraw(ABitmap : TBitmap; iX, iY : Integer);
//ABitmapのiXとiYの位置に現在のマウスカーソルを描画する
{ TODO : 2000でのマウスカーソルのキャプチャ }
var
  l_CursorInfo : TCursorInfo;
  l_IconInfo   : TIconInfo;
begin
  //http://q.hatena.ne.jp/1213429698
  //http://blog.tkooler.net/Entry/72/
  //http://ht-deko.minim.ne.jp/ft0202.html
  FillChar(l_CursorInfo, SizeOf(l_CursorInfo), 0);
  l_CursorInfo.cbSize := SizeOf(l_CursorInfo);
  GetCursorInfo(l_CursorInfo);

  FillChar(l_IconInfo, SizeOf(l_IconInfo), 0);
  l_IconInfo.fIcon := False; //取得するのはカーソル
  GetIconInfo(l_CursorInfo.hCursor, l_IconInfo);
  //https://msdn.microsoft.com/en-us/library/ms648070.aspx
  //2011-04-22:hbmMaskとhbmColorは解放しないとリソースが足りなくなる深刻なエラーに陥る
  DeleteObject(l_IconInfo.hbmMask);
  DeleteObject(l_IconInfo.hbmColor);

  if (l_CursorInfo.flags = CURSOR_SHOWING) then begin
    //カーソルは表示されている
    DrawIconEx(
      ABitmap.Canvas.Handle,
      iX - Integer(l_IconInfo.xHotspot),
      iY - Integer(l_IconInfo.yHotspot),
      l_CursorInfo.hCursor,
      GetSystemMetrics(SM_CXCURSOR),
      GetSystemMetrics(SM_CYCURSOR),
      0,
      0,
      DI_NORMAL
    );
  end;
end;