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

C++ Discussion :

Passer une structure, d'une dll vers mon exe


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 92
    Par défaut Passer une structure, d'une dll vers mon exe
    Hello,

    J'essaie de créer des petits programmes illustrant le fonctionnement de chacun des type de hook.
    J'ai donc un programme principal et une dll pour initier un hook global.

    Dans le type de hook WH_CALLWNDPROC qui intercepte les message des fonctions de type SendMessage, j'ai donc une structure de récupération des données du type CWPSTRUCT.

    maDLL.dll
    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
    LRESULT CALLBACK CallWndProc (int nCode, WPARAM wParam, LPARAM lParam) {
     
        CWPSTRUCT *cwpstruct = (CWPSTRUCT*)lParam;      // le paramètre lParam (ou cwpstruct) pointe sur une stucture CWPSTRUCT (contenant les données à traiter pour ce type de hook)
     
     
        if (nCode < 0)  return CallNextHookEx(hHook_CWP, nCode, wParam, lParam);
     
     
        switch (nCode) {                                        // nCode est le code envoyé par le système. Lors d'un hook de type WH_CALLWNDPROC si le message est de type
            case HC_ACTION:                                     // HC_ACTION, alors on peut traiter le message intercepté, sinon le message doit être rejeté car non pertinent pour ce type de hook.
     
                if (cwpstruct->message == WM_NULL) {            // On ne détecte que les messages WM_NULL envoyés par les fonctions de la famillle SendMessage() & Co.
                    //UninstallCallWndProcHook (hHook_CWP);
                    hProgPrincipal = FindWindow (NULL, AppName_ProgPrincipal);
                    PostMessage (hProgPrincipal, WM_CALLWNDPROCMSG, (WPARAM) cwpstruct->hwnd, (LPARAM) cwpstruct);
                    //wsprintf (buffer, formatHexa, hProgPrincipal); MessageBoxA(0, buffer, buffer, 0);
                }
                break;
     
            default:
                break;
        }
     
    	return CallNextHookEx (hHook_CWP, nCode, wParam, lParam);
    }
    la structure "cwpstruct" reçoit effectivement les bonnes données attendues, j'utilise la fonction PostMessage() pour renvoyer ces données vers mon programme principal mais c'est là qu'il se passe un problème.
    le paramètre (LPARAM) cwpstruct est sensé renvoyer l'intégralité des données placées dans cette structure, alors que (WPARAM) cwpstuct->hwnd est sensé revoyer que le paramètre hwnd de cette même structure pour contrôler ce paramètre lors du passage.

    Individuellement (WPARAM) cwpstuct->hwnd est correctement transmis par PostMessage, mais pas la structure elle-même dans sa totalité (LPARAM) cwpstruct.

    Voici le code du prog principal.
    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
    BOOL CALLBACK DlgMain(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
        RECT rect;
     
        switch(uMsg) {
            // ---------------------------------------------------------------------------------------------------------------------------- DEBUT ---- case WM_INITDIALOG:
            case WM_INITDIALOG: {
     
            }
            return TRUE;
            // ---------------------------------------------------------------------------------------------------------------------------- FIN ------ case WM_INITDIALOG:
     
     
            // ---------------------------------------------------------------------------------------------------------------------------- DEBUT ---- case WM_CLOSE
            case WM_CLOSE: {
                EndDialog(hDlg, 0);
            }
            return TRUE;
            // ---------------------------------------------------------------------------------------------------------------------------- FIN ------ case WM_CLOSE
     
     
            // ---------------------------------------------------------------------------------------------------------------------------- DEBUT ---- case WM_COMMAND:
            case WM_COMMAND: {
     
            }
            return TRUE;
            // ---------------------------------------------------------------------------------------------------------------------------- FIN ------ case WM_COMMAND:
     
     
            // ---------------------------------------------------------------------------------------------------------------------------- DEBUT ---- case WM_CALLWNDPROCMSG
            case WM_CALLWNDPROCMSG : {
                CWPSTRUCT *cwpstruct = (CWPSTRUCT*) lParam;
                wsprintf (buffer, resultat, cwpstruct->hwnd, cwpstruct->message, cwpstruct->wParam, cwpstruct->lParam,   wParam);
                SetDlgItemText (hDlg, IDC_RICHEDIT, buffer);
           }
            return TRUE;
    ...
    ..
    .

    Comment passer correctement le contenu de ma structure CWPSTRUCT.

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 487
    Par défaut
    Vous passez un pointeur local à l'appel d'une fonction (c'est un paramètre de la fonction), dans le contexte d'un programme A vers un programme B, via un canal asynchrone.

    C'est un peu comme si on programmait du temps de Window3 en 16 bits. Maintenant c'est un peu IMPOSSIBLE.

    Vous devez aménager un canal de communication entre ces 2/X programmes. X->c'est un hook donc potentiellement dans tous les programmes en exécution.

    Le choix du canal de communication est fonction de vos contraintes.

    Le plus proche de votre solution initiale, c'est l'utilisation de WM_COPYDATA :
    http://www.codeproject.com/Articles/...ng-WM-COPYDATA

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    J'allais le dire, le plus simple est d'utiliser WM_COPYDATA (et avec SendMessage(), pas PostMessage()) et Windows fera le marshalling pour toi.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 92
    Par défaut
    Bien vu ! Merci.

    Je poste la solution à ce problème, cette structure pour passer des données entre application peut en intéresser d'autres.


    Dans ma DLL :
    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
    LRESULT CALLBACK CallWndProc (int nCode, WPARAM wParam, LPARAM lParam) {
     
        CWPSTRUCT *cwpstruct = (CWPSTRUCT*)lParam;      // le paramètre lParam (ou cwpstruct) pointe sur une stucture CWPSTRUCT (contenant les données à traiter pour ce hook)
        COPYDATASTRUCT cds;
     
        if (nCode < 0)  return CallNextHookEx(hHook_CWP, nCode, wParam, lParam);
     
     
        if (wParam == 0) {                                          // Si wParam = 0 alors le message hoooké provient d'un SendMessage d'autre programme que cette dll même.
     
            switch (nCode) {                                        // nCode est le code envoyé par le système. Lors d'un hook de type HW_CALLWNDPROC si le message est de type
                case HC_ACTION:                                     // HC_ACTION, alors on peut traiter le message intercepté, sinon le message doit être rejeté car non pertinent pour ce type de hook.
     
                    if (cwpstruct->message == WM_NULL) {            // On ne détecte que les messages WM_NULL envoyés par les fonctions de la famille SendMessage() & Co.
                        hProgPrincipal = FindWindow (NULL, AppName_ProgPrincipal);
     
                        cds.dwData = 0x28110091;            // Mon code unique de communication entre la maDLL.dll et le prog.exe
                        cds.cbData = sizeof (CWPSTRUCT);    // On passe la taille de la structure CWPSTRUCT puisque c'est elle que je veux transmettre à mon prog.exe
                        cds.lpData = (LPVOID) cwpstruct;    // Les données transportées par COPYDAASTRUCT sont les données de ma structure cwpstruct elles-mêmes. 
                        SendMessage (hProgPrincipal, WM_COPYDATA, (WPARAM) NULL, (LPARAM) (LPVOID)&cds);    // et j'envoie la totalité de COPYDATASTRUCT contenant elle-même
                                                                                                            // les données de la structure CWPSTRUCT.
                    } // FIN if (... == WM_NULL) {
                    break;
     
                default:
                    break;
            } // FIN switch (nCode) {
        } // FIN if (wParam) {
    	return CallNextHookEx (hHook_CWP, nCode, wParam, lParam);
    }
    //*********************************************** MOUSE *************************************************************


    Mon prog.exe
    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
     
    BOOL CALLBACK DlgMain(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
     
        switch(uMsg) {
            // ---------------------------------------------------------------------------------------------------------------------------- DEBUT ---- case WM_INITDIALOG:
            case WM_INITDIALOG: {
     
            }
            return TRUE;
            // ---------------------------------------------------------------------------------------------------------------------------- FIN ------ case WM_INITDIALOG:
     
     
            // ---------------------------------------------------------------------------------------------------------------------------- DEBUT ---- case WM_CLOSE
            case WM_CLOSE: {
     
            }
            return TRUE;
            // ---------------------------------------------------------------------------------------------------------------------------- FIN ------ case WM_CLOSE
     
     
            // ---------------------------------------------------------------------------------------------------------------------------- DEBUT ---- case WM_COMMAND:
            case WM_COMMAND: {
     
            }
            return TRUE;
            // ---------------------------------------------------------------------------------------------------------------------------- FIN ------ case WM_COMMAND:
     
     
            // ---------------------------------------------------------------------------------------------------------------------------- DEBUT ---- case WM_COPYDATA
            case WM_COPYDATA : {
                COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;         // pcds est un pointeur sur une structure COPYDATASTRUCT laquelle est passée par le membre lParam
                CWPSTRUCT* cwpstruct = (CWPSTRUCT*) pcds->lpData;       // cwpstruct est un pointeur sur le membre lpData (de la structure précédente), membre qui lui-même 
                                                                        // pointe sur les données à transmettre donc sur la structure CWPSTRUCT provenant de la dll
     
                if (pcds->dwData == 0x28110091) {                       // Mon code unique de communication entre maDLL.dll et le prog.exe
                    wsprintf (buffer, resultat, cwpstruct->hwnd, cwpstruct->message, cwpstruct->wParam, cwpstruct->lParam); // Affichage des membres de la structure cwpstruct
                    SetDlgItemText (hDlg, IDC_RICHEDIT, buffer);                                                            // dans une RICHEDIT Control.
                }
           }
            return TRUE;
            // ---------------------------------------------------------------------------------------------------------------------------- FIN ------ case WM_COPYDATA
     
     
        } // FIN switch(uMsg) {
        return FALSE;
    }//------------------------------------------------------------------------------------------------------------------------------------------------------------------//

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 487
    Par défaut
    Merci pour ce code simple, qui illustre bien la solution.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 15/10/2009, 13h33
  2. [XL-2007] Afficher une checkbox dans une feuille si une checkbox d'une autre feuille est cochée
    Par JessieCoutas dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 18/08/2009, 13h35
  3. Réponses: 5
    Dernier message: 12/10/2008, 13h41
  4. Recherche une valeur d'une cellule dans une colonne d'une autre feuille
    Par kourria dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 21/06/2007, 13h48
  5. Réponses: 7
    Dernier message: 26/04/2007, 12h04

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