Repeindre une région depuis une portion d'un Tbitmap

Résolu
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 - 15 août 2005 à 23:11
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 - 21 août 2005 à 17:25
Donc voila mon probleme : J'ai une appli, j'ai pas envie de boutons ni de Timages ni de composants externes ( j'apprends) dedans, et je travaille avec des if PtInRegion(....) et les onMouseUp/down de la form. Jusque là facile. Apres j'ai deux bitmaps, de la taille de la form, l'un présentant la form avec tout les boutons "éteint", et l'autres tout les boutons "allumés".

Le but étant lorsque j'ai le OnMouseDown dans une région, de repeindre la dite région (donc de repeindre localement le canvas de ma form) avec le bouton allumé, prélevé dans le bitmap idoine, aux coordonnées adéquates. Et de meme avec le onMouseUp, donc.

Et je vois pas comment faire.....


A l'aide :-)

12 réponses

DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
21 août 2005 à 17:25
Allez hop, probleme résolu :

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);


var CurrRect:TRect;
CurrRgn:HRGN;
begin


CurrRgn:=0;


if PtInRegion(RgnPRV,X,Y) then CurrRgn:=RgnPRV;


if PtInRegion(RgnPLAY,X,Y) then CurrRgn:=RgnPLAY;


if PtInRegion(RgnPAUS,X,Y) then CurrRgn:=RgnPAUS;


if PtInRegion(RgnSTOP,X,Y) then CurrRgn:=RgnSTOP;


if PtInRegion(RgnNXT,X,Y) then CurrRgn:=RgnNXT;


if PtInRegion(RgnTINY,X,Y) then CurrRgn:=RgnTINY;


if (CurrRgn <> 0) then
begin
GetRgnBox(CurrRgn,CurrRect);
SelectClipPath(CurrRgn,Rgn_Copy);
SelectClipRgn(Form1.Canvas.Handle,CurrRgn);


BitBlt(Form1.Canvas.Handle,
CurrRect.Left,
CurrRect.Top,
CurrRect.Right,
CurrRect.Bottom,
LayoutON.Canvas.Handle,
CurrRect.Left,
CurrRect.Top,
SrcCopy);


SelectClipRgn(Form1.Canvas.Handle,0); // pas oublier !
end;
end;

Autre chose, toujours déclarer une région avec 1 ligne et une colonne de pixels de plus (bottom/right), certaines fonctions rognent.

gnh !
3
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
16 août 2005 à 04:13
var
Form1: TForm1;
BitmapBoutonUp:TBitmap;
BitmapBoutonDown:TBitmap;
implementation


{$R *.dfm}


procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
case X of // si coordonné x de la zone du bouton
1..100: case Y of
1..100:begin // si coordonné Y de la zone du bouton
canvas.Draw(1,1,BitmapBoutonDown);
end;
end;
end;


end;


procedure TForm1.FormCreate(Sender: TObject);
begin
BitmapBoutonUp:=TBitmap.Create;
BitmapBoutonUp.LoadFromFile('c:\BitmapBoutonUp.bmp');
// load from ressource ou autre ...


BitmapBoutonDown:=TBitmap.Create;
BitmapBoutonDown.LoadFromFile('c:\BitmapBoutonDown.bmp');
end;


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeAndNil(BitmapBoutonUp);
FreeAndNil(BitmapBoutonDown);
end;


procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
case X of
1..100: case Y of
1..100:begin
canvas.Draw(1,1,BitmapBoutonUp);
end;
end;
end;
end;


end.

yve
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
16 août 2005 à 10:20
Merci.... Ca ne repeint qu'un pixel a chaque fois, ou bien ? Mon probleme est de repeindre une région cliquée en entier.


Je pense qu'un GetRgnBox pour avoir le rectangle englobant de la région et une recopie pixel a pixel avec test de PtInRegion pourrait marcher, mais ca risque pas de ramer ?
0
florenth Messages postés 1023 Date d'inscription dimanche 1 août 2004 Statut Membre Dernière intervention 17 août 2008 3
16 août 2005 à 14:41
Inspires toi de cela:

<hr size= "2" width="100%"> var

Form1: TForm1;

B: HRGN;



implementation



{$R *.dfm}



procedure TForm1.FormCreate(Sender: TObject);

begin

B : = CreateEllipticRgn(100,100,200,200);

end;



procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

