win32 - how create a bitmap Region?

how can i create a bitmap Region?
i did these function for create a bitmap Region:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
class MemoryDC
{
private:
    HDC memoryDC;

public:
    MemoryDC ()
    {
        memoryDC=CreateCompatibleDC(NULL);
    }

    operator HDC() const
    {
        return memoryDC;
    }

    ~MemoryDC ()
    {
       DeleteDC(memoryDC);
    }
};

class BitmapDC
{
private:
    MemoryDC hdcbitmap;
    HGDIOBJ bitmapold;
    HBITMAP bitmapcurrent;
    int intwidth;
    int intheight;

    void init(int width, int height)
    {
        bitmapcurrent = CreateBitmap(width, height, 1, 32, NULL);
        bitmapold = SelectObject(hdcbitmap, bitmapcurrent);
        intwidth=width;
        intheight=height;
    }

    void destroy()
    {
        SelectObject(hdcbitmap, bitmapold);
        DeleteObject(bitmapcurrent);
    }

public:

    BitmapDC(int width, int height)
    {
        init(width, height);
    }

    BitmapDC()
    {
        init(1, 1);
    }

    void size(int width, int height)
    {
        destroy();
        init(width, height);
    }

    int Width()
    {
        return intwidth;
    }

    int Height()
    {
        return intheight;
    }

    BitmapDC& operator= (const BitmapDC &bitmapsource)
    {
        if (this == &bitmapsource)      // Same object?
            return *this;
        destroy();
        init(bitmapsource.intwidth, bitmapsource.intheight);
        BitBlt(bitmapsource, 0, 0, intwidth, intheight, bitmapsource, 0, 0, SRCCOPY);
        return *this;
    }

    BitmapDC& operator= (const HBITMAP &bitmapsource)
    {
        destroy();
        BITMAP bm;
        GetObject(bitmapsource,sizeof(bm),&bm);
        init(bm.bmWidth, bm.bmHeight);
        DrawHBITMAPtoHDC(bitmapsource,hdcbitmap);
        return *this;
    }

    //testing the bitmao value if is nullptr
    bool operator != ( nullptr_t ) const
    {
        return bitmapcurrent != nullptr;
    }

    bool operator==(const BitmapDC &other) const
    {
        return (other.bitmapcurrent == this->bitmapcurrent);
    }

    bool operator!=(const BitmapDC &other) const
    {
        return !(*this == other);
    }

    operator HBITMAP() const
    {
        return bitmapcurrent;
    }

    operator HDC() const
    {
        return hdcbitmap;
    }

    ~BitmapDC()
    {
       destroy();
    }
};

const int LastPixel=-1;
const int FirstPixel=-2;
void DrawHBITMAPtoHDC(HBITMAP hBitmap, HDC hdc, int PosX=0, int PosY=0, COLORREF backcolor=-1)
{
    BITMAP bm;
    HDC MemDCExercising = CreateCompatibleDC(hdc);
    HBITMAP oldbitmap =(HBITMAP) SelectObject(MemDCExercising, hBitmap);
    GetObject(hBitmap,sizeof(bm),&bm);
    if(backcolor==LastPixel)
        TransparentBlt(hdc, PosX, PosY, bm.bmWidth , bm.bmHeight, MemDCExercising, 0, 0,bm.bmWidth , bm.bmHeight,GetPixel(MemDCExercising,bm.bmWidth-1,bm.bmHeight-1));
    else if(backcolor==FirstPixel)
        TransparentBlt(hdc, PosX, PosY, bm.bmWidth , bm.bmHeight, MemDCExercising, 0, 0,bm.bmWidth , bm.bmHeight,GetPixel(MemDCExercising,0,0));
    else
        TransparentBlt(hdc, PosX, PosY, bm.bmWidth , bm.bmHeight, MemDCExercising, 0, 0,bm.bmWidth , bm.bmHeight,backcolor);
    SelectObject(MemDCExercising,oldbitmap);
    DeleteDC(MemDCExercising);
    DeleteObject(hBitmap);
}

HRGN CreateBitmapRegion(HBITMAP bitmap, COLORREF transparentcolor=-1)
{
    HRGN hRgn, hRgnTemp;
    COLORREF mask_color=transparentcolor;
    int x=0, y=0;
    BITMAP bm={0};
    GetObject(bitmap,sizeof(bm),&bm);

    hRgn = CreateRectRgn(0, 0, bm.bmWidth, bm.bmHeight);
    BitmapDC btDC(bm.bmWidth, bm.bmHeight);
    DrawHBITMAPtoHDC(bitmap,btDC);

    for (x = 0 ; x<bm.bmWidth-1; x++)
    {
        for (y = 0 ; y<bm.bmHeight-1; y++)
        {
            if (GetPixel(btDC,x,y) == mask_color)
            {
                hRgnTemp = CreateRectRgn(x, y, x+1, y+1);
                int a=0;
                a=CombineRgn(hRgn, hRgn, hRgnTemp, RGN_OR);
                if(a==ERROR || a== NULLREGION)
                    SetWindowText(ActivatedForm, "REgion error");
                DeleteObject(hRgnTemp);
            }
        }
    }
    return hRgn;
}

i used the GetLastError() too, and i only get '6:The handle is invalid.'. i don't know i get these error. but imust see it after ;)
back to Regions: why i don't get the Regions? the child control is showed sometimes then isn't. the Region functions don't give me errors, only bad results :(
Last edited on
Currently you're doing nothing with the region. I guess you want clipping?

For that you need ExtSelectClipRgn(...):

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

[
and maybe GetClipRgn(...):
https://msdn.microsoft.com/en-us/library/windows/desktop/dd144866%28v=vs.85%29.aspx
]

Something like this?
1
2
3
4
5
6
7
8
9
  HRGN clip_hr = CreateRectRgn(0, 0, bm.bmWidth, bm.bmHeight);

  // GetClipRgn(hdc, clip_hr);

  HRGN hr = CreateRectRgn(x, y, x+1, y+1); // A single pixel?

  ExtSelectClipRgn(hdc, hr, RGN_OR); // Or wouldn't change anything?

  DeleteObject(hr);
now works fine:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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 hRgn;
}

thanks for all
Topic archived. No new replies allowed.