GDI/GDI+中只有对字体的外边框的测量,而没有提供对点,线,面,曲线的外边框获取函数。下面是本人利用DIB技术编写的探测简单图元,甚至也可以探测自己定义的复杂图元的外边矩形框的函数。本人已经测试,效果很棒。
bool GetFeatureRange(void *object, //自己定义的图元对象 CRect rect, // DIB屏幕大小 CDC *pDC, //绘图设置 CRect &retVal // 检测范围 ) { CDC memDC; //临时绘图设备 COLORREF bkcolor = RGB(255,255,255); // 背景色 //创建临时设备 memDC.CreateCompatibleDC(pDC); // 建立一个与屏幕显示相同大小的DIB位图 BITMAPINFO info; memset(&info.bmiHeader,0,sizeof(BITMAPINFOHEADER)); info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); info.bmiHeader.biWidth = rect.Width(); info.bmiHeader.biHeight = rect.Height(); info.bmiHeader.biPlanes = 1; info.bmiHeader.biBitCount = 32; info.bmiHeader.biCompression = BI_RGB; PVOID pBits; // 位图数据指针 HBITMAP hbitmap = CreateDIBSection(memDC.m_hDC,&info,DIB_RGB_COLORS, &pBits,0,0); HBITMAP hOldBitmap = (HBITMAP)memDC.SelectObject(hbitmap); // 使用背景色清除位图 memDC.FillSolidRect(0,0,rect.Width(), rect.Height(), bkcolor); // 绘制图元 object->Draw(...); // 还原位图 memDC.SelectObject(hOldBitmap); // 销毁临时绘图设备 memDC.DeleteDC(); // 获取位图信息 CBitmap *pBitmap = CBitmap::FromHandle(hbitmap); BITMAP bmp; pBitmap->GetBitmap(&bmp); BYTE *pixels = (BYTE*)bmp.bmBits; // 探测范围 bool bExist = false; // DIB存储方向有下至上 颜色存储形式BGR BYTE r,g,b; for(int i = 0; i < bmp.bmHeight; i++) { for(int j = 0; j < bmp.bmWidth; j++) { b = *(pixels++); g = *(pixels++); r = *(pixels++); pixels++; //跳过透明度 位图像素占32位字节 if(RGB(r,g,b) != bkcolor) { if(bExist){ retVal.top = i; if(retVal.left > j) retVal.left = j; if(retVal.right < j) retVal.right = j; } else { retVal.left = retVal.right = j; retVal.top = retVal.bottom = i; bExist = true; } } } } if(bExist) //调整与屏幕相同的坐标 { retVal.top = bmp.bmHeight - retVal.top; retVal.bottom = bmp.bmHeight - retVal.bottom; } pBitmap->DeleteObject(); return bExist; }