まあこんなことをやらずとも、素直にイメージリストコモンコントロール(VB付属のではなく、API関数の方ね)を使った方が、描画も管理も簡単だが、昔、遊びで書いたソースが出てきたので書いておく。
はっきり言ってよく分からないコードになっている。OSによっては動かないかもしれない。
Private Type ICONINFO fIcon As Long xHotspot As Long yHotspot As Long hbmMask As Long hbmColor As Long End Type Private Type BITMAP bmType As Long bmWidth As Long bmHeight As Long bmWidthBytes As Long bmPlanes As Integer bmBitsPixel As Integer bmBits As Long End Type
'デバイスコンテキストを取得する
'デバイスコンテキストを解放する
'メモリ互換のデバイスコンテキストを作成する
'画像ファイルを複製する
'オブジェクトの描画対象を設定・選択する
'指定したDCにあるBMPと互換のビットマップオブジェクトを作成する
'ビットマップを作成する
'背景色を設定する
'ビット転送する
'文字列の色を設定する
'アイコンに変換し、ハンドルを返す
'オブジェクトを破棄する
'デバイスコンテキストを破棄する
'オブジェクトを取得する
Private Const IMAGE_BITMAP = 0
'--------------------------------------------------------------------------- ' 関数名: CreateIconFromBitmap ' 機能 : ビットマップハンドルからアイコンを作る ' 引数 : (in)hBitmap … ビットマップハンドル ' 返り値: アイコンのハンドル '--------------------------------------------------------------------------- Public Function CreateIconFromBitmap(ByVal hBitmap As Long) As Long Dim hDesktopDC As Long 'デスクトップのデバイスコンテキスト Dim hDCColor&, hDCMask As Long '作成するデバイスコンテキスト Dim hNewColor&, hNewMask As Long '作成するイメージのハンドル Dim OldhNewColor&, OldhNewMask As Long '変更前のハンドル Dim udtICONINFO As ICONINFO Dim i As Long Dim ICON_WIDTH, ICON_HEIGHT As Long 'アイコンの幅・高さ ICON_WIDTH = 16: ICON_HEIGHT = 16 #If 1 Then Dim udtBITMAP As BITMAP 'ビットマップのサイズ取得 Call GetObject(hBitmap, Len(udtBITMAP), udtBITMAP) ICON_WIDTH = udtBITMAP.bmWidth ICON_HEIGHT = udtBITMAP.bmHeight #End If 'hDC取得 hDesktopDC = GetDC(0&) '転送先ビットマップ作成 hDCColor = CreateCompatibleDC(hDesktopDC) hNewColor = CopyImage(hBitmap, IMAGE_BITMAP, ICON_WIDTH, ICON_HEIGHT, 0&) OldhNewColor = SelectObject(hDCColor, hNewColor) 'マスク用ビットマップ作成 hDCMask = CreateCompatibleDC(hDesktopDC) hNewMask = CreateBitmap(ICON_WIDTH, ICON_HEIGHT, 1, 1, ByVal 0&) 'hNewMask = CreateCompatibleBitmap(hDCMask, IconWidth, IconWidth) OldhNewMask = SelectObject(hDCMask, hNewMask) '背景をマスクカラーに設定(無くても動く?) 'Call SetBkColor(hDCColor, MaskColor) '準備は整った!! マスク用にビットブリット発動!! 'WinNT系? Call BitBlt(hDCMask, 0, 0, ICON_WIDTH, ICON_HEIGHT, hDCColor, 0, 0, vbSrcCopy) 'Win95はこれで良かった↓ 'Call BitBlt(hDCMask, 0, 0, ICON_WIDTH, ICON_HEIGHT, hDCColor, 0, 0, vbSrcAnd) '転送先のビットマップを設定 Call SetBkColor(hDCColor, vbBlack) '背景セット Call SetTextColor(hDCColor, &HFFFFFF) '文字色セット 'マスク処理 Call BitBlt(hDCColor, 0, 0, ICON_WIDTH, ICON_HEIGHT, hDCMask, 0, 0, vbSrcAnd) 'オブジェクトを元に戻す Call SelectObject(hDCColor, OldhNewColor) Call SelectObject(hDCMask, OldhNewMask) 'アイコンの設定もしないとね With udtICONINFO .fIcon = True .xHotspot = 0 .yHotspot = 0 .hbmColor = hNewColor .hbmMask = hNewMask End With 'ビットマップ→アイコン変換 CreateIconFromBitmap = CreateIconIndirect(udtICONINFO) '後処理 Call DeleteObject(hNewColor) Call DeleteDC(hDCColor) Call DeleteObject(hNewMask) Call DeleteDC(hDCMask) Call ReleaseDC(0, hDesktopDC) End Function フォームの AutoRedraw プロパティを True にし、ボタンとピクチャーボックスを配置する。ピクチャーボックスには適当な16X16の画像を設定する。そうしたら以下のコードを書く。ボタンを押すと32×32サイズのアイコンが表示されるはず。 Private Declare Function DrawIcon Lib "user32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal hIcon As Long) As Long
Private Sub Command1_Click() Dim hIcon As Long hIcon = CreateIconFromBitmap(Picture1.Picture.handle) Call DrawIcon(Me.hdc, 0, 0, hIcon) Me.Refresh End Sub |