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 :

Difficultés avec TMenuItem.OnDrawItem


Sujet :

Composants VCL Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 63
    Points : 47
    Points
    47
    Par défaut Difficultés avec TMenuItem.OnDrawItem
    Bonjour,

    Je vous soumets un problème que je rencontre lors de la création d'un menu popup avec OwnerDraw True.

    En Rad, je crée une form vide Form1.

    Je crée un menu popup et je renseigne ses MenuItems lors de l'événement FormActivate.

    Voici le code (succint) de mon unité qui inclut aussi les procédures nécessaires au fonctionnement du menu popup.

    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Menus;
     
    type
      TForm1 = class(TForm)
        procedure FormActivate(Sender: TObject);
      private
        { Déclarations privées }
        procedure PopupMenuClick(Sender: TObject);
        procedure PopupMenuMeasureItem(Sender: TObject; ACanvas: TCanvas; var Width, Height: Integer);
        procedure PopupMenuAdvancedDrawItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect; State: TOwnerDrawState);
      public
        { Déclarations publiques }
        PopupMenu : TPopupMenu;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormActivate(Sender: TObject);
    var
      i : integer;
      MI : TMenuItem;
    begin
      PopupMenu := TPopupMenu.Create(Form1);
      with PopupMenu do begin
        for i := 1 to 3 do begin
          MI := TMenuItem.Create(PopupMenu);
          MI.Caption := format('Item %d', [i]);
          MI.Name := format('Item%d', [i]);
          MI.Tag := i;
          MI.OnClick := PopupMenuClick;
          MI.OnMeasureItem := PopupMenuMeasureItem;
          MI.OnAdvancedDrawItem := PopupMenuAdvancedDrawItem;
          Items.Add(MI);
        end;
        OwnerDraw := True;
      end;
      Form1.PopupMenu := PopupMenu;
    end;
     
    procedure TForm1.PopupMenuClick(Sender: TObject);
    begin
      with (Sender as TMenuItem) do
        ShowMessage(format('Clic sur PopupMenu Item %d', [Tag]));
    end;
     
    procedure TForm1.PopupMenuMeasureItem(Sender: TObject; ACanvas: TCanvas; var Width, Height: Integer);
    var
      ts : TSize;
    begin
      with (Sender as TMenuItem) do
        ts := ACanvas.TextExtent(format('PopupMenu Item %d', [Tag]));
      Width := ts.cx;
      Height := ts.cy;
    end;
     
    procedure TForm1.PopupMenuAdvancedDrawItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect; State: TOwnerDrawState);
    begin
      with (Sender as TMenuItem) do
        ACanvas.TextOut(0, 0, format('PopupMenu Item %d', [Tag]));
    end;
     
    end.
    A l'exécution, je devrais voir apparaître le popup avec trois items l'un au dessus des autres : Popup Item 1, Popup Item 2, Popup Item 3.

    Or un clic droit fait apparaître un cadre blanc susceptible d'afficher les trois lignes correspondant aux trois items voulus, avec UN SEUL item est qui est affiché tout en haut et dont le numéro correspond à la position approximative du curseur sur le menu (donc PopupMenu Item 1, 2, ou 3),

    Pourtant, si je clique en bas du menu popup, je vois que mon ShowMessage m'affiche comme il se doit Clic sur PopupMenu Item 3.

    Mon problème est donc un problème d'affichage des items dessinés à la volée dont les libellés s'empilent tous sur le premier item.

    Qu'ai-je manqué dans mon code que je compile sous D6 ?

    Merci d'avoir pris le temps de me lire.

    ....et meilleurs voeux pour 2005.

  2. #2
    MHI
    MHI est déconnecté
    Membre à l'essai
    Inscrit en
    Octobre 2004
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 21
    Points : 22
    Points
    22
    Par défaut
    Il y a plusieurs problème, il y en a un au moins qui est du au fait que dans le canvas tu utilise toujours 0, 0 alors qu'il fuadrait je pense faire varier le y pour qu'il n'ecrive pas toujours au même endroit.

    Par contre pourquoi utilises-tu :
    OnMeasureItem et PopupMenuAdvancedDrawItem, je ne vois pas l'interet dans ton code.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 63
    Points : 47
    Points
    47
    Par défaut
    Merci pour ta réponse.

    Avec OnMeasureItem, j'indique la taille de l'élément à afficher.

    Je donne toujours les coordonnées 0,0 dans l'événement OnDraw car je pense que le TRect qui m'est passé correspond à la place que PopupMenu alloue à l'élément. Comment pourrais-je calculer une position y si PopupMenu se mettait à scroller ?

    Quant à l'utilisation de AdvancedDrawItem au lieu de DrawItem, c'est partiellement parceque j'ai essayé les deux (avec le même résultat), mais aussi parceque le State est susceptible de m'intéresser (quand la première étape marchera...).

    A+

  4. #4
    MHI
    MHI est déconnecté
    Membre à l'essai
    Inscrit en
    Octobre 2004
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 21
    Points : 22
    Points
    22
    Par défaut
    j'ai trouvé il faut que tu utilise le Trect pour récupérer les coordonnés à utiliser dans TextOut

    ACanvas.TextOut(ARect.Left, ARect.Top, format('PopupMenu Item %d', [Tag]));

    Je viens d'essayer cela fonctionne.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 63
    Points : 47
    Points
    47
    Par défaut
    En fait MHI, tu as raison.

    Malgré mes doutes, j'ai testé ta suggestion et c'est bien à moi de calculer la position Y

    Et s'il y a lieu de scroller, le système s'en débrouille bien tout seul.

    Ma procedure de DrawItem se présente donc comme suit (où H est une variable globale qui contient la hauteur à affecter à chaque item). Le traitement de l'événement OnMeasureItem est donc inutile....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    procedure TForm1.PopupMenuAdvancedDrawItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect; State: TOwnerDrawState);
    begin
      with (Sender as TMenuItem) do
        ACanvas.TextOut(0, H * pred(Tag), format('PopupMenu Item %d', [Tag]));
    end;
    Merci++

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [SSIS][2k5]Difficulté avec SSIS
    Par david71 dans le forum SSIS
    Réponses: 9
    Dernier message: 05/01/2006, 20h28
  2. [Calcul] difficulté avec BigDecimal
    Par dinver dans le forum Langage
    Réponses: 4
    Dernier message: 01/01/2006, 17h41
  3. [JS] Difficulté avec le onmouseover...
    Par Pleymo dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 26/11/2005, 13h09
  4. [VBA] difficultés avec une requête INSERT
    Par elias dans le forum Access
    Réponses: 7
    Dernier message: 06/09/2005, 15h53
  5. Difficultés avec - onchange - !
    Par zakuli dans le forum Balisage (X)HTML et validation W3C
    Réponses: 7
    Dernier message: 20/07/2005, 13h00

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