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 :

Ajouter une fenêtre en plus de la fenêtre principale d'un programme en win 32


Sujet :

Windows

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 16
    Points : 12
    Points
    12
    Par défaut Ajouter une fenêtre en plus de la fenêtre principale d'un programme en win 32
    Bonjour à tous.

    Je butte actuellement sur un problème. Je souhaite en fait ajouter une fenetre transparente avec CreateWindowEx( ) pour créer une OSD (On Screen Display) par dessus une vidéo.

    Bien que je fasse bien attention de passer le bon handle de fenetre dans chacune de mes fonctions , je rencontre un problème lorsque j'initialise mes fenetres avec le code ci-dessous.


    En effet, lorsque j'arrete et je remet en lecture la vidéo, la vidéo est affiché dans la fenetre osd et non plus hWnd.

    J'ai remarqué que cela se produisait seulement lorsque la fenetre osd était affiché en meme temps que hWnd.

    Pourriez vous me guider sur la méthode d'ajout d'une seconde fenetre dans mon programme en win32?

    Je vous en remercie d'avance.



    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {


    hInst = hInstance; // Stocke le handle d'instance dans la variable globale

    hWnd = CreateWindow(szWindowClass, szTitle, WS_POPUP,
    CW_USEDEFAULT, 0, largeur, hauteur, NULL, NULL, hInstance, NULL);


    osd = CreateWindowEx(
    WS_EX_TOPMOST | WS_EX_LAYERED
    | WS_EX_TRANSPARENT,
    szWindowClass,TEXT("On Screen Display IAM"),
    WS_POPUP,0,0,largeur/2,hauteur/2,hWnd,0,hInstance,0);
    // Choisir la couleur de fond (blanc) comme couleur transparente:
    SetLayeredWindowAttributes(osd, RGB(255,255,255), 0, LWA_COLORKEY);

    if (!hWnd)
    {
    return FALSE;
    }
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);



    return TRUE;
    }

  2. #2
    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 518
    Points
    41 518
    Par défaut
    Trop peu d'infos, mais déjà, il faut que tu nous dises:
    • Soit tu veux deux fenêtres de classes différentes,
    • Soit tu veux deux fenêtres de la même classe

    Sachant que pour un débutant, le second cas est plus compliqué, car toutes les variables statiques de la WindowProc (sans parler des globales, bien sûr) sont partagées entre les fenêtres, et c'est rarement ce qu'on veut.
    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.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Merci de ta réponse !
    Je vais être plus clair sur le but de mon application.

    La fenetre de menu ne sert qu'à afficher des données et donc à priori je ne m'en sert que pour dessiner et afficher des icônes et du texte à l'intérieur.

    La fenetre vidéo doit me permettre d'afficher la vidéo que je traite via les filtres de directshow.

    La fenetre de menu est une fenetre transparente superposé à la fenetre vidéo.
    Or, lorsque je change l'affichage sur la fenetre vidéo (redimensionnement de la vidéo par exemple), l'affichage de la vidéo ne se fait plus sur la fenetre vidéo mais sur la fenetre de menu.

    J'ai un peu de mal à cerner comment cela peut se faire car j'ai deux handles de fenetres différents.

    A priori, au vue de ta réponse il est plus simple de passer pas deux fenetres de classes différentes.

    Je ne sais pas si j'ai pu apporter plus d'informations sur le problème que je rencontre.

    C'est exactement ce que je veux faire car je pense qu'il faut gérer indépendemment l'actualisation des deux fenetres (notamment au niveau du WM_PAINT).
    Pourrais tu m'en dire un peu plus sur la première solution? Dois je créer une autre classe de fenetre avec toutes fonctions (Winmain , Winproc etc.) associé ?

    Merci d'avance.

  4. #4
    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 518
    Points
    41 518
    Par défaut
    Ben, c'est clair, pour deux fenêtres aussi différentes, il faut vraiment créer deux classes différentes. Même s'il n'y avait pas de conflits de partage.

    Mais pour ton problème DirectShow, je pense que c'est ça: Des données qui sont partagées entre les fenêtres alors qu'elles ne devraient pas l'être. En créant deux classes différentes, ça devrait régler une bonne partie du problème si tu n'utilise pas les variables globales de manière inconsidérée...

    Deux classes de fenêtre différentes, ça signifie:
    • Un seul WinMain().
    • Deux structures WNDCLASS ou WNDCLASSEX qui doivent avoir un szClassName différent.
    • Deux appels à RegisterClass() ou RegisterClassEx() (un pour chaque szClassName).
    • Deux WindowProcs différentes.
    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.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Salut,

    Merci pour l'info. J'ai tenté de faire ce que tu m'as conseillé, mais maintenant je n'arrive pas à afficher ma fenêtre de menu.

    Pourrais tu me dire ce qui ne vas pas dans le code? Ou aurais tu un exemple d'implémentation de deux fenêtres dans une application?

    Je te remercie beaucoup du temps que tu consacres à mon problème.

    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    //Déclarations des WndProcs
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK    WndProcOsd(HWND , UINT , WPARAM , LPARAM );
    
    // Enregistrement de deux structures WNDCLASSEX différentes
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
        WNDCLASSEX wcex;
    
        wcex.cbSize = sizeof(WNDCLASSEX);
    
        wcex.style            = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra        = 0;
        wcex.cbWndExtra        = 0;
        wcex.hInstance        = hInstance;
        wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_IAMV3));
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName    = MAKEINTRESOURCE(IDC_IAMV3);
        wcex.lpszClassName    = szWindowClass;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    
        return RegisterClassEx(&wcex);
    
        WNDCLASSEX wcosd;
    
        wcosd.cbSize = sizeof(WNDCLASSEX);
    
        wcosd.style            = CS_HREDRAW | CS_VREDRAW;
        wcosd.lpfnWndProc    = WndProcOsd;
        wcosd.cbClsExtra    = 0;
        wcosd.cbWndExtra    = 0;
        wcosd.hInstance        = hInstance;
        wcosd.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_IAMV3));
        wcosd.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcosd.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
        wcosd.lpszMenuName    = MAKEINTRESOURCE(IDC_IAMV3);
        wcosd.lpszClassName    = L"szWindowOsd";
        wcosd.hIconSm        = LoadIcon(wcosd.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    
        return RegisterClassEx(&wcosd);
    }
    
    // WndProc numéro 1
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        int wmId, wmEvent;
        PAINTSTRUCT ps;
        HDC hdc;
    
        HDC hdciam;
        PAINTSTRUCT psiam;
    
        switch (message)
        {
        case WM_COMMAND:
            wmId    = LOWORD(wParam);
            wmEvent = HIWORD(wParam);
            // Analyse les sélections de menu :
            switch (wmId)
            {
           
            case IDM_EXIT:
                DestroyWindow(osd);
                break;
            default:
                return DefWindowProc(osd, message, wParam, lParam);
            }
            break;
        case WM_PAINT:
            hdc = BeginPaint(osd, &ps);
           
            // TODO : ajoutez ici le code de dessin...
            EndPaint(osd, &ps);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(osd, message, wParam, lParam);
        }
        return 0;
    }
    
    
    // WndProc numéro 2
    LRESULT CALLBACK WndProcOsd(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        int wmId, wmEvent;
        PAINTSTRUCT ps;
        HDC hdc;
    
        HDC hdciam;
        PAINTSTRUCT psiam;
    
        switch (message)
        {
        case WM_COMMAND:
            wmId    = LOWORD(wParam);
            wmEvent = HIWORD(wParam);
            // Analyse les sélections de menu :
            switch (wmId)
            {
           
            case IDM_EXIT:
                DestroyWindow(osd);
                break;
            default:
                return DefWindowProc(osd, message, wParam, lParam);
            }
            break;
        case WM_PAINT:
            hdc = BeginPaint(osd, &ps);
           
            // TODO : ajoutez ici le code de dessin...
            EndPaint(osd, &ps);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(osd, message, wParam, lParam);
        }
        return 0;
    }

  6. #6
    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 518
    Points
    41 518
    Par défaut
    Salut,
    Déjà, ta fonction MyRegisterClass() aurait du te donner un warning "Unreachable code".

    Ensuite, je ne vois aucun CreateWindow() dans ton nouveau code.

    Mais j'ai vu d'autres erreurs pour les fenêtres: Les deux contiennent un appel à PostQuitMessage() dans le WM_DESTROY, je ne pense pas que ce soit ce que tu cherchais à faire.
    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.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Salut,

    C'est bon j'ai réussi à regler le problème grace à ton aide.

    Heu j'avais pas mis tout mon code en fait c'est pour ca que tu ne voyais pas de CreateWindow()

    Mais en fait je m'étais trompé sur la fonction winproc de ma deuxième fenetre et maintenant ca roule impec.

    Par contre je constate que la fenetre vidéo en arrière plan rame sévèrement. Saurais tu s'il est possible d'allouer un maximum de ressources à une fenetre en arrière plan??

    Merci encore pour ta précieuse aide.

  8. #8
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 352
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 352
    Points : 20 359
    Points
    20 359
    Par défaut
    Il faut basculer en plein écran pour les performances.
    Cela rame car l'OS doit redistribuer les messages systèmes entre les 2 fenêtres et scruter à un instant précis s'il doit agir en conséquence ( redessiner la fenêtre, entrées menus etc..)
    Une fenêtre=un processus donc une contrainte supplémentaire pour le système.
    En plus la vidéo demande énormément de ressources à chaque instant Direct Show doit décompresser un flux
    Citation Envoyé par djin94
    Par contre je constate que la fenetre vidéo en arrière plan rame sévèrement. Saurais tu s'il est possible d'allouer un maximum de ressources à une fenetre en arrière plan??
    Peut-être en créant un thread avec niveau de priorité maximal.
    A essayer..

  9. #9
    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 518
    Points
    41 518
    Par défaut
    Je dirais plutôt en baissant la priorité de tout autre thread du programme.
    Si tu montes la priorité d'un truc comme DirectShow, ton ordinateur ne va vraiment pas apprécier...
    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.

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

Discussions similaires

  1. [WD10] Ajouter à une combo sans fermer/ouvrir la fenêtre
    Par tpalloko dans le forum WinDev
    Réponses: 3
    Dernier message: 17/12/2012, 18h22
  2. [Débutant] Ajouter à une fenêtre une icone des ressources du projet
    Par Thomsy92 dans le forum Windows Presentation Foundation
    Réponses: 1
    Dernier message: 26/08/2009, 01h53
  3. Ajouter une fenêtre d'accueil à un projet existant
    Par SmileSoft dans le forum C++Builder
    Réponses: 9
    Dernier message: 05/09/2008, 01h26
  4. Ajouter une fenêtre au projet
    Par sab_info dans le forum C++Builder
    Réponses: 4
    Dernier message: 04/04/2008, 23h20
  5. Ajouter une barre d'outils à une sous fenêtre
    Par barthelv dans le forum MFC
    Réponses: 6
    Dernier message: 23/04/2004, 15h17

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