begin

if PtInRegion(B,X,Y) then

begin

Canvas.Brush.Color := clBlue;

PaintRgn(Canvas.Handle,B);

end

else

begin

Canvas.Brush.Color := clWhite;

PaintRgn(Canvas.Handle,B);

end

end;



procedure TForm1.FormDestroy(Sender: TObject);

begin

DeleteObject(B);

end;

<hr size ="2" width="100%">Je ne sais pas s'il y a un équivalent à PaintRgn mais qui dessinerait des bitmaps mas l'idée est là je pense.



@ ++ Florent


Si tu ne te plantes pas ......
tu ne poussera jamais
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
16 août 2005 à 16:15
Oui, l'idée est là et j'en était arrivé au meme point avant de m'interroger sur repeindre une région à partir d'un morceau de bitmap.

gnh !
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
17 août 2005 à 00:01
Bon, c'est jouissif ce truc, entre getcursor (qui marche pas lors d'un evenement onclick) et les x,y d'un onclick (par exemple) qui ne travaillent pas dans les meme coordonnées ( form.left et form.top a ajouter)

et ces foutues régions qui elles sont définie dans les unités écran encore différentes, je rame !

Mais bon, je m'en suis sorti (a peu pres):

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var RectPaint: Trect;

begin
if PtInRegion(RgnPRV,X+Form1.Left,Y+Form1.Top) then
begin

GetRgnBox(RgnPRV,RectPaint);
RectPaint.Top :=RectPaint.Top-Form1.Top;
RectPaint.Left :=RectPaint.Left-Form1.Left;
RectPaint.Bottom:=RectPaint.Bottom-Form1.Top;
RectPaint.Right :=RectPaint.Right-Form1.Left;


Form1.Canvas.Brush.Color:=clBackground;
Form1.Canvas.BrushCopy RectPaint,LayoutOFF,RectPaint,clBackground);


end;


end;

On va dire que ca marche, Delphi me dit que BrushCopy est dépassé, et mes régions sont rectangulaires, donc ne présentent aucun interet, vu que truc ci dessus recopie un rectangle, je pouvais bosser avec des Timages....

Pour profiter des régions pleinement reste a recopier les bons pixels (ceux de la région) et pas tous.

gnh !
0
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
17 août 2005 à 01:11
var
Form1: TForm1;
BitmapBoutonUp:TBitmap;
BitmapBoutonDown:TBitmap;
HRegion:HRGN;


implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
BitmapBoutonUp:=TBitmap.Create;
BitmapBoutonUp.LoadFromFile('c:\BitmapBoutonUp.bmp');
BitmapBoutonDown:=TBitmap.Create;
BitmapBoutonDown.LoadFromFile('c:\BitmapBoutonDown.bmp');


HRegion:=CreateEllipTicRgn(0,0,100,100);
//HRegion c'est la région du bouton, devrais correspondre avec
//l'image du bouton que l'on va dessiner plus tard (selectClipRgn(Canvas.Handle,HRegion);...)


SelectClipPath(HRegion,Rgn_Copy);
// select englobe tous les points pour vérification futur ,ça pourrait
// être l'union de 3 HRegion .Wow Tout un Bouton etc..
end;


procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
// donc Si ça correspond à la zone cliquer
if(PtInRegion(HRegion,X,Y)=true)then
begin
//on détermine la zone de dessin ,ici l'ellipse seulement
selectClipRgn(Canvas.Handle,HRegion);


//et on copie l'image bitmap sur le canvas


BitBlt(Form1.Canvas.Handle,//la fenêtre de destination
0,//coordonné Horizontale du rectangle de destination
0,//coordonné Verticale du rectangle de destination
100,//la largeur Width du rectangle de destination
100,//la Hauteur Height du rectangle de destination
BitmapBoutonDown.Canvas.Handle,//la fenêtre source
0,//coordonné Horizontale du rectangle source
0,//coordonné Verticale du rectangle source
SrcCopy);//Raster Operation Code //
end;


end;


procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if(PtInRegion(HRegion,X,Y)=true)then
begin
selectClipRgn(Canvas.Handle,HRegion);
BitBlt(Canvas.Handle,0,0,100,100,BitmapBoutonUp.Canvas.Handle,0,0,SrcCopy);
//Idem avec l'autre Bitmap
end;
end;


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeAndNil(BitmapBoutonUp);
FreeAndNil(BitmapBoutonDown);
DeleteObject(HRegion);
//et on libère les objets
end;


