Sign in to follow this  
cambalinho

C\C++ - win32: how create regions by images?

Recommended Posts

heres how i create the Region:

HRGN  hRgn = CreateRectRgn(0,0,0, 0);

now see how i test the pixels on a variable:

DWORD p=0;
    for (WORD y=0; y<wBmpHeight; y++)
    {
        for (WORD x=0; x<wBmpWidth; x++)
        {
            BYTE jRed   = pPixels[p+2];
            BYTE jGreen = pPixels[p+1];
            BYTE jBlue  = pPixels[p+0];
            COLORREF pixelcolor=RGB(jRed,jGreen,jBlue);
            if (pixelcolor!=backcolor)
            {
                // add regions points, except the backcolor
                hTmpRgn = CreateRectRgn(x,y,x+1,y+1);
                CombineRgn(hRgn, hRgn, hTmpRgn, RGN_OR);
                DeleteObject(hTmpRgn);
            }

            // next pixel
            p+=3;
        }
    }

i see 2 problems:

1 - the backcolor is showed sad.png ;

2 - the control size is allways changed sad.png

 

so what i'm doing wrong?

Edited by cambalinho

Share this post


Link to post
Share on other sites

The fact that people sometimes use them that way does not negate the fact that this was not part of their design.

 

They were not designed for it.  The API does not directly support it.  Many people have discovered the pattern that you described above, a manual per-pixel creation of regions that consume a huge amount of resources to initially create. 

 

They were not meant for that, they are a bad tool for per-pixel cutouts.  They are slow to generate and slow to render... plus there are alternatives that are designed to properly handle transparency.

 

There are very few times that regions are the only way to accomplish cutouts inside Windows. If you happen to be in one of those very few uses then a region may be your tool of last resort. 

 

But it should not be a go-to tool. Windows supports transparency and even alpha-blending for almost everything. Use per-pixel regions if no other alternatives, because unfortunately some things don't support it.  For everything else, use the more modern APIs.

i don't use window 8. almost people. i belive, uses the windows 7.

the WS_EX_TRANSPARENT isn't compatible with WS_CLIPCHILDREN :(

Share this post


Link to post
Share on other sites

This is a interesting read on WS_EX_TRANSPARENT. It might not do what you think it does:

http://blogs.msdn.com/b/oldnewthing/archive/2012/12/17/10378525.aspx

true... the Microsoft can be more complicated than it's lol

heres the Region function working:

//nice function for get the HBITMAP pixels with DIB's ;)
BYTE* Get24BitPixels(HBITMAP pBitmap, WORD *pwWidth, WORD *pwHeight)
{
  // a bitmap object just to get bitmap width and height
	BITMAP bmpBmp;

  // pointer to original bitmap info
	LPBITMAPINFO pbmiInfo;

  // bitmap info will hold the new 24bit bitmap info
  BITMAPINFO bmiInfo;

  // width and height of the bitmap
  WORD wBmpWidth, wBmpHeight;

  // ---------------------------------------------------------
  // get some info from the bitmap
  // ---------------------------------------------------------
	GetObject(pBitmap, sizeof(bmpBmp),&bmpBmp);
  pbmiInfo   = (LPBITMAPINFO)&bmpBmp;

  // get width and height
	wBmpWidth  = (WORD)pbmiInfo->bmiHeader.biWidth;
	wBmpWidth -= (wBmpWidth%4);                       // width is 4 byte boundary aligned.
	wBmpHeight = (WORD)pbmiInfo->bmiHeader.biHeight;

  // copy to caller width and height parms
  *pwWidth  = wBmpWidth;
  *pwHeight = wBmpHeight;
  // ---------------------------------------------------------

	// allocate width * height * 24bits pixels
  BYTE *pPixels = new BYTE[wBmpWidth*wBmpHeight*3];
	if (!pPixels) return NULL;

  // get user desktop device context to get pixels from
	HDC hDC = GetWindowDC(NULL);

  // fill desired structure
	bmiInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmiInfo.bmiHeader.biWidth = wBmpWidth;
	bmiInfo.bmiHeader.biHeight = -wBmpHeight;
	bmiInfo.bmiHeader.biPlanes = 1;
	bmiInfo.bmiHeader.biBitCount = 24;
	bmiInfo.bmiHeader.biCompression = BI_RGB;
	bmiInfo.bmiHeader.biSizeImage = wBmpWidth*wBmpHeight*3;
	bmiInfo.bmiHeader.biXPelsPerMeter = 0;
	bmiInfo.bmiHeader.biYPelsPerMeter = 0;
	bmiInfo.bmiHeader.biClrUsed = 0;
	bmiInfo.bmiHeader.biClrImportant = 0;

  // get pixels from the original bitmap converted to 24bits
  int iRes = GetDIBits(hDC,pBitmap,0,wBmpHeight,(LPVOID)pPixels,&bmiInfo,DIB_RGB_COLORS);

  // release the device context
	ReleaseDC(NULL,hDC);

  // if failed, cancel the operation.
	if (!iRes)
  {
    delete pPixels;
    return NULL;
  };

  // return the pixel array
	return pPixels;
}

