您的位置:首页 > 其它

创建异形窗口(总结)

2012-05-18 10:30 253 查看
根据图片创建不规则窗口

#define TRANS_COLOR         (ALPHA_MASK | RGB(255, 0, 255))

BOOL CMyDialog::OnInitDialog()
{
    CDialog::OnInitDialog();

    CRgn rgn;
    CreateRgnByImage(_T("MyImage.png"), rgn);
    SetWindowRgn(rgn, TRUE);

    return TRUE;
}

void CMyDialog::CreateRgnByImage(const CString &imageName, CRgn &rgn)
{
    Bitmap img(imageName);
    ASSERT(PixelFormat32bppARGB == img.GetPixelFormat());

    Rect rect(0, 0, img.GetWidth(), img.GetHeight());
    BitmapData data;
    img.LockBits(&rect, ImageLockModeRead, PixelFormat32bppARGB, &data);
    UINT *pData = static_cast<UINT*>(data.Scan0);

    rgn.CreateRectRgn(0, 0, 0, 0);

    CRgn tempRgn;
    for (UINT h = 0; h < data.Height; ++ h)
    {
        UINT w = 0;
        while(w < data.Width)
        {
            UINT leftX;
            while (w ++ < data.Width && TRANS_COLOR == *pData ++);
            leftX = w;
            while (w ++ < data.Width && TRANS_COLOR != *pData ++);

            tempRgn.CreateRectRgn(leftX, h, w - 1, h + 1);
            rgn.CombineRgn(&rgn, &tempRgn, RGN_OR);
            tempRgn.DeleteObject();
        }
    }

    img.UnlockBits(&data);
}
HRGN CAUShellDlg::CreateRgn(CBitmap &cBitmap, DWORD dwColorKey)
{
    CDC *pDC = this->GetDC();
    CDC memDC;
    //创建与传入DC兼容的临时DC
    memDC.CreateCompatibleDC(pDC);

    CBitmap *pOldMemBmp=NULL;
    //将位图选入临时DC
    pOldMemBmp=memDC.SelectObject(&cBitmap);

    CRgn wndRgn;
    //创建总的窗体区域,初始region为0
    wndRgn.CreateRectRgn(0,0,0,0);

    BITMAP bit;   
    cBitmap.GetBitmap (&bit);//取得位图参数,这里要用到位图的长和宽     

    int y;
    for(y=0; y <= bit.bmHeight; y++)
    {
        CRgn rgnTemp;
        int iX = 0;
        do
        {
            //跳过透明色找到下一个非透明色的点.
            while (iX <= bit.bmWidth  && memDC.GetPixel(iX, y) == dwColorKey)
                iX++;
            //记住这个起始点
            int iLeftX = iX;
            //寻找下个透明色的点
            while (iX <= bit.bmWidth  && memDC.GetPixel(iX, y) != dwColorKey)
                ++iX;
            //创建一个包含起点与重点间高为1像素的临时“region”
            rgnTemp.CreateRectRgn(iLeftX, y, iX, y+1);
            //合并到主"region".
            wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_OR);
            //删除临时"region",否则下次创建时和出错
            rgnTemp.DeleteObject();
        } while(iX < bit.bmWidth );
        iX = 0;
    }

    if(pOldMemBmp)
        memDC.SelectObject(pOldMemBmp);

    CWnd * pWnd = pDC->GetWindow();
    pWnd->SetWindowRgn(wndRgn, TRUE); 
    return wndRgn;
}

以上两种方法差不多,但可能在性能上有所差距

Reference: Windows 中不规则窗体的编程实现点击打开链接

以BMP图片为蓝本创建不规则窗口 http://blog.csdn.net/ninsun/article/details/4826557
VC2010 MFC 使用图片***不规则外形窗口http://xiaoyu611.blog.51cto.com/3560086/752705


Converting a bitmap to a region

http://www.codeguru.com/cpp/g-m/bitmap/usingregions/article.php/c1751/Converting-a-bitmap-to-a-region.htm

http://gc.nuaa.edu.cn/ec/Articles/25.pdf
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: