Ir ao conteúdo

double buffer\pisca\flicker


Cambalinho

Posts recomendados

Postado

eu tenho 1 codigo que movo 1 imagem, mas da-me 1 especie de flicker:


#include <conio2.h>
#include <stdio.h>
#include <windows.h>


void DrawBitmap(HDC hdcDest, char* filename, int x, int y);
void DrawTransparentBitmap(HDC hdcDest, char *filename, int x, int y, int width, int height, COLORREF a );
void apidoevents();

HWND foco;
HDC a;

int main()
{
foco = GetForegroundWindow();
a=GetDC( foco);
HBRUSH b;
HPEN c;
SetWindowPos(foco, 0, 100, 100, 500, 500, 0);
int x=0;
int y=0;


SetWindowText(foco, "Draw image and rectangle with brush and pen sample");
fflush(stdin);
do
{

clrscr();
backcolor(RED);
textcolor(WHITE);
//DrawBitmap(a,"C:\\test\\Bleu Battle.bmp",0,0);
DrawBitmap(a,"C:\\Users\\Public\\Pictures\\Sample Pictures\\Chrysanthemum.bmp",0,0);
DrawTransparentBitmap(a,"C:\\test\\Bleu Battle.bmp",x,y,100,100, -1);

c=CreatePen(PS_DOT, 1, RGB(255,0,0));
SelectObject( a, c);

b=CreateHatchBrush(HS_CROSS, RGB(255,0,0));
SelectObject( a,b );
//SelectObject( a, CreateSolidBrush(RGB(0,255,0)));

Rectangle(a,100,0,150,50);
//RedrawWindow(foco,NULL, NULL, RDW_UPDATENOW);
//apidoevents();
getch();
if (GetAsyncKeyState (VK_LEFT) & 0x8000)
x=x-1;
else if (GetAsyncKeyState (VK_RIGHT) & 0x8000)
x=x+1;
else if (GetAsyncKeyState (VK_UP) & 0x8000)
y=y-1;
else if (GetAsyncKeyState (VK_DOWN) & 0x8000)
y=y+1;

}
while(!(GetAsyncKeyState (VK_RETURN) & 0x8000));
DeleteObject (c);
DeleteObject (B);
fflush(stdin);
getch();
ReleaseDC(foco,a);
return 0;
}

