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 :

[Windows API] Créer une fenêtre "popup" sur clic menu


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Par défaut [Windows API] Créer une fenêtre "popup" sur clic menu
    Bonjour,

    J'ai réalisé une application (ou du moins posé les premières fondations) avec l'API Windows.

    Je souhaiterais créer une fenêtre "popu" qui s'afficherait après avoir cliqué sur un item du menu.

    Ci-dessous le pseudo code avec quelques détails sur les fonctions _child :

    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
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    int WINAPI wWinMain(...)
    {
    	MyInitCommonControls();
     
    	MyRegisterClass(hInst); // avec WindowProc
     
    	InitInstance(hInst, nCmdShow);
     
    	MessageLoop();
    }
     
    LRESULT CALLBACK WindowProc(...)
    {
    	switch (uMsg)
    	{
    		...
     
    		case WM_COMMAND:
    		{
    			witch (LOWORD(wParam))
    			{
    				...
     
    				CASE IDM_MENU_TEST:
    				{
    					MyRegisterClass_child(hInst); // avec WindowProc_child - j'ignore si je dois enregistrer toutes les classes dans wWinMain
     
    					InitInstance_child(hInst, nCmdShow); 
     
    					MessageLoop_child()
    				}
     
    				...
    			}
    		}
     
    		...
    	}
    }
     
    LRESULT CALLBACK WindowProc_child(...)
    {
    	switch (uMsg)
    	{
    		...
     
    	}
    }
     
    //-----------------------------------------------
     
     
    ATOM MyRegisterClass_child(hInst)
    {
    	WNDCLASSEX wcex = { };
    	wcex.cbSize = sizeof(WNDCLASSEX);
    	wcex.style = CS_HREDRAW | CS_VREDRAW; //CS_DBLCLKS; // CS_HREDRAW | CS_VREDRAW; // UNIT    style                                
    	wcex.lpfnWndProc = EditProc;   // WNDPROC
    	// int     cbClsExtra
    	// int     cbWndExtra
    	wcex.hInstance = hInst;      // HINSTANCE
    	wcex.hbrBackground = (HBRUSH)COLOR_BTNSHADOW; // HCURSOR hCursor
    	// HBRUSH  hbrBackground
    	// LPCSTR  lpzMenuName
    	wcex.lpszClassName = CHILD_WINDOW_CLASS; // LPCSTR
     
    	return RegisterClassEx(&wcex);
    }
     
    HWND InitInstance_child(hInst, nCmdShow)
    {
    	HWND hwnd_child = CreateWindowEx
    	(
    		NULL,
    		CHILD_WINDOW_CLASS,
    		L"Child window",
    		WS_SIZEBOX | WS_CLIPSIBLINGS,//WS_CHILD | WS_POPUP | WS_VISIBLE,
    		225, 65,
    		150, 24,
    		NULL,
    		NULL,
    		hInst,
    		NULL
    	);
     
    	return hwnd_child;
    }
    J'aimerais que la fenêtre soit modeless et complétement découplée de la fenêtre principale.

    Pouvez-vous me confirmer le pattern ci-dessous et m'aider à la corriger ?

    Merci par avance !

  2. #2
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2018
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 28
    Localisation : Autre

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

    Informations forums :
    Inscription : Novembre 2018
    Messages : 20
    Par défaut
    Pourquoi n'utilises-tu pas la macro DialogBox ?
    Le template de base de Visual Studio te donne un exemple presque complet de ce que tu veux, il suffit juste de supprimer la relation parent-enfant à la création du Dialog :
    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
     
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_COMMAND:
            {
                int wmId = LOWORD(wParam);
                // Parse the menu selections:
                switch (wmId)
                {
                case IDM_ABOUT:
    		DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), NULL, About);
    		break;
     
                default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
                }
            }
            break;
     
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
     
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
    }
     
    // Message handler for about box.
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
        UNREFERENCED_PARAMETER(lParam);
        switch (message)
        {
        case WM_INITDIALOG:
            return (INT_PTR)TRUE;
     
        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
            {
                EndDialog(hDlg, LOWORD(wParam));
                return (INT_PTR)TRUE;
            }
            break;
        }
        return (INT_PTR)FALSE;
    }

  3. #3
    Membre éclairé
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Par défaut
    J'étais justement tombé sur cet example dans la doc de Microsoft, même si je dois admettre ne pas encore eu la dévotion de tout lire...

    En fait, la fenêtre que je souhaite créer s'apparente davantage à un formulaire, bien qu'il me semble que cette notion de formulaire ne fait pas partie de l'API Windows.

    En fait, j'aimerais avoir une fenêtre avec divers zones de saisies, comboboxes, couleurs, voire éventuellement des graphiques. Visiblement, ça serait quand même possible (en tout cas, je ne souhaite pas encore introduire de framework tier). Je ne sais pas si tu as fait attention, mais le DialogBox est accompagné d'une ressource :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    IDD_ABOUT DIALOG DISCARDABLE  0, 0, 239, 66
    STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
    CAPTION "Account management software"
    FONT 8, "MS Sans Serif"
    BEGIN
    DEFPUSHBUTTON   "&OK", IDOK, 174, 18, 50, 14
    PUSHBUTTON      "&Cancel", IDCANCEL, 174, 35, 50, 14
    GROUPBOX        "Account management software", IDC_STATIC, 7, 7, 225, 52
    CTEXT           "Account management software.\r\n\r\nCopyright (c) 2019",
    IDC_STATIC, 16, 18, 144, 33
    END
    Ce qui me dérange, c'est qu'il n'y a pas de Message Loop avec le DialogBox, à moins tout ce passe avec celle dans le wWinMain ?

    En fait, j'avais réussi (j'entends par là que ça ne fonctionne de nouveau plus ) à créer une fenêtre "popup", mais j'avais évaluer l'instruction ShowWindow(hWndPopup, SW_SHOWNORMAL); qui donnait une valeur fausse, mais je viens de me rendre compte que cela ne signifie pas qu'il y avait une erreur, mais juste que la fenêtre n'était pas encore affichée... Il s'avère que la fenêtre en question n'avait pas les petits icônes en haut à droite et était de style diffèrent de la fenêtre principale.

  4. #4
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2018
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 28
    Localisation : Autre

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

    Informations forums :
    Inscription : Novembre 2018
    Messages : 20
    Par défaut
    Le handling des messages se fait dans la fonction de callback spécifié à l'appel.
    Ici, la fonction About :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), NULL, About);

    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
     
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
        UNREFERENCED_PARAMETER(lParam);
        switch (message)
        {
        case WM_INITDIALOG:
            return (INT_PTR)TRUE;
     
        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
            {
                EndDialog(hDlg, LOWORD(wParam));
                return (INT_PTR)TRUE;
            }
            break;
        }
        return (INT_PTR)FALSE;
    }
    Tu remarqueras le parallélisme avec IDOK (dans le fichier rc et dans la callback About) qui met fin à l'affichage du Dialog. Autrement, le programme boucle bien.


    J'attire aussi ton attention sur la macro DialogBoxParam qui te permet d'envoyer les paramètres dont tu pourrais avoir besoin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_ABOUTBOX), NULL, (DLGPROC)MyCallback, (LPARAM)0x12);

  5. #5
    Membre éclairé
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Par défaut
    Merci, j'avais lu comme quoi DialogBox est un cas particulier de CreateWindow(Ex).

    Bon, j'avais finalement quand même réussi à afficher une fenêtre "popup" via CreateWindowEx de style identique à la fenêtre principale avec les p'tits boutons en-haut à droite, sauf que la fenêtre restait modale (alors qu'elle est sensé déjà être modeless par défaut) et je n'ai pas encore réussi à tout intégrer comme les tooltips.

    J'imagine que ce n'est au final pas plus compliqué qu'une grosse boîte de Lego, mais il faut just que je "digère" un peu les infos et que je continue à me documenter .

  6. #6
    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
    Si tu veux une boîte de dialogue modeless plutôt que modale, il faut utiliser CreateDialog[Param]() plutôt que DialogBox[Param]().

    Pour moi, le seul cas qui peut être considéré "un cas particulier de CreateWindow[Ex]()", c'est le CreateDialog[Param] où le dialog box template inclut le nom d'une window class personnalisée (et pas basée sur la window class des boîtes de dialogue).
    J'ai déjà vu ça dans un code trouvé sur internet, ça se résumait à "CreateWindow() mais avec un dialog box template pour créer les contrôles à l'intérieur à moindre effort".
    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.

Discussions similaires

  1. créer une fenêtre popup
    Par justin_du_42 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 04/04/2009, 21h55
  2. [Débutant] Créer une fenêtre windows
    Par frizou11 dans le forum Visual C++
    Réponses: 7
    Dernier message: 13/02/2007, 16h47

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