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++Builder Discussion :

Passer pointeur via message � autre prog


Sujet :

C++Builder

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
    162
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2002
    Messages : 162
    Par d�faut Passer pointeur via message � autre prog
    j'avais un probl�me : mon programme se lan�ait plusieurs fois lorsque l'on s�lectionnait plusieurs fichiers dans l'explorateur et qu'on appuyait sur "Entr�e".

    Ca c'est r�solu.

    MAIS

    j'aimerai que les autres instances du programme, avant de se fermer, envoient leurs param�tres au programme d�j� lanc�.

    J'ai donc mis en place un petit message : WM_ADDFILE
    en me disant que je pourrais mettre en wParam un pointeur sur la chaine de param�tres.

    non.

    �a ne fonctionne pas.

    Pour voir j'ai essay� de passer juste un pointeur sur un entier, �a donne �a :

    dans le WinMain :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #define WM_ADDFILE  (WM_USER + 2005)
     
    ...
     
        int* pMsg;
        pMsg = new int;
     
        AnsiString s = (int)pMsg;    //on affiche l'adresse pointée
        MessageBox(NULL, s.c_str(), "toto", MB_OK);
     
        PostMessage(hPreviousInstance, WM_ADDFILE, (WPARAM)pMsg, NULL);
    et dans la m�thode OnMessage d'un TApplicationEvents:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        if (Msg.message == WM_ADDFILE)
        {
            if (*( (int*)Msg.wParam ) == 24)
                MessageBox(NULL, "message24", "titi", MB_OK);
            else
                MessageBox(NULL, "echec24", "titi", MB_OK);
     
            delete (int*)Msg.wParam;
            Handled = true;
        }
    la valeur de wParam correspond bien � l'adresse point�e pas pMsg mais vaut "????"

    euh... pourquoi ?
    quelle autres solutions pour passer les param�tres du programme au programme d�j� pr�sent ?


    [Mod�ration, Alacazam : Pri�re d'utiliser un langage correct, merci]

  2. #2
    Membre �prouv� Avatar de ken_le_videur
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    129
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 129
    Par d�faut
    Utilise SendMessage() � la place de POstMessage(). PostMessage() ne doit pas �tre utilis�e avec des pointeurs.

  3. #3
    Membre confirm�
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    162
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2002
    Messages : 162
    Par d�faut
    mais SendMessage n'est pas r�ceptionn� par mon TApplicationEvents ...

    Je crois que j'avais essay� de mettre le message dans un BEGIN_MASSAGE_MAP END_MESSAGE_MAP mais il n'a pas �t� re�u non plus

    je r�essaie et je vous informe...

  4. #4
    Membre �prouv� Avatar de ken_le_videur
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    129
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 129
    Par d�faut
    A priori, l'utilisation de l'un ou de l'autre ne cr�e aucune diff�rence pour l'application receptrice. La diff�rence se situe au niveau de l'application emettrice.

  5. #5
    Membre confirm�
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    162
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2002
    Messages : 162
    Par d�faut
    ah l� l�...

    je n'y comprends rien.

    j'ai dans l'ordre :

    dans mon main :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    #define WM_ADDFILE (WM_USER + 2005)
     
     
    WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
      ...
                SendMessage(hPreviousInstance, WM_ADDFILE, (WPARAM)pMsg, NULL);
      ...
    pour envoyer le message WM_ADDFILE � l'instance pr�c�dente de mon programme.

    dans mon MainForm.h
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #define WM_ADDFILE (WM_USER + 2005)
    ...
    protected:
        BEGIN_MESSAGE_MAP
            //Pour le drop de fichiers
            VCL_MESSAGE_HANDLER(WM_DROPFILES, TMessage, WMDropFiles);
            //Pour l'ajout de fichier quand il y plusieurs instances 
            VCL_MESSAGE_HANDLER(WM_ADDFILE,   TMessage, WMAddFile);
        END_MESSAGE_MAP(TForm)
     
    private:
        virtual void __fastcall WMDropFiles(TMessage &Message);
        virtual void __fastcall WMAddFile(TMessage &Message);
    et ma fonction WMAddFile qui est la m�me que le OnMessage du feu TApplicationEvents

    et bien devinez... je ne rentre jamais dans WMAddFile.
    alors que si dans le WinMain je mets
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    SendMessage(hPreviousInstance, WM_CLOSE, NULL, NULL);
    la fen�tre se ferme. Donc le message est bien envoy�, mais pas re�u ?

    le DropFile fonctionne bien par contre. Ca viendrait peut-�tre de la d�finition de WM_ADDFILE ?

  6. #6
    Membre confirm�
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    162
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2002
    Messages : 162
    Par d�faut
    Bon, alors deux possibilit�s : Personne ne me r�pond car

    - tout les utilisateurs du forum sont en train de plancher sur mon probl�me et personne ne trouve de solution.
    - tout le monde me fait la gueule parce que j'ai dit que j'aimais bien jumelle.

    (Optons pour la premi�re possibilit�...)

    R�jouissez-vous, j'ai trouv� une solution. Ca m'a l'air d'�tre du bidouillage mais �a fonctione....

    Premi�rement : on ne passe pas de pointeur � un autre prog car windows leur attribue des espaces m�moire s�par�s. Donc c'est un �chec. Il faut utiliser des segments de m�moire partag�e.

    Deuxi�mement : Les messages �taient re�us n'importe comment car ils �taient envoy�s � l'application et non pas � la fen�tre principale. L'application voyant WM_CLOSE se fermait (normal) mais elle n'envoyait pas WM_ADDFILE aux fen�tres. Le probl�me est r�solu en retrouvant la fen�tre principale d�j� pr�sente plut�t que l'application et en lui envoyant les messages.

    Je vous explique ma m�thode : Lors du lancement du prog je cr�e un segment de m�moire partag�e. Lorsqu'une autre instance est lanc�e, elle essaie de cr�er un segment de m�moire partag�e, mais �choue. Ca nous permet de savoir que le prog est d�j� lanc�. Que fait-elle alors ? elle retrouve le segment d�j� existant, prend ses fichiers en param�tres et pour chaque fichier elle dis � l'application d�j� lanc�e "tiens, je te file mon fichier" et elle �crit le chemin d'acc�s au fichier dans le segment partag�. Et voil� !

    bon, un peu de d�tails : Mon prog est un visualiseur d'images. lorsque dans l'explorateur vous s�lectionnez n fichiers et faites "entr�e", le programme est lanc� n fois. Maintenant n-1 programmes filent leur param�tre au dernier programme :

    Dans le fichier main :
    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
     
    #define WM_ADDFILE      (WM_USER    + 2010)
    #define WM_ADDFILESTART (WM_ADDFILE +   10)
    #define FILEMAPPINGNAME "VieuxVerFileMapping_"
     
    //---------------------------------------------------------------------------
    void __fastcall SendFileToPrevious(HANDLE hFileMap)
    {
        //on retrouve l'instance précédente
        //ATTENTION : les messages seront passés à la fiche principale et non pas à l'application
        //donc il faut retrouver la fiche principale
        HWND hPreviousInstance = FindWindow( "TMainFormFrm", NULL);
     
        if (hPreviousInstance)    //c'est cool, on l'a trouvée
        {
            //On retrouve la mémoire partagée
            char* pFile = (char*)MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
     
            int i = 1;
     
            //on file tous les fichiers.
            while (ParamStr(i) != "")
            {   
                //attendre que les fichiers précédents aient étés traités avant d'écrire en mémoire
                //VOIR (*)
                SendMessage(hPreviousInstance, WM_ADDFILESTART, 0, 0);
     
                strcpy(pFile, ParamStr(i).c_str());	//écrit le nom du fichier dans la mémoire partagée
                SendMessage(hPreviousInstance,	//dire à l'instance précédente qu'il y a un fichier
                    WM_ADDFILE,
                    (WPARAM)( ( ((DWORD)hFileMap) & 0xFFFF0000 ) >> 16 ),	//heu je ne me rappelle plus de la taille des (W/L)Param
                    (LPARAM)(   ((DWORD)hFileMap) & 0xFFFF)    );		//alors je passe deux octets du handle du fichier sur chaque
     
                i++;
            }
     
            UnmapViewOfFile(hFileMap);
        }
    }
     
    //---------------------------------------------------------------------------
    WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
        Application->Title = APPNAME;
     
        //on crée le segment de mémoire partagée
        HANDLE hFileMap = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE,
                     0, MAX_PATH, FILEMAPPINGNAME);
     
        if (GetLastError() == ERROR_ALREADY_EXISTS) //le programme est déjà lancé
        {
            if (ParamStr(1) != "")	//allez hop, on file les fichiers au prog
                SendFileToPrevious(hFileMap);
     
            return 0;
        }
     
        try
        {
             //... initialisation de l'appli
        }
        catch (Exception &exception)
        {
             Application->ShowException(&exception);
        }
        catch (...)
        {
             //...
        }
     
        //Penser à fermer le fichier avant de partir
        CloseHandle(hFileMap);
        return 0;
    }
    (*) ceci est du bidouillage mais �a aide bien :
    Le programme auquel on envoie les messages traite ces messages un par un. normal.
    Rappelons que SendMessage bloque le programme appelant tant que le message n'a pas �t� trait� (contrairement � PostMessage).
    Comme indiqu� plus loin, WM_ADDFILESTART ne fait rien. Disons que nous ne l'utilisions pas :
    Chaque nouvelle instance du programme va �crire dans le segment m�moire.

    Le programme appel� re�oit les messages :
    WM_ADDFILE fichier1
    WM_ADDFILE fichier2
    WM_ADDFILE fichier3
    WM_ADDFILE fichier4

    le probl�me est que les messages seront envoy�s avant m�me qu'il ait fini de traiter le premier fichier. Donc pour les trois autres messages il lira "fichier4"

    Maintenant avec le WM_ADDFILESTART :
    WM_ADDFILESTART
    WM_ADDFILE fichier1
    WM_ADDFILESTART
    WM_ADDFILE fichier2
    WM_ADDFILESTART
    WM_ADDFILE fichier3
    WM_ADDFILESTART
    WM_ADDFILE fichier4

    Chaque application envoie son WM_ADDFILESTART. Le prog appel� re�oit le premier fichier. Il s'en occupe. Pendant ce temps, une autre appli lui envoie WM_ADDFILESTART. Mais comme l'appel� est trop occup� par le traitement du premier fichier, il ne repond pas tout de suite, il r�pondra quand il aura fini.
    Donc, exactement ce qu'on voulait, tant que l'appelant ne re�oit pas de r�ponse � son WM_ADDFILESTART, il attend... et pendant ce temps l� il n'�crit pas en m�moire partag�e !!!

    Alors l� on est content, �a roule !

    pour ce qui est du traitement des messages :

    dans le .h
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    //... des trucs
    private:
        virtual void __fastcall WMAddFile(TMessage &Message);
        virtual void __fastcall WMAddFileStart(TMessage &Message) {};	//fonction qui ne fait rien
     
    public:
        BEGIN_MESSAGE_MAP
            //Pour initialiser l'ajout de fichier quand il y plusieurs instances
            VCL_MESSAGE_HANDLER(WM_ADDFILESTART,   TMessage, WMAddFileStart);
            //Pour l'ajout de fichier quand il y plusieurs instances
            VCL_MESSAGE_HANDLER(WM_ADDFILE,   TMessage, WMAddFile);
        END_MESSAGE_MAP(TForm);
    dans le .cpp
    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
     
    void __fastcall TMainFormFrm::WMAddFile(TMessage &Message)
    {
        //reconstruire le handle
        HANDLE hFile = (HANDLE) (
                ( ((DWORD)Message.WParam) << 16 )
                |
                ( (DWORD)Message.LParam )
                                );
     
        if (hFile)
        {
    	//on récupère le segment de mémoire
            char* pFile = (char*)MapViewOfFile(hFile, FILE_MAP_READ, 0, 0, 0);
     
            if (pFile)
            {
                char sPath[MAX_PATH];
                strcpy(sPath, pFile);
     
                //on ajoute l'image à la liste déjà présente
                m_iImageIndex = g_pSlideManager->Count();
                g_pSlideManager->AddSlide(sPath);
                SetSlide();
     
                UnmapViewOfFile(hFile);
            }
        }
     
        //on met l'application au premier plan
        Application->BringToFront();
    }
    voil�, j'esp�re que �a pourra aider des gens !!

  7. #7
    Invit� de passage
    Inscrit en
    Juillet 2003
    Messages
    1
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 1
    Par d�faut petit rectificatif
    salut,

    j'ai essay� ton code qui m'a vraiment rendu service, merci
    mais j'ai deux petites remarques :

    1. la taille des L/W param est de au moins 32bits (j'ai pass� 0x123456789) donc on peut all�ger � peine le code

    2. pour le WM_ADDFILESTART, en fait je crois que �a ne se passe pas tout � fait comme tu le dis :

    la 1� app. envoie son AddFileStart, puis �crit et envoie AddFile
    la 2� app. envoie son AddFileStart puis attend
    la 3� app. envoie son AddFileStart puis attend
    le traitement du premier fichier est fini, l'application m�re r�pond imm�diatement aux deux AddFileStart
    les 2 app. re�oivent la notification quasi simultan�ment
    les 2 app. �crivent en m�moire quasi simultan�ment
    les 2 app. envoie leur AddFile quasi simultan�ment
    l'application m�re traite deux AddFile avec la m�me chose dans la m�moire

    Donc en tout cas c'est ce qu'il se passe chez moi, mais si �a marche chez toi redis-moi, si j'ai fait une erreur en recopiant ...
    Enfin moi je n'ai pas vraiment besoin de cette fonctionnalit� mais bon, �a m'intrigue quand m�me ...

    cyril

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. R�ponses: 2
    Dernier message: 02/07/2014, 12h16
  2. R�ponses: 4
    Dernier message: 01/02/2013, 16h05
  3. R�ponses: 2
    Dernier message: 01/02/2013, 15h50
  4. Commander d'autres prog via VB
    Par d.jphilippe dans le forum Windows Forms
    R�ponses: 11
    Dernier message: 19/08/2008, 23h20
  5. [statusbar] recuperer des infos d'un autre prog
    Par noyax dans le forum API, COM et SDKs
    R�ponses: 2
    Dernier message: 20/12/2002, 15h52

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