[C\C++] - my menu double buffer don't works:(

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
heres my structure and menu function:struct ImageInfo
{
HBITMAP ImageImage;
BITMAP Imagebm;
HDC ImagehdcMem;
HBITMAP ImageMaskImage;
BITMAP ImageMaskbm;
HDC ImageMaskhdcMem;
};

enum DrawWay {Normal, Stretch};

class Image
{
//if MaskColor is -2 then the transparency is ignored;
//if MaskColor is -1 then the transparent color is the pixel 0,0
public : void Load(ImageInfo &imagem, char *FileName,COLORREF MaskColor)
{
int posx;
int posy;

COLORREF b;


//Load the image
imagem.ImageImage = (HBITMAP)LoadImage(0, FileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
GetObject(imagem.ImageImage , sizeof(BITMAP), &imagem.Imagebm);
imagem.ImagehdcMem = CreateCompatibleDC(NULL);
SelectObject(imagem.ImagehdcMem, imagem.ImageImage);

//Create the mask
if (MaskColor==-2)
{
//dont do the mask
}
else
{
imagem.ImageMaskImage = (HBITMAP)LoadImage(0, FileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
GetObject(imagem.ImageMaskImage , sizeof(BITMAP), &imagem.ImageMaskbm);
imagem.ImageMaskhdcMem = CreateCompatibleDC(NULL);
SelectObject(imagem.ImageMaskhdcMem, imagem.ImageMaskImage);

if (MaskColor==-1) MaskColor= GetPixel(imagem.ImageMaskhdcMem,0 ,0);

for (posy=0;posy<imagem.Imagebm.bmHeight;posy++)
{
for (posx=0;posx<imagem.Imagebm.bmWidth ;posx++)
{
b=GetPixel(imagem.ImageMaskhdcMem,posx,posy);
if (b==MaskColor)
SetPixel(imagem.ImageMaskhdcMem,posx,posy,RGB(255,255,255));
else
SetPixel(imagem.ImageMaskhdcMem,posx,posy,RGB(0,0,0));
}
}
}
}

public: void Draw(HDC &Destination, ImageInfo &Origem, BOOL Transparent, int PosX, int PosY, int Width, int Height,DrawWay dwDraw)
{
if (Transparent==TRUE)
{
if (dwDraw==Stretch)
{
StretchBlt (Destination,
PosX, PosY,
Width, Height,
Origem.ImagehdcMem,
0, 0,
Origem.Imagebm.bmWidth, Origem.Imagebm.bmHeight,SRCINVERT);
StretchBlt (Destination,
PosX, PosY,
Width, Height,
Origem.ImageMaskhdcMem,
0, 0,
Origem.Imagebm.bmWidth, Origem.Imagebm.bmHeight, SRCAND);
StretchBlt (Destination,
PosX, PosY,
Width, Height,
Origem.ImagehdcMem,
0, 0,
Origem.Imagebm.bmWidth, Origem.Imagebm.bmHeight, SRCINVERT);
}
else if (dwDraw==Normal)
{
BitBlt( Destination,
PosX, PosY,
Origem.Imagebm.bmWidth, Origem.Imagebm.bmHeight,
Origem.ImagehdcMem,
0, 0,
SRCINVERT);

BitBlt( Destination,
PosX, PosY,
Origem.Imagebm.bmWidth, Origem.Imagebm.bmHeight,
Origem.ImageMaskhdcMem,
0, 0,
SRCAND);
BitBlt( Destination,
PosX, PosY,
Origem.Imagebm.bmWidth, Origem.Imagebm.bmHeight,
Origem.ImagehdcMem,
0, 0,
SRCINVERT);
}
}
else
{
if (dwDraw==Stretch)
{
StretchBlt (Destination,
PosX, PosY,
Width, Height,
Origem.ImagehdcMem,
0, 0,
Origem.Imagebm.bmWidth, Origem.Imagebm.bmHeight,SRCCOPY);
}
else
{
BitBlt( Destination,
PosX, PosY,
Origem.Imagebm.bmWidth, Origem.Imagebm.bmHeight,
Origem.ImagehdcMem,
0, 0,
SRCCOPY);
}
}
}

public: void Destroy(ImageInfo &BitmapImage)
{
DeleteDC(BitmapImage.ImagehdcMem);
DeleteObject((HBITMAP)BitmapImage.ImageImage);
}
};


int Menu(int PosX, int PosY, char *Items, COLORREF TextColor=RGB(255,255,255),COLORREF TextBackColor=RGB(0,0,255),COLORREF BackColor= RGB(0,0,0), char *ItemImage=NULL, char *BackgrounImage=NULL)
{
const KEY_DOWN = 0x8000;
const KEY_UP = 0x1;
char sentences[40][255];
int i=0;
int a=0,b=0;
int intItem=0;
int Item=OPAQUE;
Colors clra;
Image ImageOperations;
ImageInfo MenuImage;
ImageInfo BackgroundMenuImage;
ImageInfo DoubleBuffer;
Window Console;
RECT rec;
HBRUSH Hbrush;

//testing if the items and images(strings) was enter
if (Items==NULL) return -1;
if (ItemImage!=NULL) ImageOperations.Load(MenuImage,ItemImage,-1);
if (BackgrounImage!=NULL) ImageOperations.Load(BackgroundMenuImage,BackgrounImage,-2);

//Getting the window handle and DC;
GetConsoleHwnd(Console);//works fine

//separe the items from ; symbol and put them on a string array
for(i=0; Items!=; i++)
{
if(Items==;)
{
sentences[a]=;
b=0;
a=a+1;

}
else
{
sentences[a]=Items;
b=b+1;
}
}
sentences[a]=;
a=a+1;

//prepare the double buffer to window rect or background image
GetWindowRect(Console.WindowHandle,&rec);
DoubleBuffer.ImagehdcMem = CreateCompatibleDC (Console.WindowDC);
if(BackgrounImage==NULL)
DoubleBuffer.ImageImage = CreateCompatibleBitmap (Console.WindowDC,rec.right-rec.left, rec.bottom-rec.top);
else
DoubleBuffer.ImageImage = CreateCompatibleBitmap (Console.WindowDC,BackgroundMenuImage.Imagebm.bmWidth , BackgroundMenuImage.Imagebm.bmHeight);
SelectObject (DoubleBuffer.ImagehdcMem, DoubleBuffer.ImageImage );

//change the backcolor before draw something
Hbrush=CreateSolidBrush(BackColor);
SelectObject(DoubleBuffer.ImagehdcMem,Hbrush);
Rectangle( DoubleBuffer.ImagehdcMem,0,0,rec.right,rec.bottom);

//change text color and text background
SetBkColor(DoubleBuffer.ImagehdcMem,TextBackColor);
SetTextColor(DoubleBuffer.ImagehdcMem,TextColor);

//draw the text items to double buffer
for (i=0; i<a; i++)
{
if (TextBackColor==-1) Item = TRANSPARENT; else Item = OPAQUE;
if (i==intItem)
SetBkMode(DoubleBuffer.ImagehdcMem,Item);
else
SetBkMode(DoubleBuffer.ImagehdcMem, TRANSPARENT);
TextOut(DoubleBuffer.ImagehdcMem,PosX,PosY+(30*i),sentences,strlen(sentences) );
}
//draw the images to double buffer if any
if (ItemImage!=NULL) ImageOperations.Draw( DoubleBuffer.ImagehdcMem,BackgroundMenuImage,false,0,0,0,0,Normal);
if (BackgrounImage!=NULL) ImageOperations.Draw( DoubleBuffer.ImagehdcMem,MenuImage,true,PosX-50,PosY + (30*intItem)-3,0,0,Normal);

//draw to windows
BitBlt( Console.WindowDC ,0,0,DoubleBuffer.Imagebm.bmWidth,DoubleBuffer.Imagebm.bmHeight, DoubleBuffer.ImagehdcMem,0,0,SRCCOPY);

while(1)
{
//draw the text items to double buffer
for (i=0; i<a; i++)
{
if (TextBackColor==-1) Item = TRANSPARENT; else Item = OPAQUE;
if (i==intItem)
SetBkMode(DoubleBuffer.ImagehdcMem,Item);
else
SetBkMode(DoubleBuffer.ImagehdcMem, TRANSPARENT);
TextOut(DoubleBuffer.ImagehdcMem,PosX,PosY+(30*i),sentences,strlen(sentences) );

//draw double buffer to window
BitBlt( Console.WindowDC ,0,0,DoubleBuffer.Imagebm.bmWidth,DoubleBuffer.Imagebm.bmHeight, DoubleBuffer.ImagehdcMem,0,0,SRCCOPY);
}
if ((GetAsyncKeyState(VK_UP) & KEY_UP) == KEY_UP)
{
if (intItem==0)
{
intItem=a-1;
}
else
{
intItem=intItem-1;
}
//draw to double buffer and then to windows
Rectangle(DoubleBuffer.ImagehdcMem,0,0,rec.right,rec.bottom);
if (ItemImage!=NULL) ImageOperations.Draw( DoubleBuffer.ImagehdcMem,BackgroundMenuImage,false,0,0,0,0,Normal);
if (BackgrounImage!=NULL) ImageOperations.Draw( DoubleBuffer.ImagehdcMem,MenuImage,true,PosX-50,PosY + (30*intItem)-3,0,0,Normal);
BitBlt( Console.WindowDC ,0,0,DoubleBuffer.Imagebm.bmWidth,DoubleBuffer.Imagebm.bmHeight, DoubleBuffer.ImagehdcMem,0,0,SRCCOPY);

}
else if ((GetAsyncKeyState(VK_DOWN) & KEY_UP) == KEY_UP)
{
if (intItem==a-1)
{
intItem=0;
}
else
{
intItem=intItem+1;
}
//draw to double buffer and then to windows
Rectangle( DoubleBuffer.ImagehdcMem,0,0,rec.right,rec.bottom);
if (ItemImage!=NULL) ImageOperations.Draw( DoubleBuffer.ImagehdcMem,BackgroundMenuImage,false,0,0,0,0,Normal);
if (BackgrounImage!=NULL) ImageOperations.Draw( DoubleBuffer.ImagehdcMem,MenuImage,true,PosX-50,PosY + (30*intItem)-3,0,0,Normal);
BitBlt( Console.WindowDC ,0,0,DoubleBuffer.Imagebm.bmWidth,DoubleBuffer.Imagebm.bmHeight, DoubleBuffer.ImagehdcMem,0,0,SRCCOPY);
}
else if ((GetAsyncKeyState(VK_RETURN) & KEY_UP) == KEY_UP)
{
break;
}
}
//clean the memoryimages and double buffer
DeleteObject((HBITMAP)DoubleBuffer.ImageImage);
if (BackgrounImage!=NULL) ImageOperations.Destroy( BackgroundMenuImage);
if (ItemImage!=NULL) ImageOperations.Destroy( MenuImage);
DeleteObject(Hbrush);
return intItem;
}
my problem is realy inside of my menu code... if i dont use the DoubleBuffer, the code works normaly(with a flicker, sometimes). but i dont understand what im doing wrong with my double buffer:(
can anyone advice me?

View the full article
 
Back
Top