heres my image class:

class image
{
private:
    ULONG_PTR m_gdiplusToken;
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    HDC hdcimage=CreateCompatibleDC(NULL);
    HGDIOBJ obj=NULL;
    HBITMAP btBitmap=NULL;
    Image *img;
    bool isimgused=false;
    int imageheight=0;
    int imageweight=0;
    int framecount=0;
    int intSelectFrame=0;
    int framedelay=0;
    string strfilename="";
    Gdiplus::Color clrBackColor=Gdiplus::Color::Transparent;
    HDC hdcwindow;
    bool blnTransparent=true;

    HICON HICONFromHBITMAP(HBITMAP bitmap)
    {
        BITMAP bmp;
        GetObject(bitmap, sizeof(BITMAP), &bmp);
        HBITMAP hbmMask = CreateCompatibleBitmap(GetDC(NULL), bmp.bmWidth, bmp.bmHeight);

        ICONINFO ii = {0};
        ii.fIcon    = TRUE;
        ii.hbmColor = bitmap;
        ii.hbmMask  = hbmMask;

        HICON hIcon = CreateIconIndirect(&ii);
        DeleteObject(hbmMask);

        return hIcon;
    }

public:

    image()
    {
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        btBitmap=CreateCompatibleBitmap(hdcimage,1,1);
        obj = SelectObject(hdcimage, btBitmap);
    }

    image(HDC hdcWindow)
    {
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        hdcwindow=hdcWindow;
    }

    image(int width, int height)
    {
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        hdcimage = CreateCompatibleDC(NULL);
        btBitmap = CreateBitmap(width,height,1,32,NULL);
        obj = SelectObject(hdcimage, btBitmap);
        framecount=1;
        imageheight=height;
        imageweight=width;
    }

    image( const string & filename)
    {
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        strfilename=filename;
        if(toupper(filename[filename.size()-3])=='C' && toupper(filename[filename.size()-2])=='U' && toupper(filename[filename.size()-1])=='R')
        {
            //create the transparent icon handle
            HCURSOR hicon = (HCURSOR)LoadImage(NULL, filename.c_str(), IMAGE_CURSOR, imageweight, imageheight, LR_LOADFROMFILE|LR_SHARED|LR_DEFAULTSIZE|LR_LOADTRANSPARENT);
            ICONINFO ii;
            BOOL fResult = GetIconInfo(hicon, &ii);
            if (fResult)
            {
                BITMAP bm;
                fResult = GetObject(ii.hbmMask, sizeof(bm), &bm) == sizeof(bm);
                if (fResult)
                {
                    imageweight= bm.bmWidth;
                    imageheight= ii.hbmColor ? bm.bmHeight : bm.bmHeight / 2;
                }
                if (ii.hbmMask) DeleteObject(ii.hbmMask);
                if (ii.hbmColor) DeleteObject(ii.hbmColor);
            }
            btBitmap=CreateBitmap(imageweight,imageheight,1,32,NULL);//create the bitmap with icon size
            obj = SelectObject(hdcimage, btBitmap);//add the bitmap to memory DC
            DrawIconEx(hdcimage,0,0,hicon,imageweight,imageheight,0,0,DI_NORMAL);//draw the icon to DC with right size
            //seems the DrawIcon(), always, draw it with 32X32 size
            framecount=1;
            DestroyCursor(hicon);
        }
        else
        {
            isimgused=true;
            Gdiplus::Image img2(towstring(filename).c_str());
            btBitmap=CreateBitmap(img2.GetWidth(),img2.GetHeight(),1,32,NULL);
            obj = SelectObject(hdcimage, btBitmap);
            Gdiplus::Graphics graphics(hdcimage);
            graphics.DrawImage(&img2, 0, 0, img2.GetWidth(), img2.GetHeight());
            imageweight=img2.GetWidth();
            imageheight=img2.GetHeight();
            UINT count = 0;
            count = img2.GetFrameDimensionsCount();
            GUID* pDimensionIDs = (GUID*)malloc(sizeof(GUID)*count);
            img2.GetFrameDimensionsList(pDimensionIDs, count);
            framecount=img2.GetFrameCount(&pDimensionIDs[0]);
            if (framecount>1)
                framedelay =img2.GetPropertyItemSize(PropertyTagFrameDelay);
            else
                framedelay =0;
            img=new Image(towstring(filename).c_str());
            free(pDimensionIDs);
        }
    }

