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

Windows Discussion :

win32 - Gestion des messages sans procedure de fenetre -


Sujet :

Windows

  1. #1
    Membre extrêmement actif Avatar de nikau6
    Homme Profil pro
    Inscrit en
    Février 2008
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Février 2008
    Messages : 406
    Points : 737
    Points
    737
    Par défaut win32 - Gestion des messages sans procedure de fenetre -
    Bonjours a tous.
    Mon message concerne l'API Win32.
    J'aurai voulu savoir si il etait possible de gerer les messages(WM_COMMAND, WM_USER, ect...) sans avoir a utiliser du tout la procedure de fenetre "LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM)" ?
    Le tout en C/C++ evidement. Je ne parle pas de MFC, DotNet, ect...

    Merci

    ps : je precise que je connais deja un peu, mais pas beaucoup, cette API ayant realiser avec il y a quelque temps un petit moteur de jeu 2D et quelques autres petites applications.

    Il me semble qu'avec les MFC, que je ne connais pas, la procedure de fenetre ne soit pas utilisee. Savez vous comment cela fonctionne en interne ?

  2. #2
    Membre confirmé
    Homme Profil pro
    .
    Inscrit en
    Juin 2002
    Messages
    239
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : .
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2002
    Messages : 239
    Points : 567
    Points
    567
    Par défaut
    Bonjour.

    L'API Win32 offre deux fonctions de base pour recevoir les messages :
    GetMessage et PeekMessage.

    La première attend qu'un message soit disponible avant de revenir, la seconde revient tout de suite même s'il n' y a pas de message disponible.

    Voir la MSDN à leur sujet.

  3. #3
    Membre extrêmement actif Avatar de nikau6
    Homme Profil pro
    Inscrit en
    Février 2008
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Février 2008
    Messages : 406
    Points : 737
    Points
    737
    Par défaut
    Merci pour ta reponse, mais ca n'etait pas ma question. Je connais GetMessage() et PeekMessage().
    Je demandais si il etait possible de se passer de la procedure de fenetre LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM) pour le traitement des message WM_... , est-ce qu'il existe des fonctions dans l'API qui permet le traitement des messages d'une maniere differente ?

  4. #4
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    GetMessage et PeekMessage piquent le message actuellement en tête de file dans la queue de messages du thread courant. On en fait ensuite ce qu'il nous plaît. Cela veut très bien dire qu'avoir une WndProc n'est pas intrinsèquement indispensable dans une application Windows. Cependant, tous les messages ne passent pas obligatoirement par la queue des messages. Au contraire, la majorité des messages sont directement envoyés vers les fenêtres, c'est-à-dire directement vers les procédures de fenêtre. Généralement, Windows met dans la queue des messages les événements liés aux entrées de l'utilisateur (les keydown, mousemove, etc.) et tout ce qu'ils provoquent (WM_CHAR, WM_COMMAND, etc.), ainsi que certains messages non prioritaires (WM_TIMER, WM_PAINT, etc.). Les autres vont directement chez leur destinataire. Cette différence se voit également au niveaux de certaines APIs et non seulement au niveau des notifications. Par exemple, SendMessage appelle directement la procédure de fenêtre alors que PostMessage place un message dans la queue des messages. La procédure de fenêtre est donc finalement indispensable, en pratique .

  5. #5
    Membre extrêmement actif Avatar de nikau6
    Homme Profil pro
    Inscrit en
    Février 2008
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Février 2008
    Messages : 406
    Points : 737
    Points
    737
    Par défaut
    Ok, merci. Je me doutais bien qu'elle etait indispensable... En fait, je suis en train de me fabriquer un petit framework et je voudrais pouvoir encapsuler dans mes classes(CMenu, CButton, ect...) des fonctions qui traitent les messages (CMenu::OnClick(), CButton::Onclick(), ect...), sans rien avoir a rajouter dans la procedure de fenetre lorsque j'utilise mon framework.
    Je crois avoir trouve la solution a l'aide d'un container de struct contenant, entre autre, des pointeurs de fonction, et l'identite du message, et ce container sera place dans la procedure de fenetre et je le remplirai a l'utilisation du framework et non pendant sa compilation... Je ne sais pas si c'est clair.. Je vais voir ce que cela donne.

    Merci encore pour vos reponses :-)

  6. #6
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Il y a quelques années je me suis amusé à faire un truc de ce type, et je m'en suis même longtemps servi. Les sources se trouvent sur le forum C++ : Encapsuler l'API Windows. Ce code a été écrit alors que je débutais en C++ donc ne sois pas surpris de voir des horreurs comme une struct dans une classe là où on aurait pu utiliser l'héritage, etc. A part ce détail, il aura au moins le mérite de mettre en évidence l'architecture des frameworks ou des libs telles que la VCL ou les MFC . Et bien sûr n'hésite pas s'il y a des choses que tu ne comprends pas.

  7. #7
    Membre extrêmement actif Avatar de nikau6
    Homme Profil pro
    Inscrit en
    Février 2008
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Février 2008
    Messages : 406
    Points : 737
    Points
    737
    Par défaut
    Merci, je vais y jeter un œil :-)

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Attention, le prototype de la DialogProc est obsolète; il faut retourner un INT_PTR de nos jours (à cause des messages WM_CTLCOLORxxx)
    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.

  9. #9
    Membre extrêmement actif Avatar de nikau6
    Homme Profil pro
    Inscrit en
    Février 2008
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Février 2008
    Messages : 406
    Points : 737
    Points
    737
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Attention, le prototype de la DialogProc est obsolète; il faut retourner un INT_PTR de nos jours (à cause des messages WM_CTLCOLORxxx)
    Le prototype etait celui de la procedure de fenetre et pas celui d'une boite de dialogue quelconque.

    Sinon, sauriez vous combien il y a de WM_... en tout ? La question peut paraitre saugrenue, mais j'ai vraiment besoin de le savoir. Je n'ai pas trouve la reponse sur msdn, ni ailleurs sur le web...

    Merci.

  10. #10
    Membre extrêmement actif Avatar de nikau6
    Homme Profil pro
    Inscrit en
    Février 2008
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Février 2008
    Messages : 406
    Points : 737
    Points
    737
    Par défaut
    Voila ma solution afin de gerer les messages sans avoir a remplir la procedure de fenetre lorsque j'utilise mon framework. C'est pour l'instant tres basique, je voulais juste poser les bases.
    Dites moi ce que vous en pensez, et si vous auriez fais autrement,dites moi comment vous auriez fait.

    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
    //
    // Xevents.h
    
    // Voici la structure qui s'occupe de la gestion des messages. Les messages 
    // sont stockes dans un tableau XArray.
    
    #ifndef X_EVENTS_H
    #define X_EVENTS_H
    
    #include "Xdefs.h"
    #include "Xarray.h"
    
    X_NAMESPACE_BEGIN
    
    struct XEvent{
    	
    	inline XEvent() : Type(0), Name(nullptr){}
    	inline ~XEvent() { X_DELETE_POINTER_ARRAY(Name) }
    	
    	Xbool (*Event)(HWND wnd, WPARAM wPAram, LPARAM lParam);
    	
    	Xuint Type;
    	Xchar* Name;
    	static XArray<X::XEvent> EventsArray;
    };
    
    XArray<X::XEvent> XEvent::EventsArray(100);
    
    X_NAMESPACE_END
    #endif

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    LRESULT CALLBACK XWindow::WindowProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	for(Xint i=0; i<X::XEvent::EventsArray.Size(); i++)
    	{
    		if(msg == X::XEvent::EventsArray[i].Type)
    		{
    			if(X::XEvent::EventsArray[i].Event(wnd, wParam, lParam))
    			    return 0;
    		}
    	}
    	return DefWindowProc(wnd, msg, wParam, lParam);
    		
    }
    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
    //
    // main.cpp
    // Je commence avec main et non WinMain. WinMain est charger par ma lib. Je me suis inspire de QT sur ce coup la, si un jours je veux rendre mon code portable, ca sera plus facile...
    
    #include "../X.h"
    
    Xbool Event_Escape(HWND wnd, WPARAM wParam, LPARAM lParam);
    Xbool Event_Destroy(HWND wnd, WPARAM wParam, LPARAM lParam);
    
    int main(int argc, char** argv)
    {
    	X::XApplication app(argc, argv); // initialisation du programme.
    
    	X::XWindow* window; // Creation de la fenetre.
    	window = new X::XWindow("X_Window");
    	window->Create(150, 150, 640, 480);
    	window->Show(SW_SHOW);
    
    	X::XEvent event1;
    	event1.Type = WM_KEYDOWN;
    	event1.Name = "ESCAPE";
    	event1.Event = &Event_Escape;
    	X::XEvent::EventsArray.Append(event1);
    
    	X::XEvent event2;
    	event2.Type = WM_DESTROY;
    	event2.Name = "DESTROY";
    	event2.Event = &Event_Destroy;
    	X::XEvent::EventsArray.Append(event2);
    
    	app.Exec(X::GETMESSAGE); // Je lance la boucle de message 
                                                                                                       
           delete window;
           return EXIT_SUCCESS;
    	
    }
    
    Xbool Event_Escape(HWND wnd, WPARAM wParam, LPARAM lParam)
    {
    	X_UNUSED_TYPE(lParam);
    
    	if(X_ON_CLICK(VK_ESCAPE)){
    		DestroyWindow(wnd);
                    return true;
             }
             return false;
    }
    
    
    Xbool Event_Destroy(HWND wnd, WPARAM wParam, LPARAM lParam)
    {
    	X_UNUSED_TYPE(wParam);
    	X_UNUSED_TYPE(lParam);
    
    	ReleaseDC(wnd, X::XWindow::GetDeviceContext());
    	PostQuitMessage(0);
    
            return true;
    }

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    J'ai l'impression qu'un tel code donne des événements communs à tous les types de fenêtre.

    Et en plus, ça remplit le tableau en run-time, alors qu'il peut être défini en compile-time comme le fait MFC (mais MFC utilise un tableau "Message Map" par classe de fenêtre).

    Aussi, je ne suis pas sûr qu'une recherche linéaire soit la meilleure idée pour ça. Vu que le tableau n'est modifié qu'au début et qu'il est consulté très souvent, tu devrais au moins en faire un tableau trié et faire une recherche dichotomique dessus (avec bsearch() en C ou std::binary_search<>() en C++).

    Edit: J'ai du mal à voir l'utilité du nom, aussi. Surtout que tu y mets une chaîne littérale et que tu sembles faire un delete dessus dans le destructeur...
    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.

  12. #12
    Membre extrêmement actif Avatar de nikau6
    Homme Profil pro
    Inscrit en
    Février 2008
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Février 2008
    Messages : 406
    Points : 737
    Points
    737
    Par défaut
    Merci pour ta reponse. Pour le run time tu as raison. Sinon, pour le reste, j'ai bien dit que ce n'etait qu'une base, je vais bien evidement l'optimiser. En tous les cas, merci pour les pistes :-)

Discussions similaires

  1. [GUI] Gestion des messages d'erreurs
    Par agent007se dans le forum C++
    Réponses: 11
    Dernier message: 28/07/2006, 20h52
  2. gestion des messages d'erreurs
    Par keibenoit dans le forum Access
    Réponses: 2
    Dernier message: 31/05/2006, 14h49
  3. [debutant]gestion des messages des exceptions
    Par maxvador dans le forum Langage
    Réponses: 4
    Dernier message: 03/02/2006, 14h55
  4. Gestion des message windows dans les threads
    Par billyboy dans le forum Windows
    Réponses: 5
    Dernier message: 06/10/2003, 17h25

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