< タイトルバーのないウインドウのドラッグ | error C2275 : typedef 識別子に、クラス メンバ アクセス演算子 (->) を使用しました。 >

January 21, 2006

アイコンの不透明部分のリージョンを作成する

アイコン型のウインドウを作成したかったのです。それには、アイコンのマスク部分を取得して、マスクの不透明部分の形のウインドウリージョンを作って設定します。

リージョン作成部分は続きの方にかいときますが、ウインドウプロシージャはこんな感じ。

LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_PAINT:
        PAINTSTRUCT PaintStruct;
        HDC hDC = BeginPaint (hWnd, &PaintStruct);
        DrawIcon (hDC, 0, 0, m_hIcon);
        EndPaint (hWnd, &PaintStruct);
        break;
    case WM_MOVE:
        SetWindowRgn (hWnd, m_hRgn, TRUE);
        break;
    default:
        break;
    }
    return DefWindowProc (hWnd, uMsg, wParam, lParam);
}

説明が前後しますが、ウインドウ作成時にウインドウに描画するアイコンを m_hIcon 仁読み込んであります。同時に、そのアイコンハンドルを渡して後述の CreateRgnFromIcon (HICON) を呼びだし、m_hRgn にアイコンのマスク部分の形のリージョンを得てあります。では、その CreateRgnFromIcon 関数です。

HRGN CreateRgnFromIcon (HICON hIcon)
{
    HRGN hRgnRet = NULL;    // 完成したリージョンを格納する
    
    // アイコンの情報を取り出します。
    ICONINFO IconInfo;
    ZeroMemory (&IconInfo, sizeof (ICONINFO));
    if (GetIconInfo (hIcon, &IconInfo))
    {
        // アイコン情報にマスクビットマップのハンドルが含まれるため、
        // そこからビットマップを取得します。
        BITMAP MaskBitmap;
        ZeroMemory (&MaskBitmap, sizeof (BITMAP));
        int nBytes = GetObject (IconInfo.hbmMask, sizeof (BITMAP), &MaskBitmap);
        if (nBytes)
        {
            // DC を作成します。
            // 引数に NULL を指定しているので、現在の画面と互換性のある DC が作成されます。
            // マスクビットマップは2値なので、何でもいいです。
            HDC hDC = CreateCompatibleDC (NULL);
            if (hDC)
            {
                // マスクビットマップを DC に選択します。
                HBITMAP hBmpOld = (HBITMAP) SelectObject (hDC, static_cast <HGDIOBJ> (IconInfo.hbmMask));
                if (hBmpOld)
                {
                    // 空のリージョンを作成します。
                    HRGN hRgn1px = CreateRectRgn (0, 0, 0, 0);
                    if (hRgn1px)
                    {// こちらも空のリージョンを作成します。
                        hRgnRet = CreateRectRgn (0, 0, 0, 0);
                        if (hRgnRet)
                        {
                            // マスクビットマップの各ピクセルの色を取得し、
                            // 黒いピクセルをリージョンに追加していきます。
                            for (int nYPos = 0; abs (MaskBitmap.bmHeight) > nYPos; nYPos ++)
                            {
                                for (int nXPos = 0; MaskBitmap.bmWidth > nXPos; nXPos ++)
                                {
                                    COLORREF clrPos = GetPixel (hDC, nXPos, nYPos);
                                    if (clrPos == 0x00000000)
                                    {
                                        SetRectRgn (hRgn1px, nXPos, nYPos, nXPos + 1, nYPos + 1);
                                        CombineRgn (hRgnRet, hRgnRet, hRgn1px, RGN_OR);
                                    }
                                }
                            }
                        }
                        DeleteObject (hRgn1px);
                    }
                    SelectObject (hDC, hBmpOld);
                }
                DeleteDC (hDC);
            }
        }
        DeleteObject (IconInfo.hbmColor);
        DeleteObject (IconInfo.hbmMask);
    }
    return hRgnRet;
}


トラックバック

このエントリーにトラックバック:
http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/1264

コメント

コメントする

※ コメントスパム対策のため、コメント本文はおはよう、こんにちわ、こんばんわのいずれかより始めるようにしてください。

name:
email:

※ 必要ですが、表示しません。

url:
情報を保存する ?