N_M_B
Messages postés94Date d'inscriptionmardi 9 mai 2006StatutMembreDernière intervention 1 mars 2008
-
4 juil. 2006 à 00:37
N_M_B
Messages postés94Date d'inscriptionmardi 9 mai 2006StatutMembreDernière intervention 1 mars 2008
-
6 juil. 2006 à 21:55
Bonjour a tous
Avec delphi 7
je voudrais savoir comment gerer le focus de mon composant ?, j'ai bien pu réagire au message CM_FOCUSCHANGED et au mouse down mais il reste encore un problème avec la tabulation car mon composant ne reprend pas le focus si il y'a un TButton ou autre compo focalisable sur la fiche je pence qui manque quelque chose genre taborder ou tabstop mais je suis pas sure .
je voudrais tout simplement un petit bout de code example (si possible commenté ) pour pouvoir gerer correctement le focus .
N_M_B
Messages postés94Date d'inscriptionmardi 9 mai 2006StatutMembreDernière intervention 1 mars 2008 6 juil. 2006 à 02:41
Bon en résumé on doit tout d'abord intercepter le message CMFOCUSCHANGED on déclare la procedure comme ceci: procedure CMFocusChanged(var Message: TMessage); message CM_FOCUSCHANGED; pour faire un ivalidate dedans puis
dans la procedure paint on pose la condition if focused then drawfocusrect() ou autre déssin pour différencier l'état normal et l'état focusé
enfin on ajoute les propriétées hérités ->
published
property tabstop ;
property taborder;
et de préférence on initialise tabstop a true dans le constructeur de classe du composant et cela devrais marcher(je pense )
P.S: grand merci a ThWilliam qui a pris le temps de me répondre et pour ses commentaires @+
ThWilliam
Messages postés418Date d'inscriptionmardi 3 janvier 2006StatutMembreDernière intervention26 novembre 20134 4 juil. 2006 à 14:45
Salut,
Si tu veux que ton compo soit focalisé avec la tabulation, il faut mettre évidemment TabStop = true.
Le plus simple, c'est de publier la propriété héritée TabStop et de laisser le choix en mode conception.
N_M_B
Messages postés94Date d'inscriptionmardi 9 mai 2006StatutMembreDernière intervention 1 mars 2008 5 juil. 2006 à 16:08
Désolée ,cela ne marche toujour pas j'ai ajouté ceci a mon composant:
published
property tabstop ;
property taborder;
mais cela ne marche toujour pas !
je peut vous montrer le source le voici
N*M*B
Vous n’avez pas trouvé la réponse que vous recherchez ?
procedure Register;
begin
RegisterComponents('Delphifr', [TNMBBtn]);
end;
/////////////////////TCustomBtn/////////////////////
constructor TCustomBtn.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
(aowner as Twincontrol).DoubleBuffered:=true;
end;
Destructor TcustomBtn.Destroy;
begin
inherited Destroy;
end;
//////////////////////TColors//////////////////////////////
Constructor Tcolors.Create(AOwner: TCustomBtn);
begin
inherited Create;
FOwner:= AOwner;
FColor1:=clGray;
FColor2:=clWhite;
FColor3:=$00FBFBFB;
FColor4:=$00ADADAD;
end;
procedure Tcolors.SetColor(Index: Integer; Value: Tcolor);
begin
case index of
0:FColor1:=value;
1:FColor2:=value;
2:FColor3:=value;
3:FColor4:=value;
end;
Fowner.invalidate;
//Fowner.Invalidate;
end;
///////////////////////////////////////////////////////////
procedure TNMBbtn.setCaption(Avalue:string);
begin
Fcaption:=Avalue;
invalidate;
end;
procedure TNMBbtn.DrawCaption;
var TXheight,TXWidth:integer;
flags:longint;
Arect:Trect;
sdf:pdrawtextparams;
begin
//aRect := ClientRect;
//Flags := DT_Center Or DT_VCENTER Or DT_EXPANDTABS Or DT_SINGLELINE;
//DrawText(Canvas.Handle, PChar(Caption), -1,Arect , Flags);
procedure TNMBbtn.CMMouseEnter(var Msg: TMessage);
begin
if csDesigning in ComponentState then exit;
if Enabled
then if Assigned(FOnMouseEnter) then FOnMouseEnter(Self);
if FCharged then State:=SDown else State:=SHot;
if (Not(csDesigning in ComponentState))and(FEFFECTENABLED) then
begin
FTimer2.Enabled:=False;
FTimer.Enabled:=True;
end;
end;
Procedure TNMBbtn.CMMouseLeave(var Msg: TMessage);
begin
if Enabled
then
if Assigned(FOnMouseleave) then FOnMouseLeave(Self);
if FState=SDown then FCharged:=True;
State:=SNormal;
if Not((csDesigning in ComponentState))and(FEFFECTENABLED) then
begin
FTimer.Enabled:=False;
FTimer2.Enabled:=True;;
end;
end;
procedure TNMBbtn.MouseDown(Button: TmouseButton; Shift:TShiftState; X,Y: Integer);
begin
if Enabled
then
if Assigned(FOnMouseDawn) then FOnMouseDawn(self,Button,Shift,X,Y);
if not Focused and CanFocus then
SetFocus;
State:=SDown;
end;
procedure TNMBbtn.MouseUp(Button: TmouseButton; Shift:TShiftState; X,Y: Integer);
begin
if Enabled
then
if Assigned(FOnMouseUp) then FOnMouseUp(self,Button,Shift,X,Y);
FCharged:=false;
if (x<width) and (x>0) and (y<height) and (y>0) then
State:=SHot else State:=SNormal;
end;
procedure TNMBbtn.Setstate(Avalue:TState);
begin
//if self=nil then exit;
FState:=Avalue;
if Assigned(FOnStateChange) then FOnStateChange(self);
invalidate;
Update;
////////////////////////invalidate; par rapport au customcontrol
end;
procedure TNMBbtn.SetBorderWidth(Avalue:integer);
begin
//calcul de la bordure la plus grande possible pour ne pas créer d'erreurs
if Avalue > MaxBorderFor(FStyle,height,width)
then Avalue:=MaxBorderFor(FStyle,height,width);
FBorderWidth:=Avalue;
//if FEffectEnabled then self.Update ;//Update; //pour le clignotement du caption
invalidate;
end;
procedure TNMBbtn.SetStyle(Avalue:TStyle);
begin
FNewStyle:=Avalue;
self.Resize; //chaque style a sa bordure maximal alor on le redimentione si bordure> max
FStyle:=Avalue;
//invalidate;
invalidate;
end;
procedure TNMBbtn.paint;
var FCanPaint:Boolean;
Border:integer;
r:trect;
begin
inherited Paint;
FCanPaint:=true;
if self<>nil then if assigned(FOnBeforePaint) then FOnBeforePaint(self,FCanPaint);
if not(FCanPaint) then EXIT;
Border:=FBorderWidth;
if (csDesigning in ComponentState)
then draw(FStyle,FStateVisualiser,Border)
else draw(FStyle,FState,Border);
DrawCaption; // elle est déja dans drawdegrede
DrawBorder(FBorderWidth,FBorderColor);
if self.Focused then
begin
R := GetClientRect;
InflateRect(R, -2, -2);
DrawFocusRect(Canvas.Handle, R);
end;
if self<>nil then if assigned(FOnAfterPaint) then FOnAfterPaint(self);
update;
end;
procedure TNMBBtn.Resize;
var Resize,ResizeBorder:Boolean;
TempHSize,TempWSize:integer;
begin
inherited Resize;
if (Width<MinWidthFor(FNewStyle,FBorderWidth))or(Height<MinHeightFor(FNewStyle,FBorderWidth)) then
begin
Resize:=True;
ResizeBorder:=False;
TempHSize:=Height;
TempWSize:=Width;
Height:=FlastHeight; // Pour Ne Pas faire un paint avec des tailles
Width:=FlastWidth; // incorrectes come un showmessage a l'evenement OnCantResize
if Assigned(FOnCantResize) then FOnCantResize(TempWSize,TempHSize,FlastWidth,FlastHeight,Resize,ResizeBorder);
if resize then
begin
if ResizeBorder then
BorderWidth:=MaxBorderFor(FNewStyle,TempHSize,TempWSize)
else
begin
if (TempWSize<MinWidthFor(FNewStyle,FBorderWidth))then Width:=MinWidthFor(FNewStyle,FBorderWidth);
if (TempHSize<MinHeightFor(FNewStyle,FBorderWidth))then Height:=MinHeightFor(FNewStyle,FBorderWidth);
end;
end;
end;
FlastWidth :=Width;
FlastHeight:=Height;
end;
function TNMBBtn.MaxBorderFor(_Style: TStyle; _Height,
_Width: integer): integer;
var R:integer; //R:= nombe de dégradées du style
begin
case _Style of
Horizontal,VDefaut:R:=2;
VCourbe :R:=3;
end;
_Height:=Trunc(_Height/R);
_Width:=_Width div 2;
if _Height<=_Width then result:=_Height else result:=_Width;
end;
function TNMBBtn.MinHeightFor(_Style: TStyle;
_BorderWidth: integer): integer;
var R:integer; //R:= nombe de dégradées du style
begin
case _Style of
VDefaut,Horizontal:R :=2; // Ok //Ok
VCourbe:R :=3; //Ok
end;
result:=(_BorderWidth*(R));
end;
function TNMBBtn.MinWidthFor(_Style: TStyle;
_BorderWidth: integer): integer;
begin
Result:=_BorderWidth *2; //OK
end;
procedure TNMBBtn.SetStateVisualiser(Avalue: Tstate);
begin
FStateVisualiser:=Avalue;
//invalidate;
invalidate;
end;
procedure TNMBBtn.SetTimerInterval(Avalue: Cardinal);
begin
FTimerInterval:=Avalue;
FTimer.Interval:=FTimerInterval;
FTimer2.Interval:=FTimerInterval;
end;
procedure TNMBBtn.OnTimer(Sender: TObject);
begin
if BorderWidth=FEffectBorder then begin FTimer.Enabled:=false;EXIT end;
if FTimerDefaultBorder<FEffectBorder then
BorderWidth:=BorderWidth+1
else BorderWidth:=BorderWidth-1;
end;
procedure TNMBBtn.OnTimer2(Sender: TObject);
begin
if BorderWidth=FTimerDefaultBorder then begin FTimer2.Enabled:=false;EXIT end;
if FTimerDefaultBorder>FEffectBorder then
BorderWidth:=BorderWidth+1
else BorderWidth:=BorderWidth-1;
end;
procedure TNMBBtn.SetEffectState(Avalue: Boolean);
begin
FEffectEnabled:=Avalue;
FTimer.Enabled:=false;
FTimer2.Enabled:=False;
self.BorderWidth:=FTimerDefaultBorder;
end;
procedure TNMBBtn.Draw(_Style: TStyle; _State: TState;
BorderMargin: integer);
var Colors:TColors;
ARect:TRect;
begin
case _State of
SNormal:Colors:=FNormalColors;
SHot :Colors:=FHotColors;
SDown :Colors:=FDawnColors;
end;
Case _Style of
VCourbe:
begin
ARect:=Rect(BorderMargin,BorderMargin,width-BorderMargin,(height)div 3);
Drawdegradee(V, Colors.FColor1, Colors.FColor2 , ARect);
ARect:=rect(BorderMargin,(height)div 3,width-BorderMargin,(height)div 2);
Drawdegradee(V, Colors.FColor2, Colors.FColor3 , ARect);
ARect:=Rect(BorderMargin,(height)div 2,width-BorderMargin,height-BorderMargin);
Drawdegradee(V, Colors.FColor3, Colors.FColor4 , ARect);
end;
VDefaut:
begin
ARect:=Rect(BorderMargin,BorderMargin,width-BorderMargin,(height)div 2);
Drawdegradee(V, Colors.FColor1, Colors.FColor2, ARect);
ARect:=Rect(BorderMargin,(height)div 2,width-BorderMargin,height-BorderMargin);
Drawdegradee(V, Colors.FColor3, Colors.FColor4, ARect);
end;
Horizontal:
begin
ARect:=rect(BorderMargin,BorderMargin,width div 2,height-BorderMargin);
Drawdegradee(H, Colors.FColor1, Colors.FColor2 ,ARect);
ARect:=rect( width div 2,BorderMargin,width-BorderMargin,height-BorderMargin);
Drawdegradee(H, Colors.FColor3, Colors.FColor4 ,ARect);
end;
end;
end;
procedure TNMBBtn.DrawBorder(_Width:integer;Color:TColor);
begin
if FBorderWidth*2>0 then
begin
canvas.Pen.Color:=Color;
Canvas.Pen.Width:=_Width*2;
canvas.Rectangle(rect(0,0,Width+1,Height+1));
end;
end;
procedure TNMBBtn.SetBorderColor(Avalue: TColor);
begin
FBorderColor:=Avalue;
invalidate;
end;
procedure TNMBbtn.Drawdegradee(GradationType: TGradationType; FirstColor, LastColor: TColor; R: TRect);
function CtrlByte(N: integer): byte;
begin
if N < 0 then Result:= 0
else if N > 255 then Result:= 255
else Result:= N;
end;
type
TRGBArray = array[0..0] of TRGBTriple;
PRGBArray = ^TRGBArray;
var
GSize, X, Y, N: integer;
Red, Green, Blue: byte;
StepR, StepG, StepB: extended;
Line: PRGBArray;
Bmp: TBitmap;
begin
if GradationType = H then
GSize:= R.Right - R.Left
else
GSize:= R.Bottom - R.Top;
if GSize=0 then inc(GSize);
Red:= GetRValue(FirstColor);
Green:= GetGValue(FirstColor);
Blue:= GetBValue(FirstColor);
StepR:= (GetRValue(LastColor) - Red) / GSize;
StepG:= (GetGValue(LastColor) - Green) / GSize;
StepB:= (GetBValue(LastColor) - Blue) / GSize;
Bmp:= TBitmap.Create;
try
Bmp.Width:= R.Right - R.Left;
Bmp.Height:= R.Bottom - R.Top;
Bmp.PixelFormat:= pf24bit;
for Y:= 0 to Bmp.Height -1 do
begin
Line := Bmp.ScanLine[Y];
for X:= 0 to Bmp.Width - 1 do
begin
if GradationType = H then N:= X
else N:= Y;
Line[X].RGBTRed:= CtrlByte (Round(Red + (StepR * N)));
Line[X].RGBTGreen:= CtrlByte (Round(Green + (StepG * N)));
Line[X].RGBTBlue:= CtrlByte (Round(Blue + (StepB * N)));
end;
end;
canvas.Draw(R.Left, R.Top, Bmp);
finally
Bmp.Free;
end;
end;
procedure TNMBBtn.CMFocusChanged(var Message: TMessage);
begin
invalidate;
end;
procedure TNMBBtn.CMDialogKey(var Message: TCMDialogKey);
begin
inherited;
with Message do
if (((CharCode = VK_RETURN) and (Focused))
or ((CharCode VK_ESCAPE)) and (KeyDataToShiftState(KeyData) []))
and CanFocus then
begin
Click;
Result := 1;
end
else
inherited;
end;
ThWilliam
Messages postés418Date d'inscriptionmardi 3 janvier 2006StatutMembreDernière intervention26 novembre 20134 5 juil. 2006 à 18:00
Mais si, ça marche !!!
A condition de mettre TabStop = true en mode conception.
Tu peux aussi initialiser à true dans le constructeur de ton composant.
Je n'ai pas eu le temps de regarder tout ton code.
Cependant, 2 remarques :
- pourquoi provoquer un click quand on presse Escape ?
- plus grave : click est appelé dès qu'on enfonce la touche et continue à être appelé quand on la maintient. Fais un test en mettant un simple beep dans l'événement OnClick...
A +
Thierry
PS: je vois que ma procédure de dégradé t'a été utile. Tant mieux.
N_M_B
Messages postés94Date d'inscriptionmardi 9 mai 2006StatutMembreDernière intervention 1 mars 2008 5 juil. 2006 à 19:48
hoo merci thwiliam pour (initialiser à true dans le constructeur de ton composant) !
c'est bon cela marche a merveille(a condition que j'innitialise la propriété tabstop a true dans le constructeur de la class) c.a.d si je l'initialise pas ou que je l'initialise a false les changement de cette dernière dans l'inspecteur d'objets ne change rien au prob je ne comprend pas )???
N_M_B
Messages postés94Date d'inscriptionmardi 9 mai 2006StatutMembreDernière intervention 1 mars 2008 6 juil. 2006 à 18:51
dsl ,bon je répond a la volé mais a ma connaissance quand on met (property TabStop default true;) default sert a delphi pour gerer les dfm c.a.d que si dans un prog on met un composant automatiquement delphi sauvegarde les propriétées dans la dfm mait pas toutes les propriétes seulement les propriétes modifies !!!
EX: si lont met---> property TabStop default true;
et que la propriété en mode conception bien sure est a true il ne l'écrit pas dans la dfm puisque c'est la valeur par défaut d'ou le ( default )!!!
j'aispère que je ne me tronpe pas ^^ .
et je tien a te remercier pour l'atention que tu porte a mon égard merci et bonne prog!
ThWilliam
Messages postés418Date d'inscriptionmardi 3 janvier 2006StatutMembreDernière intervention26 novembre 20134 6 juil. 2006 à 20:37
Ton composant de base est dérivé de TCustomControl qui lui-même est dérivé de TWinControl (auquel il n'ajoute qu'un Canvas).
Dans TWinControl, la propriété TabStop est false par défaut.
En reprenant la propriété héritée telle quelle, il faut changer sa valeur par défaut, puisque tu initialises TabStop à true dans le constructeur.
C'est ainsi que font les descendants de TWinControl : TButton, TCustomEdit...
N_M_B
Messages postés94Date d'inscriptionmardi 9 mai 2006StatutMembreDernière intervention 1 mars 2008 6 juil. 2006 à 21:55
malgès mon jeune age et mon expérience toute nouvelle en programmation j'insiste sur le fait que (default) sert a delphi pour la gestion des *.dfm des projets !
il ne sert aucunement a initialiser les variables j'en ait fait l'éxperience.
la vaiable tab stop est initialisé a false dans les classes parentes bien que je n'ai vu aucune affectation dans le constructeur l'initialisation a false doit se faire ailleur (et le default ne modifie en rien la valeur de la variable FTabStop ).
comment en suije sure ?
j'ai fait un petit test : je n'ai pas initialisé tabstop dans le constructeur et je l'ai mise a true dans l'inspecteur d'objets pendent l'éxécution sa
valeur est false alor ou il y'a quelque chose qui l'initialise a false dans les classes parentes ou (comme toute variable boolean non innitialisé sa valeur est a false) le problème étais la, avec une affectation a l'éxécution a true ca marche !
mais tu me dira d'ou venait alors ton 1er problème de toute a leur et bien tout simplement que je n'ai pas recompilé mon composant et que l'initialisation ne s'est pas faite.
tout fonctione qu'elle soit initialisé a true ou a false dans le constructeur les changement dans l'inspecteur d'objets prènnent effet! merci !!!