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

MFC Discussion :

Synchronisation dans la création des ressources MFC (problème)


Sujet :

MFC

Vue hybride

Gorgo13 Synchronisation dans la... 07/08/2014, 13h02
Médinoc l'"initialisation", tu la... 07/08/2014, 16h13
Gorgo13 Bonsoir et merci pour la... 08/08/2014, 00h10
Médinoc Je ne vois pas vraiment le... 08/08/2014, 01h47
Gorgo13 Oui merci, je vais changer ça... 08/08/2014, 09h57
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 157
    Par défaut Synchronisation dans la création des ressources MFC (problème)
    Bonjour,

    depuis que je suis passé sous VS2010 (c++), j'ai de gros problèmes de fiabilité concernant tout ce qui est ressources graphiques (contrôles, dialogues).

    En effet, dans mes applis récentes il arrive assez souvent que des contrôles s'initialisent mal (ce sont des contrôles "faits maison" à dérivés de CWnd).

    Ce que j'entends par "s'initialisent mal" c'est que l'initialisation a l'air de se faire avant que toutes les propriétés des dialogues soient mises à jour (taille, position, ce genre de chose). Donc comme je récupère par exemple les informations de taille et de position client (ou autre), si elles ne sont pas correctes, mes contrôles n'apparaissent tout simplement pas (car ils sont par exemple attachés à des "static" de dimension 0,0 ... enfin, c'est ce que j'avais pu comprendre en essayant de débugger, mais pas évident)

    Le problème est que ce comportement est plus ou moins aléatoire, d'où le titre de mon post faisant référence à la synchro de création de toutes ces ressources graphiques...

    Est-ce qu'il existerait un tuto ou une doc sur ce sujet précis? Ou bien est-ce que quelqu'un peut m'indiquer une méthodologie robuste à suivre?

    Merci d'avance. Gorgo13.

    [EDIT] PS: c'est un peu le même problème que mon précédent post "Création CDialog OK mais m_hWnd=NULL (VC++2010)" mais là il ne s'agit absolument pas d'un projet importé... il est tout neuf de VC2010.

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    l'"initialisation", tu la fais quand? Dans ton OnCreate?

    Aussi, toute ta GUI est bien dans le même thread, hein?
    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 confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 157
    Par défaut
    Bonsoir et merci pour la réponse.

    Citation Envoyé par Médinoc Voir le message
    l'"initialisation", tu la fais quand? Dans ton OnCreate?
    Par exemple dans mon projet de test, je crée une nouvelle instance de mon contrôle (un contrôle de graph pour faire des plots en tout genres basé sur un CWnd) dans OnInitDialog. Dans ce contrôle, je définis 2 plots (je passe les détails). De temps en temps, un des deux graphes n'apparaît tout simplement pas. Comme c'est un comportement aléatoire, ça me donne vraiment pas envie d'essayer de débugger, donc j'en sais pas plus.

    Voici comment je procède dans le OnInitialUpdate():
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void CDev_MultiCODEView::OnInitialUpdate()
    {
    	...
    	CRect tRect;
    	this->m_GraphContainer.GetClientRect(&tRect);
    	MyGraph->Create(tRect,&m_GraphContainer,this,1974L);
    	...
    }
    et le Create de MCODE_Graph est:

    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
    BOOL MCODE_Graph::Create(const CRect& FullRect,
    		CWnd* _pParentContainer, CWnd* _pTopMostParentWnd, mcINT32 nID,
    		mcINT32 SetProperties,
    		mcINT32 RemProperties)
    {
    	...
     
    	static CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,0,(HBRUSH)BkgBrush);
     
    	DWORD dwStyle = WS_CHILD | WS_VISIBLE;
     
    	int result = -999;
    	result = CWnd::CreateEx(WS_EX_TOPMOST,className, NULL, dwStyle, 
    		FullRect.left, FullRect.top, FullRect.Width(), FullRect.Height(),
    						pParentContainer->GetSafeHwnd(), (HMENU)nID);
     
    	Hdc_Screen = GetDC()->GetSafeHdc();
    	Hdc_Memory = CreateCompatibleDC(Hdc_Screen);
     
    	...
     
    	this->GetClientRect(&m_ClientRect);
    	hBitmapFullPlot = CreateCompatibleBitmap(Hdc_Screen,m_ClientRect.Width(),m_ClientRect.Height());
     
    	return TRUE;
    }
    Citation Envoyé par Médinoc Voir le message
    Aussi, toute ta GUI est bien dans le même thread, hein?
    Oui dans l'exemple ci-dessus, c'est le cas... non??

    Donc je comprends pas très bien ce qui se passe.

    Avec une autre classe que j'ai écrite (un panneau de propriété) je crée une fenêtre avec un tableau de propriétés et quelques boutons. Le tableau doit se redimensionner à chaque fois que WM_SIZE est intercepté. J'avais constaté que des fois à l'initialisation, la taille récupérée est 0,0 et donc mon tableau de propriétés et mes boutons n'apparaissent pas car ils ont une taille de 0 (puisque tout est calculé et redimensionné à partir de la taille de la fenêtre hôte). Il suffit que je redimensionne à la main ma fenêtre pour résoudre le problème... mais évidemment je voudrais que ce soit correct au démarrage!

    Je suis un peu paumé et il y a quelque chose que je ne comprends plus (sous VC6 j'avais pas ce genre de problème.. mais c'est vrai aussi que je m'amusais moins à créer des contrôles custom).

    Bon, je sais pas si c'est beaucoup plus clair...

    GT

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    Je ne vois pas vraiment le problème, mais le coup du HDC_Screen me paraît suspect. On n'est pas censer "mémoriser" un HDC vers l'écran, on est supposer faire un ReleaseDC() avant la fin du traitement du message...
    Surtout s'il ne te sert qu'à créer un Compatible DC.

    Si tel est le cas, tu devrais plutôt faire ceci:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	{
    		CDC *pdc_Screen = GetDC();
    		Hdc_Memory = CreateCompatibleDC(pdc_Screen->GetSafeHdc());
     		hBitmapFullPlot = CreateCompatibleBitmap(pdc_Screen->GetSafeHdc(), m_ClientRect.Width(), m_ClientRect.Height());
    		ReleaseDC(pdc_Screen);
    	}
    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 confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 157
    Par défaut
    Oui merci, je vais changer ça et voir si ça vient de là. Le Hdc_Screen je m'en sers plus tard pour effectivement copier le bitmap complet vers l'affichage.

    Il faut que je récupère le Hdc_Screen à chaque fois que je l'utilise et que je le libère juste après, c'est bien ça...?

    Par contre est-ce que c'est pas la même logique pour le Hdc_Memory? (quelle différence avec le Hdc_Screen sur le principe?)

    G13.

    [EDIT] je viens de commencer à changer effectivement les "screen HDC" permanents vers des HDC "locaux". Le problème est que mes "memory DC" doivent aussi être créés à chaque fois? (j'imagine que oui parce que là les graphes sont partiellement affichés, et d'autres de mes contrôles n'affichent plus rien, etc...)

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    Citation Envoyé par Gorgo13 Voir le message
    Il faut que je récupère le Hdc_Screen à chaque fois que je l'utilise et que je le libère juste après, c'est bien ça...?
    Oui.

    Par contre est-ce que c'est pas la même logique pour le Hdc_Memory? (quelle différence avec le Hdc_Screen sur le principe?)
    Les Memory DC sont créés et détruits plus où moins à volonté, alors que les Screen DC sont un pool limité. Un Screen DC "acquis" doit donc être "rendu" le plus tôt possible.

    Edit: Puisque tu utilises MFC, pense à utiliser la classe CClientDC: Une variable locale de ce type fera le GetDC() et le ReleaseDC() 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.

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

Discussions similaires

  1. liste sharepoint : disponibilité dans le temps des ressources
    Par ITParty dans le forum Développement Sharepoint
    Réponses: 5
    Dernier message: 28/05/2013, 14h43
  2. Réponses: 5
    Dernier message: 10/04/2010, 10h36
  3. [EJB3] Exception dans la création des beans de l'application
    Par aymen007 dans le forum Java EE
    Réponses: 2
    Dernier message: 19/01/2009, 20h47
  4. Réponses: 6
    Dernier message: 29/03/2008, 19h01

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