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?