end.

Bon, je me suis amuser un peu , recherche Win32 Core API ,c'est plutôt assez complet ce que l'on peut faire avec api de windows...

yve
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
17 août 2005 à 09:42
Yep, je teste dès que possible :)

Thx !

gnh !
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
17 août 2005 à 15:16
Marche pas.

Si je mets "selectClipRgn(Canvas.Handle,HRegion);", ca ne repeint pas.

Avec 0 ( le hndl du deviceContext du bureau) à la place de Canvas.Handle, ok, ca repeint.

J'ai fait ca :

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var RectPaint: Trect;
CurrRgn:Integer;
begin


if PtInRegion(RgnPRV,X+Form1.Left,Y+Form1.Top) then
CurrRgn:=RgnPRV;
if PtInRegion(RgnPLAY,X+Form1.Left,Y+Form1.Top) then
CurrRgn:=RgnPLAY;
if PtInRegion(RgnPAUS,X+Form1.Left,Y+Form1.Top) then
CurrRgn:=RgnPAUS;
if PtInRegion(RgnSTOP,X+Form1.Left,Y+Form1.Top) then
CurrRgn:=RgnSTOP;
if PtInRegion(RgnNXT,X+Form1.Left,Y+Form1.Top) then
CurrRgn:=RgnNXT;


if (CurrRgn = RgnPRV) or
(CurrRgn = RgnPLAY) or
(CurrRgn = RgnPAUS) or
(CurrRgn = RgnSTOP) or
(CurrRgn = RgnNXT) then
begin
GetRgnBox(CurrRgn,RectPaint);
selectClipRgn(0,CurrRgn);


RectPaint.Top :=RectPaint.Top-Form1.Top;
RectPaint.Left :=RectPaint.Left-Form1.Left;
RectPaint.Bottom:=RectPaint.Bottom-Form1.Top;
RectPaint.Right :=RectPaint.Right-Form1.Left;


BitBlt(Form1.Canvas.Handle,
RectPaint.Left,
RectPaint.Top,
RectPaint.Right-RectPaint.Left+2,
RectPaint.Bottom-RectPaint.Top+2,
LayoutOFF.Canvas.Handle,
RectPaint.Left,
RectPaint.Top,
SrcCopy);


end;
end;

Ca marche globalement, mais meme avec une région elliptic ca recopie des rectangles. Une Idée ?
0
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
17 août 2005 à 22:34
comprend pas trop chez moi ça fonctionne nickel ,

si
selectClipRgn(Form1.Canvas.Handle,CurrRgn);
a correctement déterminer la région le

BitBlt(Form1.Canvas.Handle,
RectPaint.Left,
RectPaint.Top,
RectPaint.Right-RectPaint.Left+2,
RectPaint.Bottom-RectPaint.Top+2,
LayoutOFF.Canvas.Handle,
RectPaint.Left,
RectPaint.Top,
SrcCopy);
devrais dessiner ici (LayoutOFF.Canvas.Handle)dans la zone
CurrRgn ,or c'est

CurrRgn:=CreateEllipTicRgn(0,0,100,100);
SelectClipPath(CurrRgn,Rgn_Copy);
versus
GetRgnBox(CurrRgn,RectPaint);
selectClipRgn(0,CurrRgn);

c'est pas la même chose...
GetRgnBox renvoi une région rectangle ...

yve
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
19 août 2005 à 11:12
Rien que cette instruction là n'a pas l'air de marcher de la meme manière chez toi et chez moi.

selectClipRgn(Form1.Canvas.Handle,CurrRgn);

Avec le handle du canvas de la form (ci-dessus) ,il ne se passe strictement rien chez moi. Si je le remplace par zéro c'est à dire le handle du bureau windoz, la ca marche, ca repeint, le bitblt remplit son office (mais il recopie tout les pixels du rectangle englobant la region).

Ca peut etre lié à mon O.S., je suis sous win98se. Je n'en sais rien.

Si tu veux jeter un oeil au source complet je peux l'uploader quelque part.
0
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
19 août 2005 à 22:17
oui [mailto:yvemoreau@hotmail yvemoreau@hotmail] de toute façon mon adresse est publique ,ça devrais passer ...@++

yve
0
Rejoignez-nous