HRGN RegionbyBitmap(HBITMAP pBitmap,COLORREF clrTransparent=-1 )
{
    BYTE jTranspR = GetRValue(clrTransparent), jTranspG=GetGValue(clrTransparent), jTranspB=GetBValue(clrTransparent);
  // bitmap width and height
  WORD wBmpWidth,wBmpHeight;

  // the final region and a temporary region
  HRGN hRgn, hTmpRgn;

  // 24bit pixels from the bitmap
  BYTE *pPixels = Get24BitPixels(pBitmap, &wBmpWidth, &wBmpHeight);
  if (!pPixels) return NULL;

  // create our working region
  hRgn = CreateRectRgn(0,0,wBmpWidth,wBmpHeight);
  if (!hRgn) { delete pPixels; return NULL; }

  // ---------------------------------------------------------
  // scan the bitmap
  // ---------------------------------------------------------
  DWORD p=0;
  for (WORD y=0; y<wBmpHeight; y++)
  {
    for (WORD x=0; x<wBmpWidth; x++)
    {
      BYTE jRed   = pPixels[p+2];
      BYTE jGreen = pPixels[p+1];
      BYTE jBlue  = pPixels[p+0];

      if ((jRed == jTranspR && jGreen == jTranspG && jBlue == jTranspB))
      {
        // remove transparent color from region
        hTmpRgn = CreateRectRgn(x,y,x+1,y+1);
        CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
        DeleteObject(hTmpRgn);
      }

      // next pixel
      p+=3;
    }
  }

  // release pixels
  delete pPixels;

  // return the region
  return hRgn;
}

heres how use it:

if(inst->blnTransparent==true)
                {
                    TransparentBlt(test.hdc,0,0,imglabel.width(),imglabel.height(),imglabel,0,0, imglabel.width(),imglabel.height(), inst->clrBackColor);
                    inst->LabelRegion=RegionbyBitmap(imglabel, inst->clrBackColor);
                    SetWindowRgn(inst->hwnd,inst->LabelRegion,TRUE);

                }

now the child control is realy showed 'transparent'... what i mean is that the child control shape is the bitmap shape ;)

thanks to all

Share this post


Link to post
Share on other sites

why i'm receiving negative reputation on #3 if i'm right?

only after windows 8(and  windows 8 can use layed with child controls)

from: https://msdn.microsoft.com/en-us/library/windows/desktop/ff700543%28v=vs.85%29.aspx

we read:

 

WS_EX_LAYERED 0x00080000

The window is a layered window. This style cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC.

Windows 8:  The WS_EX_LAYERED style is supported for top-level windows and child windows. Previous Windows versions support WS_EX_LAYERED only for top-level windows.

Share this post


Link to post
Share on other sites
The same member has voted down all your posts across multiple threads. Normally, I would tell you to ignore it, but looking at his reputation, he votes down more than he votes up. This goes against the purpose of the rating system.

He appears to be a troll. Consider messaging a moderator about this. Edited by MarkS

Share this post


Link to post
Share on other sites

The same member has voted down all your posts across multiple threads. Normally, I would tell you to ignore it, but looking at his reputation, he votes down more than he votes up. This goes against the purpose of the rating system.

 

 

He appears to be a troll. Consider messaging a moderator about this.

can't tell something to moderator, if i don't know who give me the negative reputation tongue.png

but you have right... i will ignore it.

and i belive that my code will help others ;)

thanks for answer me ;)

 

back to topic ;)

 

what is more faster? the CreateRectRgn() with CombineRgn(), or just the CreatePolygonRgn() with POINT object array?

Edited by cambalinho

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this