#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    13
    Rep Power
    0

    Region and masks


    Hi,
    Sorry for asking a lot of questions... It's a good way to learn, so I hope you can forgive me.

    I would like to make region from a mask. But I really don't want to combine rectangles for every pixel. I don't think that's a good approach. What I would like to do, is to have a layout like this:

    Code:
    00000111111111100000
    01111111111111111000
    01111100011110001110
    01111111111111111110
    01111111110011111110
    01111001111111001110
    00111110000000111100
    00001111111111100000
    I would then like to respond to hit-tests by simply checking if the specified coordinate is 1 or 0. I would also return the bounds of the region and could also combine it with other regions, if that would be required. How can I accomplish this? It would be an "implementation" of HRGN, or something.

    Thanks in advance,
    Nille
  2. #2
  3. No Profile Picture
    Offensive Member
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2002
    Location
    in the perfect world
    Posts
    622
    Rep Power
    27
    Try

    PtInRect() or PtInRegion() with the params from the mouse click or use GetCursor()

    ClientToScreen() and ScreenToClient() may be helpfull in converting the coods.
    The essence of Christianity is told us in the Garden of Eden history. The fruit that was forbidden was on the Tree of Knowledge. The subtext is, All the suffering you have is because you wanted to find out what was going on. You could be in the Garden of Eden if you had just kept your f***ing mouth shut and hadn't asked any questions.

    Frank Zappa
  4. #3
  5. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    13
    Rep Power
    0
    I want to respond to these method calls myself. Think of it like this:

    Code:
          |--- Rectangle
    HRGN -|--- Ellipse
          |--- MyImageRegion
    I create a mask from a bitmap and return a valid HRGN. I then want to perform hit tests.

    Code:
    HRGN hRgn = CreateCustomRegion("c:\\test.bmp");
    if(PtInRegion(hRgn, 10, 10)) // <---- !!!
    {
       //...
    }
    I have no idea how regions work. I can image they do something like this:

    Code:
    ((SomeStruct*)hRgn)->IsPointInRegion(hRgn, x, y);
    The thing is, I want to do the hit test on my own, but I want the HRGN to be treated as any other HRGN.

    Imaging that HRGN was an abstract class, looking like this:
    Code:
    abstract class Region
    {
       abstract bool PtInRegion(int x, int y);
    }
    You could then make your own implementation of the abstract class. This is what I want to do. I want to make my own implementation of HRGN. Is it possible?
  6. #4
  7. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    6
    Rep Power
    0
    Hi, I don't know if this is exactly what your looking for, but i found this code written by another programmer while i was trying to create window skins. It allows you to create a region using a bitmap and specifying the rgb value of the transparent colour.

    PHP Code:
    HRGN BitmapToRegion (HBITMAP hBmpCOLORREF cTransparentColor)
    {
        
    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(hBmpsizeof(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 *)&RGB32BITSBITMAPINFODIB_RGB_COLORS, &pbits32NULL0);
                if (
    hbm32)
                {
                    
    HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDChbm32);

                    
    // 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(hbm32sizeof(bm32), &bm32);
                        while (
    bm32.bmWidthBytes 4)
                            
    bm32.bmWidthBytes++;

                        
    // Copy the bitmap into the memory DC
                        
    HBITMAP holdBmp = (HBITMAP)SelectObject(hDChBmp);
                        
    BitBlt(hMemDC00bm.bmWidthbm.bmHeighthDC00SRCCOPY);

                        
    // 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_MOVEABLEsizeof(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.rcBoundMAXLONGMAXLONG00);

                        
    // Keep on hand highest and lowest values for the "transparent" pixels
                        
    BYTE lr GetRValue(cTransparentColor);
                        
    BYTE lg GetGValue(cTransparentColor);
                        
    BYTE lb GetBValue(cTransparentColor);
                        

                        
    // 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 0bm.bmHeighty++)
                        {
                            
    // Scan each bitmap pixel from left to right
                            
    for (int x 0bm.bmWidthx++)
                            {
                                
    // Search for a continuous range of "non transparent pixels"
                                
    int x0 x;
                                
    LONG *= (LONG *)p32 x;
                                while (
    bm.bmWidth)
                                {
                                    
    BYTE b GetRValue(*p);
                                    if (
    == lr)
                                    {
                                        
    GetGValue(*p);
                                        if (
    == lg )
                                        {
                                            
    GetBValue(*p);
                                            if (
    ==lb )
                                                
    // This pixel is "transparent"
                                                
    break;
                                        }
                                    }
                                    
    p++;
                                    
    x++;
                                }

                                if (
    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(hDatasizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
                                        
    pData = (RGNDATA *)GlobalLock(hData);
                                    }
                                    
    RECT *pr = (RECT *)&pData->Buffer;
                                    
    SetRect(&pr[pData->rdh.nCount], x0yxy+1);
                                    if (
    x0 pData->rdh.rcBound.left)
                                        
    pData->rdh.rcBound.left x0;
                                    if (
    pData->rdh.rcBound.top)
                                        
    pData->rdh.rcBound.top y;
                                    if (
    pData->rdh.rcBound.right)
                                        
    pData->rdh.rcBound.right x;
                                    if (
    y+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(NULLsizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
                                        if (
    hRgn)
                                        {
                                            
    CombineRgn(hRgnhRgnhRGN_OR);
                                            
    DeleteObject(h);
                                        }
                                        else
                                            
    hRgn h;
                                        
    pData->rdh.nCount 0;
                                        
    SetRect(&pData->rdh.rcBoundMAXLONGMAXLONG00);
                                    }
                                }
                            }

                            
    // 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(NULLsizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
                        if (
    hRgn)
                        {
                            
    CombineRgn(hRgnhRgnhRGN_OR);
                            
    DeleteObject(h);
                        }
                        else
                            
    hRgn h;

                        
    // Clean up
                        
    SelectObject(hDCholdBmp);
                        
    DeleteDC(hDC);
                    }

                    
    DeleteObject(SelectObject(hMemDCholdBmp));
                }

                
    DeleteDC(hMemDC);
            }    
        }

        return 
    hRgn;

    Only thing is I have no idea how this code works, maybe if someone could figure it out and explain it. I've tried askin the guy who wrote it, but it turns out it was posted like 3 years ago so he isn't replying.

IMN logo majestic logo spyfu logo threadwatch logo seochat tools logo