-
Fonction SetParent()
Bonjour à tous,
voici le soucis que je viens d'avoir en utilisant la fonction CWnd::SetParent()
J'ai deux fenêtres :
- La fenêtre A appelle la fenêtre B via un bouton
d'appel sur la fenêtre A.
- Chaque fenêtre contient des controles graphiques
(zone de saisie, libellé, groupe, etc.)
Ex du code :
CMyWindowA::DoDataExchange(...)
{
DDX_Control(pDX, IDF_WINA_1, m_winA_1);
DDX_Control(pDX, IDF_WINA_2, m_winA_2);
DDX_Control(pDX, IDF_WINA_3, m_winA_3);
...
}
CMyWindowB::DoDataExchange(...)
{
DDX_Control(pDX, IDF_WINB_1, m_winB_1);
DDX_Control(pDX, IDF_WINB_2, m_winB_2);
DDX_Control(pDX, IDF_WINB_3, m_winB_3);
...
}
Je voudrais déplacer, par programmation certains champs
de la fenêtre B vers la fenêtre A.
Méthode utilisée:
Lorsque j'ouvre ma fenêtre A, j'utilise la fonction SetParent(),
pour déplacer les champs de la fenêtre B vers la fenêtre A
Soit m_pWinA, le pointeur sur la fenêtre A
Soit m_pWinB, le pointeur sur la fenêtre B
j'ai donc le code suivant (grossièrement)
m_winB_1.SetParent(m_pWinA);
m_winB_2.SetParent(m_pWinA);
m_winB_3.SetParent(m_pWinA);
Ce code permet d'attribuer un nouveau parent aux controles, et de ce fait,
de les déplacer sur une autre fenêtre.
Ca marche super bien, MAIS voilà
Il semblerait que lorsque j'utilise cette fonction (SetParent()),
la tabulation soit inversée. (ce n'est pas une blague).
Est-ce que quelqu'un a déjà eu un cas pareil en utilisant cette fonction ??
Merci d'avance de vos réponse.
-
Tu veux parler de l'ordre de passage des composants par appui sur tab.
Ben le taborder est propre à chaque fenêtre...
-
Salut, et merci pour ta réponse.
En effet, il s'agit de l'appui sur la touche TAB. Mais je ne m'en suis pas aperçu comme ça.
En fait j'utilise la méthode GetNextDlgTabItem(), et c'est elle, qui d'aprés ce que je vois en debuggant, me retourne un pointeur sur le champ précédent, et ainsi de suite (j'ai essayé en mettant la fonction dans un while).
C'est donc comme ça que je me suis aperçu, que l'ordre de tabulation avait été inversé.
Je suis d'accord sur le fait que chaque fenêtre possède sa propre tabulation, mais je ne vois pas comment c'est géré.
Si tu veux, dans ma fonction OnInitialUpdate de CMyWindowA, j'ai une fonction d'initialisation, par type de controle graphique, qui initialise, tous les champs (fenêtre A ET fenêtre B).
Si par exemple sur cette fonction d'initialisation de chaque type de controle, je code un SetParent, mais sans changer de fenêtre (en fait je fait un SetParent(this)), l'ordre de tabulation est inversé. En clair, je ne change pas les controles graphiques de fenêtre (je les laisse là où je les ai dessinés), et manque de bol, la tabulation est encore inversée.
Je ne comprends pas.
Merci d'avance.
-
Essaye de voir comment évolue ce changement d'order en fonction de l'ordre dans lequel tu fais les SetParent.
Mais c'est un peu moyen comme procédé.
Ta classe CMyWindowA va donc avoir comme membre des contrôles affcihés dans CMyWindowB...
Pkoi ne pas dire à B de se créer le composant puis le détruire dans A ?
-
Non.
En fait :
- les controles graphiques de CMyWindowA sont gérés par des variables membres se touvant dans CMyWindowA
- les controles graphiques de CMyWindowB sont gérés par des varaibles membres se trouvant dans CMyWindowB
CMyWindowA::OnInitialUpdate()
{
// Création de la fenêtre CMyWindowB
.... le code me retourne un pointeur sur la fenêtre CMyWindowB
// Initialisation des champs de CMyWindowA
... appel des fonctions Init() de chaque controle graphique de A
ctrl_graphique_winA_1->Init();
... idem pour chaque controle graphique de A
// Initilisation des champs de CMyWindowB
... appel des fonctions Init() de chaque controle graphique de B
pointeur_WinB->ctrl_graphique_winB_1->Init()
... idem pour chaque controle graphique de B
}
CMyCtrlGraphique1::Init()
{
// Code
// Appel de la fonction SetParent()
}
Au final, je me retrouve avec l'ordre de tabulation inversé.
Merci.
-
Je sais pas te répondre pour SetParent.
Mais je trouve l'appel à cette fonction suspect.
Tu me confirme donc que après SetParent, CMyWindowA gère les fenètres qui se trouvent dans CMyWindowB ?
-
En fait, il s'agit d'un projet un peu particulier. Le but est de pouvoir déplacer des controles graphiques dans des fenêtres autres que celles où ces mêmes controles graphiques ont été dessinés.
J'ai géré l'ergonomie via une classe dérivé de CRectTracker.
Chaque fenêtre possède un objet de cette classe. Dans cette classe, il existe un tableau qui gère les CRectTracker de chaque controle graphique de la fenêtre
Le but de l'appli est donc de sélectionner un champ dans un fenêtre A et de la déplacer dans une fenêtre B ==> Opération de Drag&Drop.
(En fait, dans le tableau de la classe CRectTracker de la fenêtre A, on enlève 1 élément et dans le tableau de la classe CRectTracker de la fenêtre B, on ajoute 1 élément)
L'appli est assez complexe.
Et si tu veux, pour ne pas avoir à détruire le controle graphique de la fenêtre B et de le reconstruire dans la fenêtre A (ce qui aurait été super lourd à gérer), j'ai opté pour la solution d'utiliser la fonction SetParent. Cette méthode me permet d'indiquer à Windows que le controle graphique X ne se trouve plus dans la fenêtre A, mais dans la fenêtre B.
...
Je viens de trouver une solution à mon problème, tout en utilisant la fonction SetParent(). C'est un peu compilquer à expliquer, mais le but est de sauvegarder où se trouve le focus (GetWindow(GW_GW_CHILD)) avant d'appeler le mécanisme des SetParent(). De telle manière, qu'aprés les SetParent(), on sache où on était à l'origine...
Je te remercie énormément de m'avoir répondu aussi rapidement.
Merci.
A+