IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants VCL Delphi Discussion :

Comportement bizarre du TStatusBar


Sujet :

Composants VCL Delphi

  1. #1
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut Comportement bizarre du TStatusBar
    Bonsoir,

    Ce qui arrive est très bizarre et ne se produit pas lorsque j'exécute le pas à pas (en théorie).

    Je dis en théorie car je me suis basé sur le contenu des variables à chaque passage dans le DrawPanel de la barre d'état et n'ai pas pu faire autrement vu qu'il est lié au timer.

    En gros ce qui arrive, c'est que j'ai le texte de mon menu qui apparait dans le dernier panel de la barre d'état (voir ci-dessous).



    Pour chaque panel de la barre d'état j'ai mis "psOwnerDraw" à la propriété "Style" afin de pouvoir le redessiner (mettre en rouge et centrer). Dans le panel affichant "NUM" j'ai placé "NUM" dans la propriété "Text".

    Dans un timer je récupère l'état de la touche Verr. Num et l'heure en cours puis je les affecte au panel 1 et 2 (rien dans le 0).

    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      AppliquerCouleur((Sender as TForm));
      with BarreEtat do
      begin
        Panels[0].Width := STATUS1;
        Panels[1].Width := STATUS2;
        Panels[2].Width := STATUS3;
      end;
    end;
     
    procedure TForm1.BarreEtatDrawPanel(StatusBar: TStatusBar;
      Panel: TStatusPanel; const Rect: TRect);
    var Rect2 : TRect;
    begin
      Rect2 := Rect;
      With StatusBar.Canvas do
      begin
        Font.Color := CouleurInterface.Police;
        DrawText(Handle,PChar(Panel.Text),-1,Rect2,DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE);
      end;
    end;
     
    procedure TForm1.HorlogeTimer(Sender: TObject);
    var StNum, StHeure : String;
    begin
      if (GetKeyState(VK_NUMLOCK) <> 0) then StNum := 'NUM'
      else StNum := '';
      StHeure := FormatDateTime('hh:nn:ss',Now);
      BarreEtat.Panels[1].Text := StNum;
      BarreEtat.Panels[2].Text := StHeure;
    end;
    En gros lorsque j'appuie sur Verr. num., j'ai soit 'NUM' soit rien dans le panel 2 et l'heure dans le panel 3 lors du premier passage dans le timer réglé à une secondre. Mais lors du second passage et des suivants dans le timer j'ai le texte correspondant à mon menu qui apparait dans le panel 3.
    J'ai voulu vérifier le contenu des variables dans le debuger et c'est là que j'ai pété un plomb en constatant que leur contenu était pourtant bon à chaque passage.

    Je m'arrache les cheveux depuis ce midi à essayer de comprendre ce qui se passe alors je m'en remets à vos lumières.

    Je précise que la procédure Appliquer couleur ne contient rien d'autre que ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Procedure AppliquerCouleur(Fiche : TForm);
      begin
        Fiche.Color := CouleurInterface.Fiches;
        Fiche.Font.Color := CouleurInterface.Police;
      end;
    Je précise également que CouleurInterface est rempli par une procédure qui recherche ces couleurs dans un fichier INI et que cette procédure est exécutée juste après le Application.Initialize.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    program Comptes;
     
    uses
      Forms,
      Start in 'Start.pas' {Form1},
      Objets in 'Objets.pas',
      Constantes in 'Constantes.pas',
      HintPerso in 'HintPerso.pas',
      Couleurs in 'Couleurs.pas';
     
    {$R *.res}
     
    begin
      Application.Initialize;
      RecupererCouleur; { Récupère les couleur choisies par l'utilisateur pour l'interface }
      HintWindowClass := THintBulle; { Remplace le Hint Windows par la bulle d'aide perso }
      Application.HintPause := 0; { Affiche la bulle immédiatement }
      Application.HintHidePause := 2000; { Durée d'affichage de la bulle à 2 sec. }
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end.
    Merci

  2. #2
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    cela ne proviendrait pas du fait que l'événement ondrawpanel n'est appelé qu'une seule fois au moment où tu lances ta fiche et après s'il n'y a pas de nouvelle dimension de volet d'état, il n'est plus appelé.
    Donc à chaque évenement ontimer, il faudrait peut-être redessiner.

    à voir...

  3. #3
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    Non, l'évènement OnDrawPanel est appelé tout de suite après le passage dans le timer du fait que le contenu du panel change. Donc à chaque fois

  4. #4
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Sans générer le ondrawpanel, ton code fonctionne bien... J'ai testé...

    L'erreur est donc engendrée par le contenu de ta procedure dans ondrawpanel.
    Il faudrait voir ça de plus près.

  5. #5
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    J'ai déjà mis le contenu de la précédure dans mon premier post. Et comme je l'ai noté, le contenu de Panel.Text est bon dans le debuger.

    Puisque tu as testé mon code, tu as sans doute remarqué la même chose. Qu'est ce qui pourrait expliquer le fait qu'à l'affichage ce contenu diffère ?

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 141
    Points : 142
    Points
    142
    Par défaut
    Salut,

    Je jette une idée vague à bout portant, sans avoir testé de code ou quoi :
    créer un TTimer crée un thread indépendant, non? J'ai lu à plusieurs endroits que les composants de la VCL étaient réputés "non thread safe". Est-ce que ça ne pourrait pas être un problème de ce type? Du style la procédure du timer déclenche un ReDraw, qui s'exécute du coup de maniière asynchrone avec le reste de la procédure du TTimer?

    Tu as essayé de garantir la synchronisation par une section critique par exemple?

    C'est vraiment une suggestion à l'aveugle.
    *LeGEC*

  7. #7
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Sans la totalité du projet, c'est difficile à trouver... Avec les toolbars et les statusbars, on a parfois des choses curieuses... (Enfin ceci dit, c'est surtout avec les toolbars...) perso, je ne vois pas.

  8. #8
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    Citation Envoyé par LeGEC Voir le message
    Salut,

    Je jette une idée vague à bout portant, sans avoir testé de code ou quoi :
    créer un TTimer crée un thread indépendant, non? J'ai lu à plusieurs endroits que les composants de la VCL étaient réputés "non thread safe". Est-ce que ça ne pourrait pas être un problème de ce type? Du style la procédure du timer déclenche un ReDraw, qui s'exécute du coup de maniière asynchrone avec le reste de la procédure du TTimer?

    Tu as essayé de garantir la synchronisation par une section critique par exemple?

    C'est vraiment une suggestion à l'aveugle.
    Qu'est ce que tu appelles une section critique ?

    Sans la totalité du projet, c'est difficile à trouver... Avec les toolbars et les statusbars, on a parfois des choses curieuses... (Enfin ceci dit, c'est surtout avec les toolbars...) perso, je ne vois pas.
    J'ai bien placé un TToolbar mais pour l'instant je me suis contenté de le poser sur la forme sans y toucher.
    Mon projet ne se compose que des unités suivantes :
    - Objets : contient les classes que j'ai défini (genre TUtilisateur),
    - Constantes : contient les constantes et les variables global (uniquement des données brutes du genre String, Integer, Double, ....)
    - Couleurs : qui contient la fonction de récupération des couleurs dans le fichier INI et les procédure de changement de couleur de la fiche, de la police de la fiche ainsi que de la police des colonnes entree et sortie de prochaines StringGrid et TListView (celle de la Grid et du ListView ne sont pas encore utilisées).
    - HintPerso, contenant la procédure qui remplace le Hint standard par une bulle d'aide personalisé (il s'agit d'un code trouvé ici meme sur lequel j'ai apporté quelques modifications pour un rendu plus joli mais qui n'est pas encore utilisé),
    - Start : pour lequel j'ai fourni la totalité du code après implementation est les uses pointant vers Constantes et Couleurs (je n'ai pas touché à ce qu'il y a avant).

    La seul procédure utilisée et touchant aux composants posé (execpté le DrawItem), je l'ai mise dans le premier post.

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 141
    Points : 142
    Points
    142
    Par défaut
    Citation Envoyé par popo Voir le message
    Qu'est ce que tu appelles une section critique ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    //à rajouter dans ton uses :
       SyncObjs
     
    //comme champ de ton TForm1 :
    fCritSection : TCriticalSection;
     
     
    //dans tes méthodes:
    procedure TForm1.FormCreate( Sender: TObject );
    begin
      fCritSection := TCriticalSection.Create;
    end;
     
    procedure TForm1.FormDestroy( Sender: TObject );
    begin
      FreeAndNil(fCritSection);
    end;
     
    procedure TForm1.BarreEtatDrawPanel(StatusBar: TStatusBar;
      Panel: TStatusPanel; const Rect: TRect);
    var Rect2 : TRect;
    begin
      fCritSection.Enter;
      { <ton code, qui accède à ta barre d'état> }
      fCritSection.Leave;
    end;
     
    procedure TForm1.HorlogeTimer(Sender: TObject);
    var StNum, StHeure : String;
    begin
      fCritSection.Enter;
      { <ton code, qui accède aussi à ta barre d'état> }
      fCritSection.Leave;
    end;
    Cette version n'est pas très fine, c'est juste pour voir si le problème vient de là.
    *LeGEC*

  10. #10
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    Ceci est sensé produire quoi ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      AppliquerCouleur((Sender as TForm));
      COL_ENTREE := 1;
      COL_SORTIE := 2;
      COL_SOLDE := 3;
      with Titre.Font do
      begin
        Size := 16;
        Style := [fsBold];
      end;
      with BarreEtat do
      begin
        Panels[0].Width := STATUS1;
        Panels[1].Width := STATUS2;
        Panels[2].Width := STATUS3;
      end;
     
      Crit := TCriticalSection.Create;
    end;
     
    procedure TForm1.BarreEtatDrawPanel(StatusBar: TStatusBar;
      Panel: TStatusPanel; const Rect: TRect);
    var Rect2 : TRect;
    begin
      Crit.Enter;
      Rect2 := Rect;
      With StatusBar.Canvas do
      begin
        Font.Color := CouleurInterface.Police;
        DrawText(Handle,PChar(Panel.Text),Length(Panel.Text),Rect2,DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE);
      end;
      Crit.Leave;
     
    end;
     
    procedure TForm1.HorlogeTimer(Sender: TObject);
    var StNum, StHeure : String;
    begin
      Crit.Enter;
      if (GetKeyState(VK_NUMLOCK) <> 0) then StNum := 'NUM'
      else StNum := '';
      StHeure := FormatDateTime('hh:nn:ss',Now);
      BarreEtat.Panels[1].Text := StNum;
      BarreEtat.Panels[2].Text := StHeure;
      Crit.Leave;
    end;
     
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      FreeAndNil(Crit);
    end;

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 141
    Points : 142
    Points
    142
    Par défaut
    Une section critique est une sorte de témoin, que 2 threads ne peuvent pas avoir en même temps. Si un thread réussit à entrer (Crit.Enter) dans la section critique, un autre thread, qui demande à y entrer aussi, sera suspendu, jusqu'à ce que le premier thread sorte de la section critique (Crit.Leave).

    Si tu veux en savoir plus sur les threads, tu peux commencer par lire les tutoriels du site.

    Dans ton cas, je te propose de rajouter une section critique pour être sûr que le bug n'est pas un problème de synchronisation de threads.
    *LeGEC*

  12. #12
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    En rajoutant les Crit.Enter et Crit.Leave je ne constate aucune amélioration.
    Une section critique est une sorte de témoin, que 2 threads ne peuvent pas avoir en même temps. Si un thread réussit à entrer (Crit.Enter) dans la section critique, un autre thread, qui demande à y entrer aussi, sera suspendu, jusqu'à ce que le premier thread sorte de la section critique (Crit.Leave).
    Si je comprend bien ce que tu dis, ma procédure DrawPanel ne devrait avoir aucun effet si le Leave du Timer n'a pas été éxécuté. Ce qui confirme que cela n'a aucun effet. Il doit y avoir un truc a ajouter du genre un test pour savoir si le CriticalSection a été libéré ou je sais pas quoi ?

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 141
    Points : 142
    Points
    142
    Par défaut
    Hmmm... ça m'apprendra à tester du code avant de poster... S'il n'y a pas d'amélioration, c'est que ça n'est pas le problème.

    Citation Envoyé par popo Voir le message
    Il doit y avoir un truc a ajouter du genre un test pour savoir si le CriticalSection a été libéré ou je sais pas quoi ?
    Non, le test est fait de lui-même. Si ton programme ne se bloque pas et que tout ton code s'exécute, c'est que la section critique était bien libre au moment de l'exécution de chaque méthode.


    Cherchons ailleurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        DrawText(Handle,PChar(Panel.Text),-1,Rect2,DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE);
    Tu as dit que tu as vérifié que les variables avaient la bonne valeur. As-tu regardé qu'est-ce qui s'exécutait sous ce DrawText? en faisant une exécution pas-à-pas?
    *LeGEC*

  14. #14
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    Derrière le DrawText, il n'y a que le timer qui s'exécute à nouveau.

    Je viens de remarquer un truc si ça peut aider. Lorsque je passe la souris au dessus de l'un des éléments du menu ou lorsque je clique sur le menu (n'importe où même sur une zone vide), j'ai bien l'heure qui apparait.

  15. #15
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 141
    Points : 142
    Points
    142
    Par défaut
    Pardon, je me suis mal exprimé. Je voulais dire :
    quelle est la fonction effectivement appelée par ce DrawText? quels sont les arguments qui lui sont passés?

    Mets un point d'arrêt sur la ligne, et fais [F7] ("Pas à pas approfondi").
    Regarde les valeurs des paramètres dans la pile d'appel, regarde dans quel bout de code tu te retrouve ( Windows.DrawText? TCustomActionControl.DrawText? TStandardMenuItem.DrawText? pour ne citer que ceux qui sont référencés par mon aide de Delphi.... )


    Tu appelles cette ligne de code à l'intérieur d'un "WITH", avec des identifiants (du type "Handle", "DrawText", "Panel" et autres) qui peuvent potentiellement faire référence aussi bien à des champs/fonctions de l'objet en cours (Self) que de l'objet mis sur la pile avec le with ("StatusBar.Canvas"), ou à des fonctions/variables globales d'unités extérieures (par exemple, le nom "DrawText" désigne à la fois une fonction de l'unité Windows et une méthode de la classe TCustomActionControl...)

    C'est le genre de truc qui prête à confusion, et en fait, même l'IDE de Delphi ne s'y retrouve pas. Il est possible que l'IDE t'affiche une valeur lorsque tu mets la souris sur un champs, mais qu'en fait, le code compilé fasse référence à d'autres champs.

    Je te suggèrerais autant que possible d'éviter les with.
    Ecris plutôt des trucs du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      var
        LCnvs : TCanvas;
     
    LCnvs:= StatusBar.Canvas;
    LCnvs.Font.Color := CouleurInterface.Police;
    DrawText( LCnvs.Handle,PChar(Self.Panel.Text),-1,Rect2,DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE);
    Mets des noms plus spécifiques que "Panel" et "StatusBar" à tes champs - style "Panel_ValeurChrono", "StatusBar_Principale"...
    *LeGEC*

  16. #16
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    J'ai mis ceci mais aucun résultat.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Rect2 := Rect;
    LeCanvas := StatusBar.Canvas;
     
    LeCanvas.Font.Color := CouleurInterface.Police;
    Windows.DrawText(LeCanvas.Handle,PChar(Panel.Text),-1,Rect2,DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE);
    Après pour StatusBar et Panel, ce n'est pas moi qui choisis les noms puisque c'est ceux fourni par l'évenement OnDrawPanel de la barre d'Etat.
    D'un point de vue visibilité il me semble que Delphi recherche d'abord les variable de la procédure avant d'aller chercher ailleurs. Donc StatusBar et Panel ne doivent pas être confondu avec autre chose. J'ai également rajouté que le DrawText venais de l'Unité Windows histoire d'être sûr. Mais bon, ça ne change absoluement rien au problème.

    Je vais faire un tour du coté de l'Unité Windows pour voir ce qui se passe en interne.
    => DrawText est tiré de user32.dll, impossible de voir ce qui se passe dedans !

  17. #17
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    Il n'y a pas un spécialiste qui pourrait me dire ce que fait le DrawText en interne ?

  18. #18
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 141
    Points : 142
    Points
    142
    Par défaut
    Ca pourrait aussi venir de la valeur de PChar(LText).

    Que vaut le deuxième argument de DrawText au moment où Delphi va appeler la fonction de l'API windows (fais F7 sur la ligne "Windows.DrawText" et regarde l'état de la pile d'appel)?

    Essaye de ne pas faire un cast de la propriété "Text" mais de passer par une variable locale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      var
        LText : string;
    ...
    LeCanvas.Font.Color := CouleurInterface.Police;
    LText := Panel.Text;
    Windows.DrawText(LeCanvas.Handle,PChar(LText),-1,Rect2,DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE);
    *LeGEC*

  19. #19
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    Contenu de la pile d'appel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TForm1.BarreEtatDrawPanel(???,???,(733,3,783,18,(733,3),(783,18)))
    J'ai fait un test en affichant le contenu de LText après le passage dans Windows.DrawText et l'heure est conservé dans la variable.

  20. #20
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 674
    Points : 5 259
    Points
    5 259
    Par défaut
    Rebonjour

    Ce que je voulais obltenir c'était d'avoir un texte centré et en rouge ou une autre couleur dans la barre d'état. Et apparement mon problème viendrait de DrawText (fonction à laquelle je n'ai pas accès).

    Afin déviter de passer par la fonction DrawText j'ai pensé à définir le centrage directement dans le panel de la barre d'état et de seulement définir la couleur.

    Seulement voila, le texte reste en noir. J'ai donc décider de faire un test très simple qui consiste à modifier le font de la barre d'état directement dans l'inspecteur d'objet (j'ai effacé les fonctions qui changeait les couleurs donc le code n'accède pas à la couleur barre d'état). Et là, surprise le texte reste en noir !

    Une idée ?

Discussions similaires

  1. Comportement bizarre de mes FPS
    Par Ekinoks dans le forum OpenGL
    Réponses: 7
    Dernier message: 22/08/2005, 15h14
  2. xsl:test .... avec comportement bizarre
    Par Blue LC dans le forum XMLRAD
    Réponses: 2
    Dernier message: 10/06/2005, 13h56
  3. [ACESS][MEMO][ISNULL]Comportement bizarre
    Par seb.49 dans le forum ASP
    Réponses: 2
    Dernier message: 09/06/2004, 10h44
  4. [HttpClient] comportement bizarre, saute des catch()...
    Par iubito dans le forum Développement Web en Java
    Réponses: 4
    Dernier message: 04/02/2004, 15h25
  5. [Sybase] Comportement bizarre d'une table
    Par sdozias dans le forum Sybase
    Réponses: 4
    Dernier message: 03/02/2004, 10h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo