本文整理汇总了C++中CombineRgn函数的典型用法代码示例。如果您正苦于以下问题:C++ CombineRgn函数的具体用法?C++ CombineRgn怎么用?C++ CombineRgn使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了CombineRgn函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: bitmap2region
// Windows uses regions only to specify the clip mask of a window therefore
// we must convert our bitmap to a region.
// Much of this code is "borrowed" from the Windows version of GTK
// (also LGPLed). Their code was based on code originally written by
// Jean-Edouard Lachand-Robert. Ain't open source great?
//
// Modified by me to use an Fl_Bitmap, to not hog memory, to not leak memory
// (I hope) and to allow bitmaps of arbitrary dimensions. -CET
static HRGN bitmap2region(Fl_Bitmap* bitmap)
{
HRGN hRgn = 0;
/* 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;
RGNDATA* pData = (RGNDATA*)malloc(sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRects));
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);
// number of bytes per line of pixels
const int bpl = (bitmap->width()+7)/8;
BYTE* p8 = (BYTE*)bitmap->array;
BYTE* p;
for (int y = 0; y < bitmap->height(); y++)
{
/* Scan each bitmap row from left to right*/
for (int x = 0; x < bitmap->width(); x++)
{
/* Search for a continuous range of "non transparent pixels"*/
int x0 = x;
while (x < bitmap->width())
{
p = p8 + x / 8;
/* This pixel is "transparent"*/
if (!((*p) & bit(x))) break;
x++;
}
if (x > x0)
{
RECT* pr;
/* Add the pixels (x0, y) to (x, y+1) as a new rectangle
* in the region
*/
if (pData->rdh.nCount >= maxRects)
{
maxRects += ALLOC_UNIT;
pData = (RGNDATA*)realloc(pData, sizeof(RGNDATAHEADER)
+ (sizeof(RECT)*maxRects));
}
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 */
p8 += bpl;
}
/* 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;
//.........这里部分代码省略.........
示例2: CreateRgnFromBitmap
HRGN CreateRgnFromBitmap(CDC *pDC, int iWidth, int iHeight, COLORREF color)
{
const DWORD RDHDR = sizeof(RGNDATAHEADER);
const DWORD MAXBUF = 40; // size of one block in RECTs
// (i.e. MAXBUF*sizeof(RECT) in bytes)
LPRECT pRects;
DWORD cBlocks = 0; // number of allocated blocks
INT i, j; // current position in mask image
INT first = 0; // left position of current scan line
// where mask was found
bool wasfirst = false; // set when if mask was found in current scan line
bool ismask; // set when current color is mask color
// allocate memory for region data
RGNDATAHEADER* pRgnData = (RGNDATAHEADER*)new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ];
memset( pRgnData, 0, RDHDR + cBlocks * MAXBUF * sizeof(RECT) );
// fill it by default
pRgnData->dwSize = RDHDR;
pRgnData->iType = RDH_RECTANGLES;
pRgnData->nCount = 0;
for ( i = 0; i < iHeight; i++ )
for ( j = 0; j < iWidth; j++ ){
// get color
ismask=(pDC->GetPixel(j,iHeight-i-1)!=color);
// place part of scan line as RECT region if transparent color found after mask color or
// mask color found at the end of mask image
if (wasfirst && ((ismask && (j==(iWidth-1)))||(ismask ^ (j<iWidth)))){
// get offset to RECT array if RGNDATA buffer
pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
// save current RECT
pRects[ pRgnData->nCount++ ] = CRect( first, iHeight - i - 1, j+(j==(iWidth-1)), iHeight - i );
// if buffer full reallocate it
if ( pRgnData->nCount >= cBlocks * MAXBUF ){
LPBYTE pRgnDataNew = new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ];
memcpy( pRgnDataNew, pRgnData, RDHDR + (cBlocks - 1) * MAXBUF * sizeof(RECT) );
delete[] pRgnData;
pRgnData = (RGNDATAHEADER*)pRgnDataNew;
}
wasfirst = false;
} else if ( !wasfirst && ismask ){ // set wasfirst when mask is found
first = j;
wasfirst = true;
}
}
// create region
/* Under WinNT the ExtCreateRegion returns NULL (by [email protected]) */
// HRGN hRgn = ExtCreateRegion( NULL, RDHDR + pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData );
/* ExtCreateRegion replacement { */
HRGN hRgn=CreateRectRgn(0, 0, 0, 0);
ASSERT( hRgn!=NULL );
pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
for(i=0;i<(int)pRgnData->nCount;i++)
{
HRGN hr=CreateRectRgn(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom);
VERIFY(CombineRgn(hRgn, hRgn, hr, RGN_OR)!=ERROR);
if (hr) DeleteObject(hr);
}
ASSERT( hRgn!=NULL );
/* } ExtCreateRegion replacement */
delete[] pRgnData;
return hRgn;
}
示例3: SetBitmapBits
/******************************************************************************
* SetBitmapBits [[email protected]]
*
* Sets bits of color data for a bitmap.
*
* RETURNS
* Success: Number of bytes used in setting the bitmap bits
* Failure: 0
*/
LONG WINAPI SetBitmapBits(
HBITMAP hbitmap, /* [in] Handle to bitmap */
LONG count, /* [in] Number of bytes in bitmap array */
LPCVOID bits) /* [in] Address of array with bitmap bits */
{
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *info = (BITMAPINFO *)buffer;
BITMAPOBJ *bmp;
DWORD err;
int i, src_stride, dst_stride;
struct bitblt_coords src, dst;
struct gdi_image_bits src_bits;
HRGN clip = NULL;
if (!bits) return 0;
bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP );
if (!bmp) return 0;
if (count < 0) {
WARN("(%d): Negative number of bytes passed???\n", count );
count = -count;
}
src_stride = get_bitmap_stride( bmp->dib.dsBm.bmWidth, bmp->dib.dsBm.bmBitsPixel );
count = min( count, src_stride * bmp->dib.dsBm.bmHeight );
dst_stride = get_dib_stride( bmp->dib.dsBm.bmWidth, bmp->dib.dsBm.bmBitsPixel );
src.visrect.left = src.x = 0;
src.visrect.top = src.y = 0;
src.visrect.right = src.width = bmp->dib.dsBm.bmWidth;
src.visrect.bottom = src.height = (count + src_stride - 1 ) / src_stride;
dst = src;
if (count % src_stride)
{
HRGN last_row;
int extra_pixels = ((count % src_stride) << 3) / bmp->dib.dsBm.bmBitsPixel;
if ((count % src_stride << 3) % bmp->dib.dsBm.bmBitsPixel)
FIXME( "Unhandled partial pixel\n" );
clip = CreateRectRgn( src.visrect.left, src.visrect.top,
src.visrect.right, src.visrect.bottom - 1 );
last_row = CreateRectRgn( src.visrect.left, src.visrect.bottom - 1,
src.visrect.left + extra_pixels, src.visrect.bottom );
CombineRgn( clip, clip, last_row, RGN_OR );
DeleteObject( last_row );
}
TRACE("(%p, %d, %p) %dx%d %d bpp fetched height: %d\n",
hbitmap, count, bits, bmp->dib.dsBm.bmWidth, bmp->dib.dsBm.bmHeight,
bmp->dib.dsBm.bmBitsPixel, src.height );
if (src_stride == dst_stride)
{
src_bits.ptr = (void *)bits;
src_bits.is_copy = FALSE;
src_bits.free = NULL;
}
else
{
if (!(src_bits.ptr = HeapAlloc( GetProcessHeap(), 0, dst.height * dst_stride )))
{
GDI_ReleaseObj( hbitmap );
return 0;
}
src_bits.is_copy = TRUE;
src_bits.free = free_heap_bits;
for (i = 0; i < count / src_stride; i++)
memcpy( (char *)src_bits.ptr + i * dst_stride, (char *)bits + i * src_stride, src_stride );
if (count % src_stride)
memcpy( (char *)src_bits.ptr + i * dst_stride, (char *)bits + i * src_stride, count % src_stride );
}
/* query the color info */
info->bmiHeader.biSize = sizeof(info->bmiHeader);
info->bmiHeader.biPlanes = 1;
info->bmiHeader.biBitCount = bmp->dib.dsBm.bmBitsPixel;
info->bmiHeader.biCompression = BI_RGB;
info->bmiHeader.biXPelsPerMeter = 0;
info->bmiHeader.biYPelsPerMeter = 0;
info->bmiHeader.biClrUsed = 0;
info->bmiHeader.biClrImportant = 0;
info->bmiHeader.biWidth = 0;
info->bmiHeader.biHeight = 0;
info->bmiHeader.biSizeImage = 0;
err = put_image_into_bitmap( bmp, 0, info, NULL, NULL, NULL );
if (!err || err == ERROR_BAD_FORMAT)
{
//.........这里部分代码省略.........
示例4: GetDC
HRGN CTaskbarNotifier::CreateRgnFromBitmap(HBITMAP hBmp, COLORREF color)
{
if (!hBmp)
return NULL;
CDC* pDC = GetDC();
if (!pDC)
return NULL;
BITMAP bm;
GetObject( hBmp, sizeof(BITMAP), &bm ); // get bitmap attributes
CDC dcBmp;
dcBmp.CreateCompatibleDC(pDC); //Creates a memory device context for the bitmap
HGDIOBJ hOldBmp = dcBmp.SelectObject(hBmp); //selects the bitmap in the device context
const DWORD RDHDR = sizeof(RGNDATAHEADER);
const DWORD MAXBUF = 40; // size of one block in RECTs
// (i.e. MAXBUF*sizeof(RECT) in bytes)
LPRECT pRects;
DWORD cBlocks = 0; // number of allocated blocks
INT i, j; // current position in mask image
INT first = 0; // left position of current scan line
// where mask was found
bool wasfirst = false; // set when if mask was found in current scan line
bool ismask; // set when current color is mask color
// allocate memory for region data
RGNDATAHEADER* pRgnData = (RGNDATAHEADER*)new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ];
memset( pRgnData, 0, RDHDR + cBlocks * MAXBUF * sizeof(RECT) );
// fill it by default
pRgnData->dwSize = RDHDR;
pRgnData->iType = RDH_RECTANGLES;
pRgnData->nCount = 0;
for ( i = 0; i < bm.bmHeight; i++ )
for ( j = 0; j < bm.bmWidth; j++ ){
// get color
ismask=(dcBmp.GetPixel(j,bm.bmHeight-i-1)!=color);
// place part of scan line as RECT region if transparent color found after mask color or
// mask color found at the end of mask image
if (wasfirst && ((ismask && (j==(bm.bmWidth-1)))||(ismask ^ (j<bm.bmWidth)))){
// get offset to RECT array if RGNDATA buffer
pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
// save current RECT
pRects[ pRgnData->nCount++ ] = CRect( first, bm.bmHeight - i - 1, j+(j==(bm.bmWidth-1)), bm.bmHeight - i );
// if buffer full reallocate it
if ( pRgnData->nCount >= cBlocks * MAXBUF ){
LPBYTE pRgnDataNew = new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ];
memcpy( pRgnDataNew, pRgnData, RDHDR + (cBlocks - 1) * MAXBUF * sizeof(RECT) );
delete[] pRgnData;
pRgnData = (RGNDATAHEADER*)pRgnDataNew;
}
wasfirst = false;
} else if ( !wasfirst && ismask ){ // set wasfirst when mask is found
first = j;
wasfirst = true;
}
}
dcBmp.SelectObject(hOldBmp);
dcBmp.DeleteDC(); //release the bitmap
// create region
/* Under WinNT the ExtCreateRegion returns NULL (by [email protected]) */
// HRGN hRgn = ExtCreateRegion( NULL, RDHDR + pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData );
/* ExtCreateRegion replacement { */
HRGN hRgn=CreateRectRgn(0, 0, 0, 0);
ASSERT( hRgn!=NULL );
pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
for(i=0;i<(int)pRgnData->nCount;i++)
{
HRGN hr=CreateRectRgn(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom);
VERIFY(CombineRgn(hRgn, hRgn, hr, RGN_OR)!=ERROR);
if (hr) DeleteObject(hr);
}
ASSERT( hRgn!=NULL );
/* } ExtCreateRegion replacement */
delete[] pRgnData;
ReleaseDC(pDC);
return hRgn;
}
示例5: RecalculateFrameSizes
LRESULT CFrameHolder::OnNcPaint(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
RecalculateFrameSizes();
if (!gpSet->isTabsInCaption)
{
LRESULT lRc = DefWindowProc(hWnd, uMsg, wParam, lParam);
return lRc;
}
FrameDrawStyle fdt = gpConEmu->DrawType();
if (fdt == fdt_Aero || fdt == fdt_Win8)
{
LRESULT lRc = DefWindowProc(hWnd, uMsg, wParam, lParam);
//TODO: Может быть на "стекле" сразу рисовать, а не в WM_PAINT?
return lRc;
}
if (!gpSet->isTabs)
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
RECT dirty_box, dirty, wr = {}, tr = {}, cr = {}, xorRect;
BOOL fRegionOwner = FALSE;
HDC hdc;
HRGN hrgn = (HRGN)wParam;
GetWindowRect(hWnd, &wr);
CalculateCaptionPosition(wr, &cr);
CalculateTabPosition(wr, cr, &tr);
// --- Регион формируем всегда сами, иначе в некоторых случаях (XP+ Theming)
// --- при выезжании окна из-за пределов экрана (обратно в видимую область)
// --- сильно мелькает текст в заголовке
//Create a region which covers the whole window. This
//must be in screen coordinates
//if(TRUE || hrgn == (HRGN)1 || hrgn == NULL)
{
hrgn = CreateRectRgnIndirect(&wr);
dirty_box = wr;
fRegionOwner = TRUE;
//#ifdef _DEBUG
// wchar_t szDbg[255];
// wsprintf(szDbg, L"CFrameHolder::OnNcPaint - New region({%ix%i}-{%ix%i})\n", wr.left,wr.top,wr.right,wr.bottom);
// OutputDebugStringW(szDbg);
//#endif
}
//else
//{
// GetRgnBox((HRGN)wParam, &dirty_box);
// #ifdef _DEBUG
// wchar_t szDbg[255];
// wsprintf(szDbg, L"CFrameHolder::OnNcPaint - Existing region({%ix%i}-{%ix%i})\n", dirty_box.left,dirty_box.top,dirty_box.right,dirty_box.bottom);
// OutputDebugStringW(szDbg);
// #endif
//}
xorRect = tr;
xorRect.top = cr.top;
if (gpConEmu->DrawType() == fdt_Aero)
{
}
else if (gpConEmu->DrawType() == fdt_Themed)
{
xorRect.left = cr.left;
xorRect.right = cr.right;
}
else
{
xorRect.left = cr.left;
//xorRect.right = cr.right;
}
OffsetRect(&xorRect, wr.left, wr.top);
if (IntersectRect(&dirty, &dirty_box, &xorRect))
{
// This must be in screen coordinates
HRGN hrgn1 = CreateRectRgnIndirect(&xorRect);
//Cut out a button-shaped hole
CombineRgn(hrgn, hrgn, hrgn1, RGN_XOR);
DeleteObject(hrgn1);
}
//#ifdef _DEBUG
//else
//{
// OutputDebugStringW(L"CFrameHolder::OnNcPaint --- IntersectRect failed\n");
//}
//#endif
//if (!mb_NcAnimate)
DefWindowProc(hWnd, uMsg, (WPARAM)hrgn, lParam);
//.........这里部分代码省略.........
示例6: MainWindowProc
static LRESULT CALLBACK
MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
CvWindow* window = icvWindowByHWND( hwnd );
if( !window )
return DefWindowProc(hwnd, uMsg, wParam, lParam);
switch(uMsg)
{
case WM_DESTROY:
icvRemoveWindow(window);
// Do nothing!!!
//PostQuitMessage(0);
break;
case WM_GETMINMAXINFO:
if( !(window->flags & CV_WINDOW_AUTOSIZE) )
{
MINMAXINFO* minmax = (MINMAXINFO*)lParam;
RECT rect;
LRESULT retval = DefWindowProc(hwnd, uMsg, wParam, lParam);
minmax->ptMinTrackSize.y = 100;
minmax->ptMinTrackSize.x = 100;
if( window->toolbar.first )
{
GetWindowRect( window->toolbar.first->hwnd, &rect );
minmax->ptMinTrackSize.y += window->toolbar.rows*(rect.bottom - rect.top);
minmax->ptMinTrackSize.x = MAX(rect.right - rect.left + HG_BUDDY_WIDTH, HG_BUDDY_WIDTH*2);
}
return retval;
}
break;
case WM_WINDOWPOSCHANGED:
{
WINDOWPOS* pos = (WINDOWPOS*)lParam;
// Update the toolbar position/size
if(window->toolbar.toolbar)
{
RECT rect;
GetWindowRect(window->toolbar.toolbar, &rect);
MoveWindow(window->toolbar.toolbar, 0, 0, pos->cx, rect.bottom - rect.top, TRUE);
}
if(!(window->flags & CV_WINDOW_AUTOSIZE))
icvUpdateWindowPos(window);
break;
}
case WM_ACTIVATE:
if(LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE)
SetFocus(window->hwnd);
break;
case WM_ERASEBKGND:
{
RECT cr, tr, wrc;
HRGN rgn, rgn1, rgn2;
int ret;
HDC hdc = (HDC)wParam;
GetWindowRect(window->hwnd, &cr);
icvScreenToClient(window->frame, &cr);
if(window->toolbar.toolbar)
{
GetWindowRect(window->toolbar.toolbar, &tr);
icvScreenToClient(window->frame, &tr);
}
else
tr.left = tr.top = tr.right = tr.bottom = 0;
GetClientRect(window->frame, &wrc);
rgn = CreateRectRgn(0, 0, wrc.right, wrc.bottom);
rgn1 = CreateRectRgn(cr.left, cr.top, cr.right, cr.bottom);
rgn2 = CreateRectRgn(tr.left, tr.top, tr.right, tr.bottom);
ret = CombineRgn(rgn, rgn, rgn1, RGN_DIFF);
ret = CombineRgn(rgn, rgn, rgn2, RGN_DIFF);
if(ret != NULLREGION && ret != ERROR)
FillRgn(hdc, rgn, (HBRUSH)icvGetClassLongPtr(hwnd, CV_HBRBACKGROUND));
DeleteObject(rgn);
DeleteObject(rgn1);
DeleteObject(rgn2);
}
return 1;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
示例7: RWOpenThemeData
//
//******************************************************************
// Function Name : OnNcPaint
// Function : QA: 32574
// Param : HRGN hrgnUpdate
// Return : LRESULT
// Create :
// Update : ±èÁ¤¹®, 2009/10/09 VS 2008 Upgrade¸¦ À§ÇÑ ÀÛ¾÷
// Comment :
//******************************************************************
LRESULT SECTreeCtrl::OnNcPaint(HRGN hrgnUpdate)
{
if(!m_hTreeTheme)
{
#ifndef __RWUXTHEME_H
m_hTreeTheme = RWOpenThemeData(m_hWnd, L"TREEVIEW");
#endif
}
if(m_hTreeTheme)
{
//---------------------//
// Draw Themed Border //
//---------------------//
HDC hdc = ::GetWindowDC(m_hWnd);
RECT rc;
RECT rcWindow;
DWORD state = ETS_NORMAL;
HRGN hrgnClip;
// State
if(!::IsWindowEnabled(this->GetSafeHwnd()))
{
state = ETS_DISABLED;
}else if(GetFocus() == this->GetParent())
{
state = ETS_HOT;
}else
{
state = ETS_NORMAL;
}
// Rect mapping
::GetWindowRect(m_hWnd, &rcWindow);
::GetClientRect(m_hWnd, &rc);
::ClientToScreen(m_hWnd, (POINT *)&rc.left);
::ClientToScreen(m_hWnd, (POINT *)&rc.right);
rc.right = rcWindow.right - (rc.left - rcWindow.left);
rc.bottom = rcWindow.bottom - (rc.top - rcWindow.top);
// Region
hrgnClip = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
if(hrgnUpdate != (HRGN)1)
CombineRgn(hrgnClip, hrgnClip, hrgnUpdate, RGN_AND);
OffsetRect(&rc, -rcWindow.left, -rcWindow.top);
ExcludeClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);
OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
//if (IsThemeBackgroundPartiallyTransparent (m_hTreeTheme, TVP_TREEITEM, state))
//RWDrawThemeParentBackground(m_hWnd, hdc, &rcWindow);
#ifndef __RWUXTHEME_H
RWDrawThemeBackground(m_hTreeTheme, hdc,
TVP_TREEITEM,
state,
&rcWindow, NULL);
#endif
::ReleaseDC(m_hWnd, hdc);
}
return 0;
}
示例8: ReorderWindows
void ReorderWindows(ATTACHED_WINDOWS& atws, int& bRedraw, int &redo, HWND hParent)
{
std::vector<HWND_DEPENDENCY> dependencies;
redo = 0;
std::vector<ATTACHED_WINDOW>::iterator atw = atws.begin();
HRGN rgn_final = CreateRectRgn(0,0,0,0);
/* iterate through all attachments */
for (; atw != atws.end(); atw++) {
HWND_DEPENDENCY hwnd_dependency;
hwnd_dependency.hWnd = atw->hWnd;
RECT r_dest;
GetWindowRect(atw->hWnd, &r_dest);
int w_dest = r_dest.right - r_dest.left;
int h_dest = r_dest.bottom - r_dest.top;
if (atw->flags & ATTB_WIDTHRATIO) {
RECT r;
GetWindowRect(atw->hWndWidth, &r);
int _w_dest = (int)((float)(r.right - r.left) * atw->width_ratio);
if (_w_dest != w_dest) {
hwnd_dependency.hWnd_depends_on.push_back(atw->hWndWidth);
redo = 1;
w_dest = _w_dest;
}
}
if (atw->flags & ATTB_HEIGHTRATIO) {
RECT r;
GetWindowRect(atw->hWndHeight, &r);
int _h_dest = (int)((float)(r.bottom - r.top) * atw->height_ratio);
if (h_dest != _h_dest) {
hwnd_dependency.hWnd_depends_on.push_back(atw->hWndHeight);
h_dest = _h_dest;
redo = 1;
}
}
bool keep_width = (atw->flags & ATTB_LEFTRIGHT) != ATTB_LEFTRIGHT;
bool keep_height = (atw->flags & ATTB_TOPBOTTOM) != ATTB_TOPBOTTOM;
ScreenToClient(hParent, &r_dest);
RECT r_old = r_dest;
HRGN rgn_old = CreateRectRgn(r_dest.left, r_dest.top, r_dest.right - 2, r_dest.bottom - 2);
HRGN rgn_upd = CreateRectRgn(0,0,0,0);
// obtain border region
HRGN rgn_border = CreateRectRgn(0,0,0,0);
bool bError = false;
if (rgn_old == ERROR || rgn_upd == ERROR || rgn_border == ERROR)
bError = true;
RECT r_client;
GetClientRect(atw->hWnd, &r_client);
ClientToScreen(atw->hWnd, &r_client);
ScreenToClient(hParent, &r_client);
HRGN rgn_clt = CreateRectRgn(r_client.left, r_client.top, r_client.right, r_client.bottom);
if (rgn_clt == ERROR)
bError = true;
if (CombineRgn(rgn_border, rgn_clt, rgn_old, RGN_XOR) == ERROR)
bError = true;
std::vector<ATTACHED_BORDER>::iterator atb = atw->attached_borders.begin();
for (; atb != atw->attached_borders.end(); atb++) {
RECT r_source;
GetWindowRect(atb->hWndAttachedTo, &r_source);
ScreenToClient(hParent, &r_source);
int value1 = -1;
int value2 = -1;
LONG* target1 = NULL;
LONG* target2 = NULL;
switch (atb->border) {
case ATTB_LEFT:
case ATTB_HCENTER:
target1 = &r_dest.left;
if (keep_width)
target2 = &r_dest.right;
break;
case ATTB_RIGHT:
target1 = &r_dest.right;
if (keep_width)
target2 = &r_dest.left;
break;
case ATTB_TOP:
case ATTB_VCENTER:
target1 = &r_dest.top;
if (keep_height)
target2 = &r_dest.bottom;
break;
//.........这里部分代码省略.........
示例9: get_region_hrgn
static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *graphics, HRGN *hrgn)
{
switch (element->type)
{
case RegionDataInfiniteRect:
*hrgn = NULL;
return Ok;
case RegionDataEmptyRect:
*hrgn = CreateRectRgn(0, 0, 0, 0);
return *hrgn ? Ok : OutOfMemory;
case RegionDataPath:
return get_path_hrgn(element->elementdata.path, graphics, hrgn);
case RegionDataRect:
{
GpPath* path;
GpStatus stat;
GpRectF* rc = &element->elementdata.rect;
stat = GdipCreatePath(FillModeAlternate, &path);
if (stat != Ok)
return stat;
stat = GdipAddPathRectangle(path, rc->X, rc->Y, rc->Width, rc->Height);
if (stat == Ok)
stat = get_path_hrgn(path, graphics, hrgn);
GdipDeletePath(path);
return stat;
}
case CombineModeIntersect:
case CombineModeUnion:
case CombineModeXor:
case CombineModeExclude:
case CombineModeComplement:
{
HRGN left, right;
GpStatus stat;
int ret;
stat = get_region_hrgn(element->elementdata.combine.left, graphics, &left);
if (stat != Ok)
{
*hrgn = NULL;
return stat;
}
if (left == NULL)
{
/* existing region is infinite */
switch (element->type)
{
case CombineModeIntersect:
return get_region_hrgn(element->elementdata.combine.right, graphics, hrgn);
case CombineModeXor: case CombineModeExclude:
left = CreateRectRgn(-4194304, -4194304, 4194304, 4194304);
break;
case CombineModeUnion: case CombineModeComplement:
*hrgn = NULL;
return Ok;
}
}
stat = get_region_hrgn(element->elementdata.combine.right, graphics, &right);
if (stat != Ok)
{
DeleteObject(left);
*hrgn = NULL;
return stat;
}
if (right == NULL)
{
/* new region is infinite */
switch (element->type)
{
case CombineModeIntersect:
*hrgn = left;
return Ok;
case CombineModeXor: case CombineModeComplement:
right = CreateRectRgn(-4194304, -4194304, 4194304, 4194304);
break;
case CombineModeUnion: case CombineModeExclude:
DeleteObject(left);
*hrgn = NULL;
return Ok;
}
}
switch (element->type)
{
case CombineModeIntersect:
ret = CombineRgn(left, left, right, RGN_AND);
break;
case CombineModeUnion:
ret = CombineRgn(left, left, right, RGN_OR);
break;
case CombineModeXor:
ret = CombineRgn(left, left, right, RGN_XOR);
break;
//.........这里部分代码省略.........
示例10: draw_graphics
static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits, const char ***sha1)
{
DWORD dib_size = get_dib_size(bmi);
HPEN solid_pen, dashed_pen, orig_pen;
HBRUSH solid_brush, dib_brush, hatch_brush, orig_brush;
INT i, y, hatch_style;
HRGN hrgn, hrgn2;
BYTE dib_brush_buf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD) + 16 * 16 * sizeof(DWORD)]; /* Enough for 16 x 16 at 32 bpp */
BITMAPINFO *brush_bi = (BITMAPINFO*)dib_brush_buf;
BYTE *brush_bits;
BOOL dib_is_1bpp = (bmi->bmiHeader.biBitCount == 1);
memset(bits, 0xcc, dib_size);
compare_hash(bmi, bits, sha1, "empty");
solid_pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0xff));
orig_pen = SelectObject(hdc, solid_pen);
SetBrushOrgEx(hdc, 0, 0, NULL);
/* horizontal and vertical lines */
for(i = 1; i <= 16; i++)
{
SetROP2(hdc, i);
MoveToEx(hdc, 10, i * 3, NULL);
LineTo(hdc, 100, i * 3); /* l -> r */
MoveToEx(hdc, 100, 50 + i * 3, NULL);
LineTo(hdc, 10, 50 + i * 3); /* r -> l */
MoveToEx(hdc, 120 + i * 3, 10, NULL);
LineTo(hdc, 120 + i * 3, 100); /* t -> b */
MoveToEx(hdc, 170 + i * 3, 100, NULL);
LineTo(hdc, 170 + i * 3, 10); /* b -> t */
}
compare_hash(bmi, bits, sha1, "h and v solid lines");
memset(bits, 0xcc, dib_size);
/* diagonal lines */
SetROP2(hdc, R2_COPYPEN);
for(i = 0; i < 16; i++)
{
double s = sin(M_PI * i / 8.0);
double c = cos(M_PI * i / 8.0);
MoveToEx(hdc, 200.5 + 10 * c, 200.5 + 10 * s, NULL);
LineTo(hdc, 200.5 + 100 * c, 200.5 + 100 * s);
}
compare_hash(bmi, bits, sha1, "diagonal solid lines");
memset(bits, 0xcc, dib_size);
for(i = 0; i < sizeof(bias_check) / sizeof(bias_check[0]); i++)
{
MoveToEx(hdc, bias_check[i].left, bias_check[i].top, NULL);
LineTo(hdc, bias_check[i].right, bias_check[i].bottom);
}
compare_hash(bmi, bits, sha1, "more diagonal solid lines");
memset(bits, 0xcc, dib_size);
/* solid brush PatBlt */
solid_brush = CreateSolidBrush(RGB(0x33, 0xaa, 0xff));
orig_brush = SelectObject(hdc, solid_brush);
for(i = 0, y = 10; i < 256; i++)
{
BOOL ret;
ret = PatBlt(hdc, 10, y, 100, 10, rop3[i]);
if(rop_uses_src(rop3[i]))
ok(ret == FALSE, "got TRUE for %x\n", rop3[i]);
else
{
ok(ret, "got FALSE for %x\n", rop3[i]);
y += 20;
}
}
compare_hash(bmi, bits, sha1, "solid patblt");
memset(bits, 0xcc, dib_size);
/* clipped lines */
hrgn = CreateRectRgn(10, 10, 200, 20);
hrgn2 = CreateRectRgn(100, 100, 200, 200);
CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
SetRectRgn(hrgn2, 290, 100, 300, 200);
CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
ExtSelectClipRgn(hdc, hrgn, RGN_COPY);
DeleteObject(hrgn2);
for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
{
MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
}
compare_hash(bmi, bits, sha1, "clipped solid hlines");
memset(bits, 0xcc, dib_size);
for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
{
MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
}
//.........这里部分代码省略.........
示例11: VBoxEnumFunc
BOOL CALLBACK VBoxEnumFunc(HWND hwnd, LPARAM lParam)
{
PVBOX_ENUM_PARAM lpParam = (PVBOX_ENUM_PARAM)lParam;
DWORD dwStyle, dwExStyle;
RECT rectWindow, rectVisible;
dwStyle = GetWindowLong(hwnd, GWL_STYLE);
dwExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
if ( !(dwStyle & WS_VISIBLE)
|| (dwStyle & WS_CHILD))
return TRUE;
Log(("VBoxTray: VBoxEnumFunc %x\n", hwnd));
/* Only visible windows that are present on the desktop are interesting here */
if (GetWindowRect(hwnd, &rectWindow))
{
char szWindowText[256];
szWindowText[0] = 0;
OSVERSIONINFO OSinfo;
HWND hStart = NULL;
GetWindowText(hwnd, szWindowText, sizeof(szWindowText));
OSinfo.dwOSVersionInfoSize = sizeof (OSinfo);
GetVersionEx (&OSinfo);
if (OSinfo.dwMajorVersion >= 6)
{
hStart = ::FindWindowEx(GetDesktopWindow(), NULL, "Button", "Start");
if ( hwnd == hStart && szWindowText != NULL
&& !(strcmp(szWindowText, "Start"))
)
{
/* for vista and above. To solve the issue of small bar above
* the Start button when mouse is hovered over the start button in seamless mode.
* Difference of 7 is observed in Win 7 platform between the dimensionsof rectangle with Start title and its shadow.
*/
rectWindow.top += 7;
rectWindow.bottom -=7;
}
}
rectVisible = rectWindow;
#ifdef LOG_ENABLED
DWORD pid = 0;
DWORD tid = GetWindowThreadProcessId(hwnd, &pid);
#endif
/* Filter out Windows XP shadow windows */
/** @todo still shows inside the guest */
if ( szWindowText[0] == 0
&& (
(dwStyle == (WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS)
&& dwExStyle == (WS_EX_LAYERED|WS_EX_TOOLWINDOW|WS_EX_TRANSPARENT|WS_EX_TOPMOST))
|| (dwStyle == (WS_POPUP|WS_VISIBLE|WS_DISABLED|WS_CLIPSIBLINGS|WS_CLIPCHILDREN)
&& dwExStyle == (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_LAYERED | WS_EX_NOACTIVATE))
|| (dwStyle == (WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN)
&& dwExStyle == (WS_EX_TOOLWINDOW))
))
{
Log(("VBoxTray: Filter out shadow window style=%x exstyle=%x\n", dwStyle, dwExStyle));
Log(("VBoxTray: Enum hwnd=%x rect (%d,%d) (%d,%d) (filtered)\n", hwnd, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
Log(("VBoxTray: title=%s style=%x exStyle=%x\n", szWindowText, dwStyle, dwExStyle));
Log(("VBoxTray: pid=%d tid=%d\n", pid, tid));
return TRUE;
}
/** @todo will this suffice? The Program Manager window covers the whole screen */
if (strcmp(szWindowText, "Program Manager"))
{
Log(("VBoxTray: Enum hwnd=%x rect (%d,%d) (%d,%d) (applying)\n", hwnd, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
Log(("VBoxTray: title=%s style=%x exStyle=%x\n", szWindowText, dwStyle, dwExStyle));
Log(("VBoxTray: pid=%d tid=%d\n", pid, tid));
HRGN hrgn = CreateRectRgn(0,0,0,0);
int ret = GetWindowRgn(hwnd, hrgn);
if (ret == ERROR)
{
Log(("VBoxTray: GetWindowRgn failed with rc=%d\n", GetLastError()));
SetRectRgn(hrgn, rectVisible.left, rectVisible.top, rectVisible.right, rectVisible.bottom);
}
else
{
/* this region is relative to the window origin instead of the desktop origin */
OffsetRgn(hrgn, rectWindow.left, rectWindow.top);
}
if (lpParam->hrgn)
{
/* create a union of the current visible region and the visible rectangle of this window. */
CombineRgn(lpParam->hrgn, lpParam->hrgn, hrgn, RGN_OR);
DeleteObject(hrgn);
}
else
lpParam->hrgn = hrgn;
}
else
{
Log(("VBoxTray: Enum hwnd=%x rect (%d,%d) (%d,%d) (ignored)\n", hwnd, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
Log(("VBoxTray: title=%s style=%x\n", szWindowText, dwStyle));
Log(("VBoxTray: pid=%d tid=%d\n", pid, tid));
}
//.........这里部分代码省略.........
示例12: X11DRV_ExtTextOut
/***********************************************************************
* X11DRV_ExtTextOut
*/
BOOL CDECL
X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
const RECT *lprect, LPCWSTR wstr, UINT count,
const INT *lpDx )
{
unsigned int i;
fontObject* pfo;
XFontStruct* font;
BOOL rotated = FALSE;
XChar2b *str2b = NULL;
BOOL dibUpdateFlag = FALSE;
BOOL result = TRUE;
HRGN saved_region = 0;
if(physDev->has_gdi_font)
return X11DRV_XRender_ExtTextOut(physDev, x, y, flags, lprect, wstr, count, lpDx);
if (!X11DRV_SetupGCForText( physDev )) return TRUE;
pfo = XFONT_GetFontObject( physDev->font );
font = pfo->fs;
if (pfo->lf.lfEscapement && pfo->lpX11Trans)
rotated = TRUE;
TRACE("hdc=%p df=%04x %d,%d %s, %d flags=%d lpDx=%p\n",
physDev->hdc, (UINT16)(physDev->font), x, y,
debugstr_wn (wstr, count), count, flags, lpDx);
if (lprect != NULL) TRACE("\trect=(%d,%d - %d,%d)\n",
lprect->left, lprect->top,
lprect->right, lprect->bottom );
/* Draw the rectangle */
if (flags & ETO_OPAQUE)
{
X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod );
dibUpdateFlag = TRUE;
wine_tsx11_lock();
XSetForeground( gdi_display, physDev->gc, physDev->backgroundPixel );
XFillRectangle( gdi_display, physDev->drawable, physDev->gc,
physDev->dc_rect.left + lprect->left, physDev->dc_rect.top + lprect->top,
lprect->right - lprect->left, lprect->bottom - lprect->top );
wine_tsx11_unlock();
}
if (!count) goto END; /* Nothing more to do */
/* Set the clip region */
if (flags & ETO_CLIPPED)
{
HRGN clip_region;
clip_region = CreateRectRgnIndirect( lprect );
/* make a copy of the current device region */
saved_region = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( saved_region, physDev->region, 0, RGN_COPY );
X11DRV_SetDeviceClipping( physDev, saved_region, clip_region );
DeleteObject( clip_region );
}
/* Draw the text background if necessary */
if (!dibUpdateFlag)
{
X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod );
dibUpdateFlag = TRUE;
}
/* Draw the text (count > 0 verified) */
if (!(str2b = X11DRV_cptable[pfo->fi->cptable].punicode_to_char2b( pfo, wstr, count )))
goto FAIL;
wine_tsx11_lock();
XSetForeground( gdi_display, physDev->gc, physDev->textPixel );
wine_tsx11_unlock();
if(!rotated)
{
if (!lpDx)
{
X11DRV_cptable[pfo->fi->cptable].pDrawString(
pfo, gdi_display, physDev->drawable, physDev->gc,
physDev->dc_rect.left + x, physDev->dc_rect.top + y, str2b, count );
}
else
{
XTextItem16 *items, *pitem;
pitem = items = HeapAlloc( GetProcessHeap(), 0,
count * sizeof(XTextItem16) );
if(items == NULL) goto FAIL;
for(i = 0; i < count; i++)
{
//.........这里部分代码省略.........
示例13: CombineRgn
void DSObjects::RMAIntersectRegion(REGION* reg1, REGION* reg2, REGION* regD)
{
CombineRgn((HRGN)regD->pOSRegion, (HRGN)reg1->pOSRegion, (HRGN)reg2->pOSRegion, RGN_AND);
ExtractRects(regD);
}
示例14: ddraw_clipper_GetClipList
/*****************************************************************************
* IDirectDrawClipper::GetClipList
*
* Retrieve a copy of the clip list
*
* Arguments:
* rect: Rectangle to be used to clip the clip list or NULL for the
* entire clip list.
* clip_list: structure for the resulting copy of the clip list.
* If NULL, fills Size up to the number of bytes necessary to hold
* the entire clip.
* clip_list_size: Size of resulting clip list; size of the buffer at clip_list
* or, if clip_list is NULL, receives the required size of the buffer
* in bytes.
*
* RETURNS
* Either DD_OK or DDERR_*
************************************************************************/
static HRESULT WINAPI ddraw_clipper_GetClipList(IDirectDrawClipper *iface, RECT *rect,
RGNDATA *clip_list, DWORD *clip_list_size)
{
struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
HRGN region;
TRACE("iface %p, rect %s, clip_list %p, clip_list_size %p.\n",
iface, wine_dbgstr_rect(rect), clip_list, clip_list_size);
wined3d_mutex_lock();
if (clipper->window)
{
if (!(region = get_window_region(clipper->window)))
{
wined3d_mutex_unlock();
WARN("Failed to get window region.\n");
return E_FAIL;
}
}
else
{
if (!(region = clipper->region))
{
wined3d_mutex_unlock();
WARN("No clip list set.\n");
return DDERR_NOCLIPLIST;
}
}
if (rect)
{
HRGN clip_region;
if (!(clip_region = CreateRectRgnIndirect(rect)))
{
wined3d_mutex_unlock();
ERR("Failed to create region.\n");
if (clipper->window)
DeleteObject(region);
return E_FAIL;
}
if (CombineRgn(clip_region, region, clip_region, RGN_AND) == ERROR)
{
wined3d_mutex_unlock();
ERR("Failed to combine regions.\n");
DeleteObject(clip_region);
if (clipper->window)
DeleteObject(region);
return E_FAIL;
}
if (clipper->window)
DeleteObject(region);
region = clip_region;
}
*clip_list_size = GetRegionData(region, *clip_list_size, clip_list);
if (rect || clipper->window)
DeleteObject(region);
wined3d_mutex_unlock();
return DD_OK;
}
示例15: msg_Err
//.........这里部分代码省略.........
void *pBits; // pointer to DIB section
// Fill a BITMAPINFO structure
BITMAPINFO bmpInfo;
memset( &bmpInfo, 0, sizeof( bmpInfo ) );
bmpInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
bmpInfo.bmiHeader.biWidth = width;
bmpInfo.bmiHeader.biHeight = -height;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biSizeImage = width * height * 4;
// Create a DIB (Device Independent Bitmap) and associate it with
// a temporary DC
HDC hDC = CreateCompatibleDC( m_hDC );
HBITMAP hBmp = CreateDIBSection( hDC, &bmpInfo, DIB_RGB_COLORS,
&pBits, NULL, 0 );
SelectObject( hDC, hBmp );
// Mask for transparency
HRGN mask = CreateRectRgn( 0, 0, 0, 0 );
// Skip the first lines of the image
pBmpData += 4 * ySrc * rBitmap.getWidth();
// Copy the bitmap on the image and compute the mask
for( int y = 0; y < height; y++ )
{
// Skip uninteresting bytes at the beginning of the line
pBmpData += 4 * xSrc;
// Flag to say whether the previous pixel on the line was visible
bool wasVisible = false;
// Beginning of the current visible segment on the line
int visibleSegmentStart = 0;
for( int x = 0; x < width; x++ )
{
uint8_t b = *(pBmpData++);
uint8_t g = *(pBmpData++);
uint8_t r = *(pBmpData++);
uint8_t a = *(pBmpData++);
// Draw the pixel
((UINT32 *)pBits)[x + y * width] =
(a << 24) | (r << 16) | (g << 8) | b;
if( a > 0 )
{
// Pixel is visible
if( ! wasVisible )
{
// Beginning of a visible segment
visibleSegmentStart = x;
}
wasVisible = true;
}
else
{
// Pixel is transparent
if( wasVisible )
{
// End of a visible segment: add it to the mask
addSegmentInRegion( mask, visibleSegmentStart, x, y );
}
wasVisible = false;
}
}
if( wasVisible )
{
// End of a visible segment: add it to the mask
addSegmentInRegion( mask, visibleSegmentStart, width, y );
}
// Skip uninteresting bytes at the end of the line
pBmpData += 4 * (rBitmap.getWidth() - width - xSrc);
}
// Apply the mask to the internal DC
OffsetRgn( mask, xDest, yDest );
SelectClipRgn( m_hDC, mask );
BLENDFUNCTION bf; // structure for alpha blending
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 0xff; // don't use constant alpha
bf.AlphaFormat = AC_SRC_ALPHA;
// Blend the image onto the internal DC
if( !AlphaBlend( m_hDC, xDest, yDest, width, height, hDC, 0, 0,
width, height, bf ) )
{
msg_Err( getIntf(), "AlphaBlend() failed" );
}
// Add the bitmap mask to the global graphics mask
CombineRgn( m_mask, m_mask, mask, RGN_OR );
// Do cleanup
DeleteObject( hBmp );
DeleteObject( mask );
DeleteDC( hDC );
}