    image (const image &cSource)
    {
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        framecount=cSource.framecount;
        framedelay=cSource.framedelay;
        clrBackColor=cSource.clrBackColor;
        img=cSource.img->Clone();
        imageweight=cSource.imageweight;
        imageheight=cSource.imageheight;
        strfilename=cSource.strfilename;
        btBitmap=CreateBitmap(imageweight,imageheight,1,32,NULL);
        obj = SelectObject(hdcimage, btBitmap);
        BitBlt(hdcimage,0,0,imageweight,imageheight,cSource.hdcimage,0,0,SRCCOPY);
    }

    image& operator= (const image &cSource)
    {
        framecount=cSource.framecount;
        framedelay=cSource.framedelay;
        clrBackColor=cSource.clrBackColor;
        img=cSource.img->Clone();
        imageweight=cSource.imageweight;
        imageheight=cSource.imageheight;
        strfilename=cSource.strfilename;
        btBitmap=CreateBitmap(imageweight,imageheight,1,32,NULL);
        obj = SelectObject(hdcimage, btBitmap);
        BitBlt(hdcimage,0,0,imageweight,imageheight,cSource.hdcimage,0,0,SRCCOPY);
        return *this;
    }

    property <int> SelectFrame
    {
        Get(int)
        {
            return intSelectFrame;
        },
        Set(int selectframe)
        {
            intSelectFrame=selectframe;
            UINT count = 0;
            count = img->GetFrameDimensionsCount();
            GUID* pDimensionIDs = (GUID*)malloc(sizeof(GUID)*count);
            img->GetFrameDimensionsList(pDimensionIDs, count);
            img->SelectActiveFrame(&pDimensionIDs[0],intSelectFrame);
            Gdiplus::Graphics graphics(hdcimage);
            graphics.Clear(clrBackColor);
            graphics.DrawImage(img, 0, 0, img->GetWidth(), img->GetHeight());
            free(pDimensionIDs);
        }
    };

    property<int> FramesCount
    {
        Get(int)
        {
            return framecount;
        }
    };

