1.新建一个MFC项目,如图所示
2.在设计视图右键对话框,选择属性选项并设置窗口属性,如下图所示
3.CTRL+S保存(养成良好的保存数据的习惯,能有效避免错误的发生机率)
4.将资源图片导入,素材图片要准备两张,一张为背景图"Background.bmp",另一张"Border.bmp"是"Background.bmp"的边框图.如下图所示
找到刚刚复制进去的res文件夹打开
选中第一副图,点打开按钮
继续按照上述方法添加另外一张图
两张图片都导入后可以展开节点看到如下效果!
CTRL+S 保存,好习惯啊
5.切换到"解决方案资源管理器"选项卡,双击展开"头文件"节点,双击TestBorder.Dlg.h打开,如下图
6.在"public:"与" CTestBorderDlg(CWnd* pParent = NULL); "中间插入一行,添加如下代码:
- HRGN BitmapToRegion(HBITMAP hBmp, COLORREF cTransparentColor, COLORREF cTolerance=NULL);
添加后效果如图所示,记得CTRL+S保存
7.找到"类视图"选项卡,双击打开"OnInitDialog()",在指定位置处添加如下代码并保存.
- CBitmap bmp;
- if(bmp.LoadBitmap(IDB_BITMAP2))
- {
- HRGN rgn;
- rgn = BitmapToRegion((HBITMAP)bmp, RGB(0,0,0));
- SetWindowRgn(rgn, TRUE);
- bmp.DeleteObject();
- }
.如图所示
8.双击打开"OnPaint()"在指定位置处增加如下代码,并保存
- CClientDC dc(this);
- CDC memDC;
- memDC.CreateCompatibleDC(&dc);
- CBitmap bmp;
- bmp.LoadBitmap(IDB_BITMAP1);
- CBitmap *pOldBmp;
- pOldBmp = memDC.SelectObject(&bmp);
- BITMAP bm;
- bmp.GetBitmap(&bm);
- dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCCOPY);
- memDC.SelectObject(pOldBmp);
- bmp.DeleteObject();
9.拖动滚动条到代码最底部,添加如下代码,并保存
- HRGN CTestBorderDlg::BitmapToRegion(HBITMAP hBmp, COLORREF cTransparentColor, COLORREF cTolerance)
- {
- HRGN hRgn = NULL;
- if (hBmp)
- {
- HDC hMemDC = CreateCompatibleDC(NULL);
- if (hMemDC)
- {
- BITMAP bm;
- GetObject(hBmp, sizeof(bm), &bm);
- //创建一个32位色的位图,并选进内存设备环境
- BITMAPINFOHEADER RGB32BITSBITMAPINFO = {
- sizeof(BITMAPINFOHEADER), // biSize
- bm.bmWidth, // biWidth;
- bm.bmHeight, // biHeight;
- 1, // biPlanes;
- 32, // biBitCount
- BI_RGB, // biCompression;
- 0, // biSizeImage;
- 0, // biXPelsPerMeter;
- 0, // biYPelsPerMeter;
- 0, // biClrUsed;
- 0 // biClrImportant;
- };
- VOID * pbits32;
- HBITMAP hbm32 = CreateDIBSection(hMemDC,(BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0);
- if (hbm32)
- {
- HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);
- // Create a DC just to copy the bitmap into the memory DC
- HDC hDC = CreateCompatibleDC(hMemDC);
- if (hDC)
- {
- // Get how many bytes per row we have for the bitmap bits (rounded up to 32 bits)
- BITMAP bm32;
- GetObject(hbm32, sizeof(bm32), &bm32);
- while (bm32.bmWidthBytes % 4)
- bm32.bmWidthBytes++;
- // Copy the bitmap into the memory DC
- HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
- BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY);
- // For better performances, we will use the ExtCreateRegion() function to create the
- // region. This function take a RGNDATA structure on entry. We will add rectangles by
- // amount of ALLOC_UNIT number in this structure.
- #define ALLOC_UNIT 100
- DWORD maxRects = ALLOC_UNIT;
- HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
- RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
- pData->rdh.dwSize = sizeof(RGNDATAHEADER);
- pData->rdh.iType = RDH_RECTANGLES;
- pData->rdh.nCount = pData->rdh.nRgnSize = 0;
- SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
- // Keep on hand highest and lowest values for the "transparent" pixels
- BYTE lr = GetRValue(cTransparentColor);
- BYTE lg = GetGValue(cTransparentColor);
- BYTE lb = GetBValue(cTransparentColor);
- BYTE hr = min(0xff, lr + GetRValue(cTolerance));
- BYTE hg = min(0xff, lg + GetGValue(cTolerance));
- BYTE hb = min(0xff, lb + GetBValue(cTolerance));
- // Scan each bitmap row from bottom to top (the bitmap is inverted vertically)
- BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes;
- for (int y = 0; y < bm.bmHeight; y++)
- {
- // Scan each bitmap pixel from left to right
- for (int x = 0; x < bm.bmWidth; x++)
- {
- // Search for a continuous range of "non transparent pixels"
- int x0 = x;
- LONG *p = (LONG *)p32 + x;
- while (x < bm.bmWidth)
- {
- BYTE b = GetRValue(*p);
- if (b >= lr && b <= hr)
- {
- b = GetGValue(*p);
- if (b >= lg && b <= hg)
- {
- b = GetBValue(*p);
- if (b >= lb && b <= hb)
- // This pixel is "transparent"
- break;
- }
- }
- p++;
- x++;
- }
- if (x > x0)
- {
- // Add the pixels (x0, y) to (x, y+1) as a new rectangle in the region
- if (pData->rdh.nCount >= maxRects)
- {
- GlobalUnlock(hData);
- maxRects += ALLOC_UNIT;
- hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
- pData = (RGNDATA *)GlobalLock(hData);
- }
- RECT *pr = (RECT *)&pData->Buffer;
- SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
- if (x0 < pData->rdh.rcBound.left)
- pData->rdh.rcBound.left = x0;
- if (y < pData->rdh.rcBound.top)
- pData->rdh.rcBound.top = y;
- if (x > pData->rdh.rcBound.right)
- pData->rdh.rcBound.right = x;
- if (y+1 > pData->rdh.rcBound.bottom)
- pData->rdh.rcBound.bottom = y+1;
- pData->rdh.nCount++;
- // On Windows98, ExtCreateRegion() may fail if the number of rectangles is too
- // large (ie: > 4000). Therefore, we have to create the region by multiple steps.
- if (pData->rdh.nCount == 2000)
- {
- HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
- if (hRgn)
- {
- CombineRgn(hRgn, hRgn, h, RGN_OR);
- DeleteObject(h);
- }
- else
- hRgn = h;
- pData->rdh.nCount = 0;
- SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
- }
- }
- }
- // Go to next row (remember, the bitmap is inverted vertically)
- p32 -= bm32.bmWidthBytes;
- }
- // Create or extend the region with the remaining rectangles
- HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
- if (hRgn)
- {
- CombineRgn(hRgn, hRgn, h, RGN_OR);
- DeleteObject(h);
- }
- else
- hRgn = h;
- // Clean up
- GlobalFree(hData);
- SelectObject(hDC, holdBmp);
- DeleteDC(hDC);
- }
- DeleteObject(SelectObject(hMemDC, holdBmp));
- }
- DeleteDC(hMemDC);
- }
- }
- return hRgn;
- }
10.打开"资源视图"选项卡,选择Dialog节点并双击展开,选择IDD_TESTBORDER_DIALOG并双击打开
右键->属性->"属性"选项卡中选择红色方框的按钮,下拉滚动条找到"WM_NCHITTEST"点右面的编辑区,弹出下拉列表后选择"<Add> OnNcHitTest"
将图1中所示代码替换为图2的代码.CTRL+S保存
图1:
图2:
再次打开"资源视图"选项卡,选择Dialog节点并双击展开,选择IDD_TESTBORDER_DIALOG并双击打开
删除对话框中的三个控件,如图所示
调整一下对话框的尺寸,以便于完全显示图片
CTRL+S保存,F5运行即可看到如下图所示的最终效果图.(提示:此装口可直接按ESC键关闭)
附件为素材图片
源代码下载地址:http://www.vdisk.cn/down/index/9369459A5242