void DrawBitmap(HDC hdcDest, char *filename, int x, int y)
{
HBITMAP image;
BITMAP bm;
HDC hdcMem;
image = (HBITMAP)LoadImage(0, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
GetObject(image, sizeof(BITMAP), &bm);
hdcMem = CreateCompatibleDC(hdcDest);

SelectObject(hdcMem, image);

BitBlt(
hdcDest,
x, y,
bm.bmWidth, bm.bmHeight,
hdcMem,
0, 0,
SRCCOPY);

/*StretchBlt (hdcDest,
x, y,
300, 300,
hdcMem,
0, 0,
bm.bmWidth, bm.bmHeight, SRCCOPY);*/

DeleteDC(hdcMem);
DeleteObject((HBITMAP)image);
}

void DrawTransparentBitmap(HDC hdcDest, char *filename, int x, int y, int width, int height, COLORREF a )
{
//posiçoes no ciclo for
int posx=0;
int posy=0;

//para comparar os pixels
COLORREF b;

//a imagem normal
HBITMAP image;
BITMAP bm;
HDC hdcMem;

//a mascara da imagem
HBITMAP imagemask;
BITMAP bmmask;
HDC hdcMemmask;



//criar 1 imagem normal do ficheiro
image = (HBITMAP)LoadImage(0, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
GetObject(image, sizeof(BITMAP), &bm);
hdcMem = CreateCompatibleDC(hdcDest);
SelectObject(hdcMem, image);

//criar 1 imagem normal do ficheiro para fazer a mascara
imagemask= (HBITMAP)LoadImage(0, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
GetObject(imagemask, sizeof(BITMAP), &bmmask);
hdcMemmask = CreateCompatibleDC(hdcDest);
SelectObject(hdcMemmask, imagemask);

//if a is -1, isso quer dizer que o pixel 0,0 - Automatico
if (a==-1) a=GetPixel(hdcMemmask,0,0);

if (width==0) width=bm.bmWidth;
if (height==0) height=bm.bmHeight;
//se a cor b for igual á cor a(cor que tem de ser transparente)
//a cor da mascara tem de ser branca
//caso contrario é preta
for (posy=0;posy<bm.bmHeight;posy++)
{
for (posx=0;posx<bm.bmWidth ;posx++)
{
b=GetPixel(hdcMemmask,posx,posy);
if (b==a)
SetPixel(hdcMemmask,posx,posy,RGB(255,255,255));
else
SetPixel(hdcMemmask,posx,posy,RGB(0,0,0));
}
}

//esta parte copia a imagem com a mask(fazendo a transparencia)
//1 - bitblt\stretchblt com bitmap vbSrcInvert
//1 - bitblt\stretchblt com bitmap mask vbSrcAnd
//1 - bitblt\stretchblt com bitmap vbSrcInvert
/*BitBlt(
hdcDest,
x, y,
bm.bmWidth, bm.bmHeight,
hdcMem,
0, 0,
SRCINVERT);
BitBlt(
hdcDest,
x, y,
bm.bmWidth, bm.bmHeight,
hdcMemmask,
0, 0,
SRCAND);
BitBlt(
hdcDest,
x, y,
bm.bmWidth, bm.bmHeight,
hdcMem,
0, 0,
SRCINVERT);*/

//SetStretchBltMode(hdcDest,STRETCH_ANDSCANS);
StretchBlt (hdcDest,
x, y,
width, height,
hdcMem,
0, 0,
bm.bmWidth, bm.bmHeight,SRCINVERT);
StretchBlt (hdcDest,
x, y,
width, height,
hdcMemmask,
0, 0,
bm.bmWidth, bm.bmHeight, SRCAND);
StretchBlt (hdcDest,
x, y,
width, height,
hdcMem,
0, 0,
bm.bmWidth, bm.bmHeight, SRCINVERT);

//temos de apagar os DC's e os objectos

//quando usamos CreateCompatibleDC() temos de usar o DeleteDC()
//para apagar o resultado do CreateCompatibleDC()
DeleteDC(hdcMem);
DeleteDC(hdcMemmask);

//quando usamos SelectObject() temos de usar o DeleteObject()
//para apagar o resultado do DeleteObject()
//neste caso o resultado de LoadImage()
DeleteObject((HBITMAP)image);
DeleteObject((HBITMAP)imagemask);
}
#include <conio.h>

como posso evitar isso?

Postado

a funçao GetForegroundWindow() fornece-nos o handle correcto?

eu pergunto isto, poque quando meto metade janela fora do ecra ou quando fica a janela á frente desta, o ciclo do..while nao mostra a imagem e nao percebo o porque. algumas dicas?

Postado

eis 1 codigo para captar o verdadeiro HWND e HDC da consola:

struct Window
{
HWND WindowHandle;
HDC WindowDC;
};

int GetConsoleHwnd(Window &console)
{

#define MY_BUFSIZE 1024 // Buffer size for console window titles.
HWND hwndFound; // This is what is returned to the caller.
char pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
// WindowTitle.
char pszOldWindowTitle[MY_BUFSIZE]; // Contains original
// WindowTitle.

// Fetch current window title.

GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);

// Format a "unique" NewWindowTitle.

wsprintf(pszNewWindowTitle,"%d/%d",
GetTickCount(),
GetCurrentProcessId());

// Change current window title.

SetConsoleTitle(pszNewWindowTitle);

// Ensure window title has been updated.

Sleep(10);

// Look for NewWindowTitle.

hwndFound=FindWindow(NULL, pszNewWindowTitle);

// Restore original window title.

SetConsoleTitle(pszOldWindowTitle);
console.WindowHandle =hwndFound;
console.WindowDC =GetDC( hwndFound);

return 0;
}

mesmo que fique 1 janela á frente, nunca perdemos as imagens.

ao inserir-mos varias subimagens no ecra(window), mostra sempre flickers. mas ao usar 1 variavel para inserir as subimagens e depois meter no ecra, o flicker desparece:


struct Images
{
HBITMAP ImageImage;
BITMAP Imagebm;
HDC ImagehdcMem;
HBITMAP ImageMaskImage;
BITMAP ImageMaskbm;
HDC ImageMaskhdcMem;
};

Images DoubleBuffer;

//Criar o DoubleBuffer
DoubleBuffer.ImagehdcMem = CreateCompatibleDC ( Console.WindowDC );
DoubleBuffer.ImageImage = CreateCompatibleBitmap ( Console.WindowDC, ImageBackGround.Imagebm.bmWidth , ImageBackGround.Imagebm.bmHeight );
SelectObject ( DoubleBuffer.ImagehdcMem, DoubleBuffer.ImageImage );

//Inserir as subimagens no DoubleBuffer
//eu usei 1 funçao minha(por causa de mascara e nao só), mas podem usar bitblt() ou outra
DrawImages(DoubleBuffer.ImagehdcMem ,ImageBackGround,FALSE,0,0,0,0,Normal);

//apos isso eis como eu as meto no ecra
BitBlt(Console.WindowDC,0,0,ImageBackGround.Imagebm.bmWidth ,ImageBackGround.Imagebm.bmHeight ,DoubleBuffer.ImagehdcMem ,0,0,SRCCOPY);

a minha livraria vai ser partilhada, mas vou ver onde;)

  • Moderador
Postado

Caso o autor do tópico necessite, o mesmo será reaberto, para isso deverá entrar em contato com a moderação solicitando o desbloqueio.

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!