win32 - memory leaks with my Region functions

i have these 2 functions:
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;
}

i'm trying found some memory leaks, but i didn't find them :(
can anyone advice me?
Last edited on
RegionbyBitmap return HRGN. is it later deleted with DeleteObject?
Have you also checked whether the GDI objects associated with the process are increasing, as well as the memory usage?

Andy

PS This code looks a bit "old school"

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


While it's valid for VC6, when new returned a NULL pointer when it failed to allocate memory, it's not the case for the newer version of Visual Studio (or GCC, etc.) new raises a std::bad_alloc exception. If you want to avoid exception handling you could use std::nothrow?
http://www.cplusplus.com/reference/new/nothrow/
Andy i did that:
1
2
3
BYTE *pPixels = new (std::nothrow) BYTE[wBmpWidth*wBmpHeight*3];
    if (pPixels==0)
        return NULL;

but i continue with problems :(
i don't understand how these 2 functions, can block the ToolTip tool :(
when i put the control hidded, the ToolTip is showed normaly.
Tath you give me an idea:
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
class region
{

private:

    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];
        BYTE *pPixels = new (std::nothrow) BYTE[wBmpWidth*wBmpHeight*3];
        if (pPixels==0)
            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;
    }
    HRGN hregion=NULL;

public:
    region(HBITMAP hbitmapregion)
    {
        hregion=RegionbyBitmap(hbitmapregion);
    }

    ~region()
    {
        DeleteObject(hregion);
    }

    void bitmap(HBITMAP hbitmapregion)
    {
        hregion=RegionbyBitmap(hbitmapregion);
    }

    operator HRGN()
    {
        return hregion;
    }
};

now the HRGN is destroyed automatic, like i did with HDC, HBITMAP and HBRUSH ;)
but i continue with problems :(
the region is created and used normaly, but the ToolTip isn't showed :(
Topic archived. No new replies allowed.