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 :

[Win32] Pointeur sur fonctions et méthodes de classe


Sujet :

Langage Delphi

  1. #1
    Invité
    Invité(e)
    Par défaut [Win32] Pointeur sur fonctions et méthodes de classe
    Bonjour,

    Je suis en train de creer une petite classe pour creer facilement des fenetre Win32, et j'ai un probleme au niveau du passage de la fonction d'evennement dans la structure TWndClassEx.

    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
    74
    75
    76
     
    type
        Window = class
        public
            constructor Create();
            destructor Destroy(); override;
     
            function InitWindow(width, height :integer; title :string) :boolean;
            function Update() : boolean;
     
     
        protected
             function MsgProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
            var
                m_Hwnd      : HWND;
                m_WndClass  : TWndClassEx;
     
        end; // class Window
     
    implementation
     
    constructor Window.Create();
    begin
        inherited Create;
     
        with m_WndClass do
        begin
            cbSize          := SizeOf(TWndClassEx);
            style           := CS_CLASSDC;
            lpfnWndProc     := @MsgProc;
            cbClsExtra      := 0;
            cbWndExtra      := 0;
            hInstance       := GetModuleHandle(nil);
            hIcon           := 0;
            hCursor         := 0;
            hbrBackground   := 0;
            lpszMenuName    := nil;
            lpszClassName   := 'ConfEngine';
            hIconSm         := 0;
        end;
     
        RegisterClassEx(m_WndClass);
    end;
     
    destructor Window.Destroy;
    begin
        UnregisterClass('ConfEngine', m_WndClass.hInstance);
    end;
     
    function Window.InitWindow(width: Integer; height: Integer; title: string):boolean;
    begin
        m_Hwnd := CreateWindow('ConfEngine',
                               PAnsiChar(title),
                               WS_OVERLAPPEDWINDOW,
                               100, 100, width, height,
                               0, 0, m_WndClass.hInstance, self);
        // Show the window
        ShowWindow(m_Hwnd, SW_SHOWDEFAULT);
        UpdateWindow(m_Hwnd);
     
        result := true;
    end;
     
    function Window.Update() :boolean;
    var
        msg : TMsg;
    begin
        result := GetMessage(msg, 0, 0, 0);
        while result do
        begin
            TranslateMessage(msg);
            DispatchMessage(msg);
     
            result := GetMessage(msg, 0, 0, 0);
        end;
    end;
    j'ai l'erreur de compilation suivante, au niveau de la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    lpfnWndProc     := @MsgProc;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    [DCC Error] application.window.pas(38): E2036 Variable required
    Que faire ? j'ai loupé quelque chose ?

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    c'est normal, la WndProc n'est pas une méthode de classe.

    toutes les méthodes possèdent un paramètre implicite "self" qui ne correspond pas à la signature de WndProc.

    il y a plusieurs façon de gérer cela, mais dans tous les cas, il faut avoir une fonction WndProc qui va déterminer à quelle classe Delphi correspond le Hwnd en paramètre.

    1) si l'application ne contient qu'une fenêtre (c'est plutôt rare ) alors il suffit que la function WndProc appelle une variable globale qui pointer sur la classe

    2) il est possible d'utiliser Get/SetProp pour associer la classe au HWnd

    3) Delphi utilise MakeObjectInstance pour générer un code dynamique qui invoque la méthode de classe

    peut-être que cette dernière solution tu suffiras.

  3. #3
    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
    Voir aussi : Combiner des procédures et des méthodes
    La solution mise en place par CodeGear est en effet celle de MakeObjectInstance.

    Moi je préfère MakeProcOfStdCallMethod :
    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
    function MakeProcOfStdCallMethod(const Method: TMethod): Pointer;
    type
      PStdCallRedirector = ^TStdCallRedirector;
      TStdCallRedirector = packed record
        PopEAX: Byte;
        PushObj: Byte;
        ObjAddress: Pointer;
        PushEAX: Byte;
        Jump: TJmpInstruction;
      end;
    begin
      GetMem(Result, SizeOf(TStdCallRedirector));
      with PStdCallRedirector(Result)^ do
      begin
        PopEAX := $58;
        PushObj := $68;
        ObjAddress := Method.Data;
        PushEAX := $50;
        MakeJmp(Jump, Method.Code);
      end;
    end;
    Plus simple, plus rapide, et valable pour n'importe quelle méthode stdcall.

    Voir aussi (publication prochainement) : Construire une procédure pointant sur une méthode

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bon, merci à vous, j'ai résolu mon problème de manière assez simple... en faisant un méthode de classe et en l'appelant ensuite ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    lpfnWndProc     := @Window.MsgProc;
    Ce qui me suffit amplement.

  5. #5
    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
    Citation Envoyé par bibi.skuk Voir le message
    Bon, merci à vous, j'ai résolu mon problème de manière assez simple... en faisant un méthode de classe et en l'appelant ensuite ainsi :
    Euh... ? T'as testé Comment tu l'as déclarée, ta méthode de classe ?

Discussions similaires

  1. mélange de pointeurs sur fonctions et classes
    Par membreComplexe12 dans le forum C++
    Réponses: 4
    Dernier message: 15/10/2012, 14h06
  2. Réponses: 5
    Dernier message: 03/10/2011, 16h20
  3. Pointeur sur fonction de classe anonyme
    Par dewsz dans le forum C++
    Réponses: 5
    Dernier message: 15/07/2008, 11h00
  4. Réponses: 12
    Dernier message: 30/06/2006, 16h46
  5. Glut / Class / Pointeur sur fonction
    Par areS. dans le forum GLUT
    Réponses: 5
    Dernier message: 02/12/2005, 20h50

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