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

Langage Delphi Discussion :

[Message] procedure x ( var Message : tX) ; message x ; ?


Sujet :

Langage Delphi

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 45
    Points : 34
    Points
    34
    Par défaut [Message] procedure x ( var Message : tX) ; message x ; ?
    Bonjour à tous,

    j'aurais aimé avoir des informations sur ce type de méthode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    procedure WMSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;
    Qui envoie le message ? Quand ? Comment ? Je trouve que l'aide est assez floue sur ce point ...

    Pourriez-vous me donner des infos ou des pistes de recherche ?

    D'avance mercè :-)

  2. #2
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut Re: [Message] procedure x ( var Message : tX) ; message x ;
    Citation Envoyé par Castagnems
    Qui envoie le message ?
    Windows
    Citation Envoyé par Castagnems
    Quand ?
    Dans ce cas-ci, lorsque l'utilisateur clique sur un élément de menu
    Citation Envoyé par Castagnems
    Comment ?
    Via SendMessage, probablement

    Voilà des réponses claire et précises à tes questions. Si tu veux savoir autre chose, tu demandes

  3. #3
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut Re: [Message] procedure x ( var Message : tX) ; message x ;
    Citation Envoyé par sjrd
    Citation Envoyé par Castagnems
    Qui envoie le message ?
    Windows
    Le thread appelant, plutôt... ;-)

    Citation Envoyé par sjrd
    Citation Envoyé par Castagnems
    Comment ?
    Via SendMessage, probablement
    PostMessage également, suivant s'il y a une réponse ou pas.

    Voilà, c'était juste pour faire avancer le schmililimili.. schmilliiibilimi... le truc, quoi....

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 45
    Points : 34
    Points
    34
    Par défaut
    Dans Forms.pas ~ tCustomForm, on trouve tout ceci (y'en a d'autres) ...

    Comment sait-on à la base qu'une fenêtre doi répondre à ces évenement ? Défini par windows ? (J'ai mis un lien dans mes favoris : msdn - je lirai ca demain ca m'aidera surement ).

    [edit]

    Ces méthodes sont en quelque sorte les gestionnaires d'évènements Windows ?

    [/edit]

    En attendant, bonne nuit et bonne matinée :-)
    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
     
        procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
        procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
        procedure WMIconEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ICONERASEBKGND;
        procedure WMQueryDragIcon(var Message: TWMQueryDragIcon); message WM_QUERYDRAGICON;
        procedure WMNCCreate(var Message: TWMNCCreate); message WM_NCCREATE;
        procedure WMNCLButtonDown(var Message: TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
        procedure WMDestroy(var Message: TWMDestroy); message WM_DESTROY;
        procedure WMCommand(var Message: TWMCommand); message WM_COMMAND;
        procedure WMInitMenuPopup(var Message: TWMInitMenuPopup); message WM_INITMENUPOPUP;
        procedure WMMenuChar(var Message: TWMMenuChar); message WM_MENUCHAR;
        procedure WMMenuSelect(var Message: TWMMenuSelect); message WM_MENUSELECT;
        procedure WMActivate(var Message: TWMActivate); message WM_ACTIVATE;
        procedure WMClose(var Message: TWMClose); message WM_CLOSE;
        procedure WMQueryEndSession(var Message: TWMQueryEndSession); message WM_QUERYENDSESSION;
        procedure WMSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;
        procedure WMShowWindow(var Message: TWMShowWindow); message WM_SHOWWINDOW;
        procedure WMMDIActivate(var Message: TWMMDIActivate); message WM_MDIACTIVATE;
        procedure WMNextDlgCtl(var Message: TWMNextDlgCtl); message WM_NEXTDLGCTL;
        procedure WMEnterMenuLoop(var Message: TMessage); message WM_ENTERMENULOOP;
        procedure WMHelp(var Message: TWMHelp); message WM_HELP;
        procedure WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo); message WM_GETMINMAXINFO;
        procedure WMSettingChange(var Message: TMessage); message WM_SETTINGCHANGE;
        procedure WMWindowPosChanging(var Message: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 45
    Points : 34
    Points
    34
    Par défaut
    Bonjour,

    petite question de compréhension () : que veut dire 'Window' dans ce cadre ? Tout simplement fenêtre ? Car il est question de ComboBox (un exemple) !

    Each window is a member of a particular window class. [...]. For example, the system defines a window procedure for the combo box class (COMBOBOX); all combo boxes then use that window procedure.
    Merci pour votre :-)

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 45
    Points : 34
    Points
    34
    Par défaut
    Je viens de voir que par exemple le système envoie un message WM_PAINT à une fenêtre grace à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    BOOL UpdateWindow(
      HWND hWnd   // handle to window
    );
    Si je comprends bien, ce message transite via la DefWindowProc de la fenêtre ?

    Comment se passe la réception et gestion de ce message au niveau 'Delphi', par rapport aux prototypes montré ci-dessous ?

    Le handle peut-il aussi être celui d'un composant (d'une Window Class) ?


  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Bon, un petit point d'historique Windows (l'OS) avant tout :
    - Sous Windows, le terme "Window" ne signifie pas la fenêtre au sens "utilisateur" du terme : c'est un composant capable de recevoir et traiter des messages. Un bouton, une case à cocher, une ListBox et bien sûr une Frame (=cadre, la "fenêtre" utilisateur) sont ce que l'on appelle des Window. Appelles-les des "fenêtres d'écoute" si ça peut t'aider à comprendre. Accessoirement, un Window n'est pas forcément visible à l'écran, loin de là.
    - On utilise un Window via son Handle, mais les messages eux-même sont habituellement "dispatchés" sur tous les Window existants. En tiennent compte ceux qui le doivent, les autres feront simplement "passer" le message aux autres. Cependant, il est tout à fait possible de "cibler" un Window particulier.

    (Pardon aux puristes Win32, c'est juste pour simplifier...)

    Toutes les procédures que tu as trouvées sont effectivement des gestionnaires non pas d'évènements (qui a un sens différent de celui de Delphi dans l'API Win32, mais laissons ça de côte), mais des gestionnaires de messages.

    Donc, on peut forcer un contrôle à se redessiner en lui envoyant un message WM_PAINT. Et tout passe par la méthode DefWindowProc , qui est ce que l'on appelle la "boucle de messages". C'est un fait un gigantesque "Case Of" sur les types de messages, exécutée en boucle infinie (ou jusqu'à réception d'un message de fermeture, bien sûr).
    Si cette boucle est bloquée (ou absente !), ton contrôle Window est "figé" et ne répond plus, il n'est plus non plus capable de se redessiner.
    Si c'est la boucle principale de l'application, c'est l'application complète qui est "figée" (c'est ce qu'il se passe lorsque tu fais un traitement long dans un gestionnaire d'évènements Delphi sans appeller Application.ProcessMessages).

    Par rapport aux messages, Delphi ne fait "rien" : ce sont les contrôles Window, "mappés" sur des classes Delphi, qui s'en occupent. Il est très rare d'être obligé de surcharger le système de messages par défaut de la VCL. Sinon, chaque procédure de traitement d'un message "exécute" le message en question, pas plus, pas moins.

    Est-ce que ça répond à tes questions ?

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 45
    Points : 34
    Points
    34
    Par défaut
    Oui oui ca m'aide pas mal :-)

    Je me suis promené un peu sur msdn ce matin et en lisant toute la partie sur les 'Window procedure' et ca me semble déja plus clair ! :-)

    Si j'ai bien compris, quand un évènement survient (prenons le cas d'un click sur un bouton d'une application quelconque), le message passe dans la file d'attente de message générale, puis est dispatché dans la file d'attente propre à l'application (thread) , et là il est géré en passant dans la procédure de message correspondante du window (pris au sens où tu viens de l'expliquer) ?

    Au niveau d'une appli delphi, où se trouve définie cette boucle de message ? Et comment "l'envoi" du message à la bonne fonction (ex : WMxxx) ?

  9. #9
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Castagnems
    Si j'ai bien compris, quand un évènement survient (prenons le cas d'un click sur un bouton d'une application quelconque), le message passe dans la file d'attente de message générale, puis est dispatché dans la file d'attente propre à l'application (thread) , et là il est géré en passant dans la procédure de message correspondante du window (pris au sens où tu viens de l'expliquer) ?
    Oui, c'est bien le principe général. Bien sûr, le contrôle final (Window) peut également répondre : en général, tu vois qu'il a "répondu" au fait que tu le vois s'enfoncer, notamment. Il peut aussi renvoyer un message en réaction, bref faire quasiment n'importe quelle action ou presque.

    Citation Envoyé par Castagnems
    Au niveau d'une appli delphi, où se trouve définie cette boucle de message ?
    Comme pour les contrôles, via une méthode WndProc. Cependant, elle n'est pas normalement visible, et je te déconseille de la surcharger.
    Toutefois, tu peux utiliser un composant TApplicationEvents et taper dans sa méthode OnMessage si tu veux le faire "propre".

    Citation Envoyé par Castagnems
    Et comment "l'envoi" du message à la bonne fonction (ex : WMxxx) ?
    C'est lié au fait que ton fameux "WM_PAINT" n'est en fait qu'un numéro : tu n'as qu'à regarder le début du source de l'unité Messages de Delphi pour comprendre.
    Delphi et Windows communiquent "correctement" parcequ'ils utilisent les mêmes numéros pour les mêmes messages, tout simplement.
    Lorsque Delphi compile ton source et qu'il trouve des directives "message" sur tes procédures/méthodes, il "rajoute" le Case correspondant à la boucle de message de l'objet correspondant. C'est complètement transparent pour toi, mais c'est pour ça qu'il faut préciser le message traité dans la déclaration.

    [EDIT]
    N'oublie pas qu'une application Delphi (et toutes les applis Windows ou presque, d'ailleurs) n'ont pas qu'une seule boucle de messages : tu en as bien sûr une pour l'appli elle-même, mais également une par bouton, case à cocher, bouton radio, etc... Simplement, celles des contrôles sont beaucoup plus simples et "primitives" que celle de l'application, tu t'en doutes.
    [/EDIT]

    C'est plus clair pour toi ?

  10. #10
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 681
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 681
    Points : 7 112
    Points
    7 112
    Par défaut
    Citation Envoyé par Mac LAK
    Comme pour les contrôles, via une méthode WndProc. Cependant, elle n'est pas normalement visible, et je te déconseille de la surcharger.
    Pourquoi ?

    :

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 45
    Points : 34
    Points
    34
    Par défaut
    Oui beaucoup :-)

  12. #12
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Lung
    Pourquoi ?
    Parcequ'il ne maîtrise pas (pas encore, du moins) le système de messagerie Windows, et que foirer la boucle de messages principale d'une appli n'est pas "neutre" : sous Windows 9x, ça peut complètement verrouiller ton OS, sous Windows NT tu peux être amené à devoir killer le processus manuellement.

    Après, il est évident que lorsque l'on connaît très bien ce système, surcharger WndProc n'est pas plus dangereux qu'un appel API. Mais pour un débutant, c'est (trop) facile d'oublier un translate ou un dispatch, ou de consommer un message qui ne devrait pas l'être.

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 45
    Points : 34
    Points
    34
    Par défaut
    Je suis curieux, mais pas fou

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 45
    Points : 34
    Points
    34
    Par défaut
    Bonjour, afin d'émuler un placement de fenêtre "à la delphi", j'ai écrit ceci ... ce qui permet donc à ma form d'avoir sa propre gestion de ce type de message.

    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
    procedure tMaForm.WMSysCommand ( var Message : TWMSysCommand ) ;
    begin
      if ( Message.cmdtype and $FFF0 )= SC_MAXIMIZE then begin
        inherited ; 
     
        top    := tForm(Owner).Top + tForm(Owner).Height          ;
        left   := 0                                               ;
        width  := Screen.WorkAreaWidth                            ;
        height := Screen.WorkAreaHeight - ( tForm(Owner).Height + tForm(Owner).Top - 6 ) ;
     
        tForm(Owner).SetFocus ;
        self.SetFocus ;
     
      end else inherited;
    end;
    Peut-on parler de surcharge de méthode static ?

    Si je ne mets pas l'inherited (dans le if), il y a des petits bugs (notamment au niveau des icones de la form). Cependant la littérature dit qu'inherited rime avec surcharge de méthodes virtuelles ... Quelle en est la signification dans ce cas ?

    Concernant le cheminement du message, j'ai exploré un peu les sources, mais ca m'a plus troublé. En effet, dans tApplication, on reénvoie un message à windows.

    Je pensais qu'au click sur la fenêtre, Windows générait 1 message, qui passe par le pool général, puis est dispatché à l'application, puis au composant, et la qu'il était traité. Mais dans tApplication.WndProc, on trouve ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    ...
          case Msg of
            WM_SYSCOMMAND:
              case WParam and $FFF0 of
                SC_MINIMIZE: Minimize;
                SC_RESTORE: Restore;
              else
                Default;
              end;
    ...
    Et dans l'implémentation de MiniMize, on trouve ceci :

    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
    procedure TApplication.Minimize;
    begin
      if not IsIconic(FHandle) then
      begin
        NormalizeTopMosts;
        SetActiveWindow(FHandle);
        if (MainForm <> nil) and (ShowMainForm or MainForm.Visible)
          and IsWindowEnabled(MainForm.Handle) then
        begin
          SetWindowPos(FHandle, MainForm.Handle, MainForm.Left, MainForm.Top,
            MainForm.Width, 0, SWP_SHOWWINDOW);
          [b]DefWindowProc[/b](FHandle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
        end else
          ShowWinNoAnimate(FHandle, SW_MINIMIZE);
        if Assigned(FOnMinimize) then FOnMinimize(Self);
      end;
    end;
    Cela veut-il dire qu'on s'occupe de placement de la fenêtre, et puis qu'on passe la main à quelqu'un d'autre ? Mais à qui ? DefWindowProc provient de la DLL user32. C'est sensé appelé la procédure de traitement de mesasge par défaut. Une procédure système ? Dans ce cas ci, qui est-ce ?

    J'espère que vous pourrez m'éclairer.

    Quoiqu'il en soit merci ! :-)

Discussions similaires

  1. Message de sécurité à l'envoi de message en VBA
    Par galopin01 dans le forum VBA Outlook
    Réponses: 3
    Dernier message: 21/06/2010, 16h33
  2. Réponses: 8
    Dernier message: 19/03/2009, 20h33
  3. Afficher un message de confirmation avant suppression des messages
    Par JackBeauregard dans le forum Général JavaScript
    Réponses: 16
    Dernier message: 18/08/2006, 14h17
  4. Réponses: 6
    Dernier message: 03/09/2003, 11h29

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