About the class Crgn

来源:互联网 发布:淘宝客服外包合算吗 编辑:程序博客网 时间:2024/05/21 14:53

 

The CRgn class  used to to encapsulate a Windows graphics device interface (GDI) region for program unregulate windows .

 

Construction CRgn Constructs a CRgn object.


Initialization CreateRectRgn    Initializes a CRgn object with a ctangular region. CreateRectRgnIndirect   Initializes a CRgn object with a rectangular region defined by a RECT structure. CombineRgn   Sets a CRgn object so that it is equivalent to the union of two specified CRgn objects. CopyRgn    Sets a CRgn object so that it is a copy of a specified CRgn object.


Operations EqualRgn   Checks two CRgn objects to determine whether they are equivalent. FromHandle  Returns a pointer to a CRgn object when given a handle to a Windows region. GetRegionData  Fills the specified buffer with data describing the given region. GetRgnBox  Retrieves the coordinates of the bounding rectangle of a CRgn object. OffsetRgn   Moves a CRgn object by the specified offsets. PtInRegion   Determines whether a specified point is in the region. RectInRegion   Determines whether any part of a specified rectangle is within the boundaries of the region.

SetRectRgn

Sets the CRgn object to the specified rectangular region.

 

 

 

 

BOOL CreateRectRgn( int x1, int y1, int x2, int y2 );

void SetRectRgn ( int x1, int y1, int x2, int y2 );

void SetRectRgn( LPCRECT lpRect );

[exap 1]

 

 

[examp  ] 

[examp2]

RECT   rc;  
   
          GetMyItemRect(&rc);  
          SendMessage(hwndToolTip,   TTM_ADJUSTRECT,   TRUE,   (LPARAM)&rc);  
          SetWindowPos(hwndToolTip,  
                                    NULL,  
                                    rc.left,   rc.top,  
                                    0,   0,  
                                    SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);   

RS:
GetMyitemRect()  用来得到你的提示框的大小的,自定义函数   
 hwndToolTip   你的提示框的句柄。 

[examp3]   When move the mouse in a special area ...

采用如下方法:  
  CToolTipCtrl     m_ToolTip;      
  CTestView::OnInitialUpdate()          
  {      
                        CView::OnInitialUpdate();      
                             
                        m_ToolTip.Create(this,TTS_ALWAYSTIP);      
                        m_ToolTip.AddTool(this,"ToolTip");      
  }      
     
  void     CTestView::OnMouseMove(UINT     nFlags,     CPoint     point)          
  {      
                        CRgn     rgn;      
                        rgn.CreateRectRgnIndirect(CRect     m_rect);      
                             
                        if(rgn.PtInRegion(point))      
                        {      
                                                CString     str;      
                                                str.Format("CX     %d,CY     %d",point.x,point.y);//可以修改提示内容      
                                                m_ToolTip.UpdateTipText(str,this);      
                        }      
                        CView::OnMouseMove(nFlags,     point);      
  }      
     
  LRESULT     CTestView::WindowProc(UINT     message,     WPARAM     wParam,     LPARAM     lParam)          
  {      
                        //     TODO:     Add     your     specialized     code     here     and/or     call     the     base     class      
                        if(message==     WM_MOUSEMOVE)      
                        {      
                                                MSG     msg;      
                                                msg.hwnd     =     m_hWnd;      
                                                msg.message     =     message;      
                                                msg.wParam     =     wParam;      
                                                msg.lParam     =     lParam;      
     
                                                m_ToolTip.RelayEvent(&msg);      
                        }      
                        return     CView::WindowProc(message,     wParam,     lParam);      
  }  
 


 
 HRGN BitmapToRegion (HBITMAP hBmp, COLORREF cTransparentColor = 0, COLORREF cTolerance = 0x101010)
{
    HRGN hRgn = NULL;

    if (hBmp)
    {
        // Create a memory DC inside which we will scan the bitmap content
        HDC hMemDC = CreateCompatibleDC(NULL);
        if (hMemDC)
        {
            // Get bitmap size
            BITMAP bm;
            GetObject(hBmp, sizeof(bm), &bm);

            // Create a 32 bits depth bitmap and select it into the memory DC 
            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;