Screenmate defectueux

cs_anthraxx Messages postés 47 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 9 juin 2004 - 25 avril 2003 à 17:17
cs_anthraxx Messages postés 47 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 9 juin 2004 - 27 avril 2003 à 13:08
Anthrax ignisque -- Le charbon et le feu >:)

J'essaye de faire un screenmate (une petite bestiole se promenant sur les fenetres), mais n'etant pas tres experimenté en C++ j'arrive pas a faire un truc qui se deplace correctement tout en etant animé!

En effet, mon animal (un gentil petit ver de terre) laisse une trainée noire derriere lui après être passé!

C'est la faute de SetWindowPos: j'ai mis le flag SWP_NOREDRAW. Seulement, si je le mets pas, des evenements WM_PAINT arrivent en cascade et rien ne marche plus!
j'ai essaye de ne pas appeler SetWindowPos depuis l'evenement WM_PAINT, seulement depuis WM_TIMER, mais ça ne marche pas non plus (le ver clignote sans arret...)

Aidez-moi!!! Je suis sur que comme ce code est entierement made by moi il y a plein de choses qui peuvent

être ameliorees, en plus bien sur de mon probleme d'effaçage.

Le code entier est bcp trop long, mais voici les morceaux mis en cause...

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc; // device context (DC) for window
PAINTSTRUCT ps; // paint data for BeginPaint and EndPaint
static bool mouseDown; // true si on est en train de bouger l'animal (un ver)
static int mouseX,mouseY; // position de la souris (coordonnees relatives à la fenetre)

switch (uMsg)
{
case WM_CREATE:
{
hdc=GetDC(hwnd); // obtient le hdc de la fenetre
hdcWorm = CreateCompatibleDC(hdc); // cree un hdc pour l'image du ver
DrawWorm(hwnd,hdc); // dessine le ver une premiere fois
ReleaseDC(hwnd,hdc);
UINT ret SetTimer(hwnd, TIMER_ID, 50, NULL); //TIMER_ID est #defini1
if(!ret) MessageBox(hwnd,"Could not SetTimer()!","Error",MB_OK|MB_ICONEXCLAMATION);
break;
}

case WM_TIMER:
hdc = GetDC(hwnd);
UpdateWorms(hwnd, hdc); // on deplace le ver et change l'image (il est animé!)
DrawWorm(hwnd, hdc); // puis on le dessine
ReleaseDC(hwnd, hdc);
break;

case WM_LBUTTONDBLCLK:
PostMessage(hwnd, WM_CLOSE, 0, 0); // ferme le programme qd on doubleclique
break;

case WM_PAINT:
hdc=BeginPaint(hwnd, &ps);
DrawWorm(hwnd,hdc); // dessine l'animal sans le Updater
EndPaint(hwnd, &ps);
break;

case WM_LBUTTONDOWN:
ReleaseCapture();
SetCapture(hwnd);
mouseDown=true;
mouseX=LOWORD(lParam);
mouseY=HIWORD(lParam);
break;

case WM_MOUSEMOVE:
if(mouseDown)
{
POINT pt={LOWORD(lParam),HIWORD(lParam)};
ClientToScreen(hwnd,&pt);
wWorm.x=pt.x-mouseX;
wWorm.y=pt.y-mouseY;
}
break;

case WM_LBUTTONUP:
mouseDown=false;
ReleaseCapture();
break;

case WM_DESTROY:
PostQuitMessage(0);
break;

case WM_CLOSE:
DeleteDC(hdcWorm);
DeleteObject(hBmpWorm);
DeleteObject(hWormRgn);
KillTimer(hwnd,TIMER_ID);
return DefWindowProc(hwnd, uMsg, wParam, lParam);

default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return (LRESULT) NULL;
}

void UpdateWorms(HWND hwnd,HDC hdc)
{
// ... ici du code qui change wWorm.x et y, et verifie si on est pas au bout de l'ecran
// ... ici du on modifie wWorm.frame pour avoir la ressource d'image souhaitée
SetWormImage(hwnd,hdc,MAKEINTRESOURCE(wWorm.frame));
}

void DrawWorm(HWND hwnd, HDC hdc)
{
SetWindowPos(hwnd,HWND_TOPMOST,wWorm.x,wWorm.y,wWorm.width,wWorm.height,SWP_NOREDRAW);
//NOREDRAW sinon on a des evenements WM_PAINT en cascade qui s'arretent pas
BitBlt(hdc,0,0,wWorm.width,wWorm.height,hdcWorm,0,0,SRCCOPY);
}

void SetWormImage(HWND hwnd, HDC hdc, LPCSTR resnumber)
{
// je sais pas trop a kwa sa sert, j'ai mis cette instruction pr essayer
// il se trouve que ça marche un peu mieux
// (le ver laisse une trainée noire au lieu d'une trainée colorée)...
SendMessage(hwnd,WM_ERASEBKGND,(WPARAM)hdc,NULL);

DeleteObject(hWormBmp);
hWormBmp = LoadBitmap(hInst, resnumber);
SelectObject(hdcWorm, hWormBmp); //copie le bitmap dans le device context

hWormRgn=BmpToRgn(hWormBmp,&wWorm.width,&wWorm.height,0); // change la region a partir du bitmap
// (les points noirs (d'ou le 0) deviennent transparents)
SetWindowRgn(hwnd,hWormRgn,FALSE);
}

2 réponses

BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 20
25 avril 2003 à 18:55
Salut,
c'est un bon début mais je pense que tu te focalises sur la résolution de ta méthode. Le prob est que c'est elle qu'il faut changer et non le code à améliorer. Le mouvement sans clignotement a besoin d'une autre approche.
Comme serait trop long à expliquer, tu vas voir:
ABOUTBOX SINUSOIDE
tu suis bien le deroulement du code pour voir les étapes des BitBlt() et autres. Devrait faire ton affaire.
BruNews, ciao...
0
cs_anthraxx Messages postés 47 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 9 juin 2004
27 avril 2003 à 13:08
Anthrax ignisque -- Le charbon et le feu >:)
0