    property<string> FileName
    {
        Get(string)
        {
            return strfilename;
        },
        Set(string filename)
        {
            if(isimgused==true)
                delete img;

            DeleteObject(btBitmap);
            DeleteObject(obj);
            strfilename=filename;
            if(toupper(filename[filename.size()-3])=='C' && toupper(filename[filename.size()-2])=='U' && toupper(filename[filename.size()-1])=='R')
            {
                //create the transparent icon handle
                HCURSOR hicon = (HCURSOR)LoadImage(NULL, filename.c_str(), IMAGE_CURSOR, imageweight, imageheight, LR_LOADFROMFILE|LR_SHARED|LR_DEFAULTSIZE|LR_LOADTRANSPARENT);
                ICONINFO ii;
                BOOL fResult = GetIconInfo(hicon, &ii);
                if (fResult)
                {
                    BITMAP bm;
                    fResult = GetObject(ii.hbmMask, sizeof(bm), &bm) == sizeof(bm);
                    if (fResult)
                    {
                        imageweight= bm.bmWidth;
                        imageheight= ii.hbmColor ? bm.bmHeight : bm.bmHeight / 2;
                    }
                    if (ii.hbmMask) DeleteObject(ii.hbmMask);
                    if (ii.hbmColor) DeleteObject(ii.hbmColor);
                }
                btBitmap=CreateBitmap(imageweight,imageheight,1,32,NULL);//create the bitmap with icon size
                obj = SelectObject(hdcimage, btBitmap);//add the bitmap to memory DC
                DrawIconEx(hdcimage,0,0,hicon,imageweight,imageheight,0,0,DI_NORMAL);//draw the icon to DC with right size
                //seems the DrawIcon(), always, draw it with 32X32 size
                framecount=1;
                DestroyCursor(hicon);
            }
            else
            {
                Gdiplus::Image img2(towstring(filename).c_str());
                btBitmap=CreateBitmap(img2.GetWidth(),img2.GetHeight(),1,32,NULL);
                obj = SelectObject(hdcimage, btBitmap);
                Gdiplus::Graphics graphics(hdcimage);
                graphics.DrawImage(&img2, 0,0,img2.GetWidth(),img2.GetHeight());
                imageweight=img2.GetWidth();
                imageheight=img2.GetHeight();
                UINT count = 0;
                count = img2.GetFrameDimensionsCount();
                GUID* pDimensionIDs = (GUID*)malloc(sizeof(GUID)*count);
                img2.GetFrameDimensionsList(pDimensionIDs, count);
                framecount=img2.GetFrameCount(&pDimensionIDs[0]);
                framedelay =img2.GetPropertyItemSize(PropertyTagFrameDelay);
                img=new Image(towstring(filename).c_str());
                isimgused=true;
                free(pDimensionIDs);
            }
        }
    };

    property<Gdiplus::Color> Backcolor
    {
        Get(Gdiplus::Color)
        {
            return clrBackColor;
        },
        Set(Gdiplus::Color bkcolor)
        {
            clrBackColor = bkcolor;
            SetDCBrushColor(hdcimage,clrBackColor.ToCOLORREF());
        }
    };

    void draw(HDC control)
    {
        //if (clrBackColor.GetValue() == Gdiplus::Color::Transparent)
        if (clrBackColor.GetValue()== Gdiplus::Color::Transparent)
        {
            TransparentBlt(control, 0, 0,width(),height(),hdcimage, 0, 0,width(), height(), GetPixel(hdcimage,width()-1,height()-1));
        }
        else
        {
            BitBlt(control,0,0,width(),height(),hdcimage,0,0,SRCCOPY);
        }
        //InvalidateRect(WindowFromDC(control),NULL,false);
    }

    operator HICON()
    {
        return HICONFromHBITMAP(btBitmap);
    }

    operator HBITMAP()
    {
        return btBitmap;
    }

    int height()
    {
        return imageheight;
    }

    int width()
    {
        return imageweight;
    }

    operator HDC()
    {
        return hdcimage;
    }

    bool operator != ( nullptr_t ) const
    {
        return btBitmap != nullptr;
    }

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

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

    bool haveimage()
    {
        if(btBitmap==NULL)
            return false;
        else
            return true;
    }

    ~image()
    {
        Gdiplus::GdiplusShutdown(m_gdiplusToken);
        SelectObject(hdcimage, obj);
        DeleteObject(btBitmap);
        DeleteDC(hdcimage);
        if(isimgused==true)
            delete img;
    }
};

using the constructor:

image(int width, int height)
    {
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        hdcimage = CreateCompatibleDC(NULL);
        btBitmap = CreateBitmap(width,height,1,32,NULL);
        obj = SelectObject(hdcimage, btBitmap);
        framecount=1;
        imageheight=height;
        imageweight=width;
    }

i'm trying the double buffer.
but the button(the 1st button) is drawed with big size:

case WM_DRAWITEM:
            {
                DRAWITEMSTRUCT *test=(DRAWITEMSTRUCT*) lParam;
                image imgButton(test->rcItem.right-test->rcItem.left,test->rcItem.bottom-test->rcItem.top);

                if(test->CtlType==ODT_BUTTON)
                {
                    SelectObject(imgButton,CreateSolidBrush(GetSysColor(COLOR_BTNFACE)));

                    HTHEME hTheme = OpenThemeData(inst->hwnd, L"BUTTON");
                    //fill the background with button face color
                    if ( test->itemState & ODS_SELECTED) // If it is pressed
                    {
                        FillRect(imgButton, &test->rcItem,(HBRUSH) GetSysColor(COLOR_BTNFACE));
                        DrawEdge(imgButton,&test->rcItem,EDGE_SUNKEN,BF_RECT); // Draw a sunken face
                    }
                    else if ( test->itemState & ODS_DISABLED)
                    {
                        FillRect(imgButton, &test->rcItem,(HBRUSH) CreateSolidBrush(RGB(192,192,192)));
                        DrawEdge(imgButton, &test->rcItem,EDGE_RAISED,BF_RECT);
                    }
                    else
                    {
                        FillRect(imgButton, &test->rcItem,(HBRUSH) GetSysColor(COLOR_BTNFACE));
                        DrawEdge(imgButton, &test->rcItem,EDGE_RAISED,BF_RECT); // Draw a raised face
                    }

                    RECT rectext=test->rcItem;
                    rectext.top=3;
                    rectext.left=3;

                    if ( test->itemState & ODS_DISABLED)
                    {
                        DrawHICONtoHDC(imgButton,CreateGrayscaleIcon(inst->imgtest),1,1);
                        DrawThemeText(hTheme, imgButton, BP_PUSHBUTTON, PBS_DISABLED,towstring(inst->strCaption).c_str(),-1,DT_LEFT|DT_HIDEPREFIX,0,&rectext);
                    }
                    else
                    {
                        DrawHICONtoHDC(imgButton, inst->imgtest,1,1);
                        SetTextColor(imgButton,inst->clrTextColor);
                        SetBkMode(imgButton,TRANSPARENT);//text background transparent
                        DrawText(imgButton,inst->strCaption.c_str(),-1,&rectext,DT_LEFT);
                    }

                    HPEN pen = CreatePen(PS_DOT,1,RGB(0,0,0));//these is the must close to the rectangle focus style
                    SelectObject(imgButton,pen);

                    if ( (test->itemState & ODS_FOCUS ) || (inst->blnMouseEnter==true)) // If the button is focused
                    {
                        int iChange = 3;
                        test->rcItem.top += iChange;
                        test->rcItem.left += iChange;
                        test->rcItem.right -= iChange;
                        test->rcItem.bottom -= iChange;
                        SelectObject(imgButton,GetStockObject(NULL_BRUSH));//the rectangle will be transparent
                        Rectangle(imgButton, test->rcItem.left, test->rcItem.top, test->rcItem.right, test->rcItem.bottom);
                    }
                    BitBlt(test->hDC,0,0,imgButton.width(), imgButton.height(), imgButton,0,0,SRCCOPY);
                    CloseThemeData(hTheme);
                }
            }
            break;

//inst is the button object pointer

maybe i have another problem with image destructor because the program takes time to end.
what i'm doing wrong?

the problem was not the button, but the label.
heres how i get the control size:

//getting the text rectangle size
            RECT textrect={0};            
            DrawText (GetDC(hwnd),strCaption.c_str(),strCaption.size(),&textrect,DT_CALCRECT);

            //testing the image size
            //i add more 7 for get size for draw a border or something
            if(imgtest.haveimage())
            {
                if((textrect.bottom-textrect.top)<imgtest.height())
                    intHeight=imgtest.height()+7;
                if((textrect.right-textrect.left)<imgtest.width())
                    intWidth=imgtest.width()+7;
            }
            else
            {
                intHeight=textrect.bottom+7;
                intWidth=textrect.right+7;
            }

            //resize the control
            SetWindowPos(hwnd, 0, 0, 0,intWidth,intHeight,
                SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOCOPYBITS);

i have 1 question: how can i get the border size?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.