OVH Cloud OVH Cloud

Problème de creation de contrôles WIN32 dans différents Threads

4 réponses
Avatar
liard
Mon problème est simple et complexe à la fois. Quant on utilise la
fonction WIN32 CreateWindow, l'objet créé est associé au thread ayant
exécuté l'appel à CreateWindow. Donc tout message associé sur ce
contrôle sera envoyé vers la file de messages de ce thread.

Or je tente de mettre en place une architecure multi-threads. J'ai une
classe C++ encapsulant le concept de fenêtre principale d'application.
Cette classe dérive de plus d'une classe de Thread que je prend en
charge. La fenêtre principale de mon application est donc créer dans
ce thread (nommons le TH2), via un appel à CreateWindow. Ce thread
démarre la pompe à message pour router les évènements vers une
procédure de fenêtre (Classique me direz vous).

Or après avoir invoqué le construction de la classe Window, le thread
principal de l'application (nommons le TH1) continu sont exécution est
abouti à vouloir créer un bouton CreateWindow("BUTTON", ....);

La fenêtre et le bouton sont donc associés à deux threads différents.
OR JE NE VEUX AVOIR QU'UNE UNIQUE POMPE A MESSAGE ASSOCIEE A TH2. Du
coup les messages générés, par exemple en cliquant sur le bouton, sont
envoyés sur la file de TH1. Il ne sont donc pas pris en compte. C'est
pire que tout, l'application se gèle et plante lamentablement.

Quelqu'un parmi vous arrait t'il une solution pour créer le bouton via
TH1, mais en l'associant à la file de messages de TH2. Ca fait trois
jours que je tests des solutions, mais sans véritable succès. Notez
bien, que si c'est TH2 qui execute l'appel à CreateWindow("BUTTON",
...), tout marche bien. Mais c'est pas ce que je veux.

Si vous avez la solution, félicitation.
Dominique

4 réponses

Avatar
Remi Thomas
Dominique wrote:
Mon problème est simple et complexe à la fois. Quant on utilise la
fonction WIN32 CreateWindow, l'objet créé est associé au thread ayant
exécuté l'appel à CreateWindow. Donc tout message associé sur ce
contrôle sera envoyé vers la file de messages de ce thread.

Or je tente de mettre en place une architecure multi-threads. J'ai une
classe C++ encapsulant le concept de fenêtre principale d'application.
Cette classe dérive de plus d'une classe de Thread que je prend en
charge. La fenêtre principale de mon application est donc créer dans
ce thread (nommons le TH2), via un appel à CreateWindow. Ce thread
démarre la pompe à message pour router les évènements vers une
procédure de fenêtre (Classique me direz vous).

Or après avoir invoqué le construction de la classe Window, le thread
principal de l'application (nommons le TH1) continu sont exécution est
abouti à vouloir créer un bouton CreateWindow("BUTTON", ....);

La fenêtre et le bouton sont donc associés à deux threads différents.
OR JE NE VEUX AVOIR QU'UNE UNIQUE POMPE A MESSAGE ASSOCIEE A TH2. Du
coup les messages générés, par exemple en cliquant sur le bouton, sont
envoyés sur la file de TH1. Il ne sont donc pas pris en compte. C'est
pire que tout, l'application se gèle et plante lamentablement.

Quelqu'un parmi vous arrait t'il une solution pour créer le bouton via
TH1, mais en l'associant à la file de messages de TH2. Ca fait trois
jours que je tests des solutions, mais sans véritable succès. Notez
bien, que si c'est TH2 qui execute l'appel à CreateWindow("BUTTON",
...), tout marche bien. Mais c'est pas ce que je veux.

Si vous avez la solution, félicitation.
Dominique



Tu dois mettre en place un protocole de communication entre les deux tread,
comme par exemple avec de simples message WM_USER.
Tu passes en argument les paramètres de l'objet que tu désires crée, ensuite
la création est faite directement pas le bon thread.

Rémi

--
Rémi Thomas - MVP Visual Studio .NET
Développeur Windows indépendant
http://www.xtware.com/cv
Avatar
patrox
Au risque de dire une enorme betise : AttachThreadInput ?

pat.


"Remi Thomas" a écrit dans le message de
news:3f5873b6$0$16183$
Dominique wrote:
> Mon problème est simple et complexe à la fois. Quant on utilise la
> fonction WIN32 CreateWindow, l'objet créé est associé au thread ayant
> exécuté l'appel à CreateWindow. Donc tout message associé sur ce
> contrôle sera envoyé vers la file de messages de ce thread.
>
> Or je tente de mettre en place une architecure multi-threads. J'ai une
> classe C++ encapsulant le concept de fenêtre principale d'application.
> Cette classe dérive de plus d'une classe de Thread que je prend en
> charge. La fenêtre principale de mon application est donc créer dans
> ce thread (nommons le TH2), via un appel à CreateWindow. Ce thread
> démarre la pompe à message pour router les évènements vers une
> procédure de fenêtre (Classique me direz vous).
>
> Or après avoir invoqué le construction de la classe Window, le thread
> principal de l'application (nommons le TH1) continu sont exécution est
> abouti à vouloir créer un bouton CreateWindow("BUTTON", ....);
>
> La fenêtre et le bouton sont donc associés à deux threads différents.
> OR JE NE VEUX AVOIR QU'UNE UNIQUE POMPE A MESSAGE ASSOCIEE A TH2. Du
> coup les messages générés, par exemple en cliquant sur le bouton, sont
> envoyés sur la file de TH1. Il ne sont donc pas pris en compte. C'est
> pire que tout, l'application se gèle et plante lamentablement.
>
> Quelqu'un parmi vous arrait t'il une solution pour créer le bouton via
> TH1, mais en l'associant à la file de messages de TH2. Ca fait trois
> jours que je tests des solutions, mais sans véritable succès. Notez
> bien, que si c'est TH2 qui execute l'appel à CreateWindow("BUTTON",
> ...), tout marche bien. Mais c'est pas ce que je veux.
>
> Si vous avez la solution, félicitation.
> Dominique

Tu dois mettre en place un protocole de communication entre les deux


tread,
comme par exemple avec de simples message WM_USER.
Tu passes en argument les paramètres de l'objet que tu désires crée,


ensuite
la création est faite directement pas le bon thread.

Rémi

--
Rémi Thomas - MVP Visual Studio .NET
Développeur Windows indépendant
http://www.xtware.com/cv




Avatar
Arnaud Debaene
Dominique wrote:
Mon problème est simple et complexe à la fois. Quant on utilise la
fonction WIN32 CreateWindow, l'objet créé est associé au thread ayant
exécuté l'appel à CreateWindow. Donc tout message associé sur ce
contrôle sera envoyé vers la file de messages de ce thread.

Or je tente de mettre en place une architecure multi-threads. J'ai une
classe C++ encapsulant le concept de fenêtre principale d'application.
Cette classe dérive de plus d'une classe de Thread que je prend en
charge. La fenêtre principale de mon application est donc créer dans
ce thread (nommons le TH2), via un appel à CreateWindow. Ce thread
démarre la pompe à message pour router les évènements vers une
procédure de fenêtre (Classique me direz vous).

Or après avoir invoqué le construction de la classe Window, le thread
principal de l'application (nommons le TH1) continu sont exécution est
abouti à vouloir créer un bouton CreateWindow("BUTTON", ....);


C'est une architectue assez inhabituelle : L'idiome standard est que le
thread principal de l'application créé l'IHM et fasse tourner la pompe à
messages, pendant que les autrs threads font le travail sans relation avec
l'IHM. Pourquoi as-tu besoin de faire différemment?

En fait, ce qui me semble bizarre, c'et cette classe qui est à la fois un
thread et une fenêtre : ca me semble un usage abusif de l'héritage. La règle
de base est : une classe, une responsabilité. Ca me semblerait plus juste
d'avoir une classe thread dont la fonction main créé un objet fenêtre
séparé.


Quelqu'un parmi vous arrait t'il une solution pour créer le bouton via
TH1, mais en l'associant à la file de messages de TH2. Ca fait trois
jours que je tests des solutions, mais sans véritable succès. Notez
bien, que si c'est TH2 qui execute l'appel à CreateWindow("BUTTON",
...), tout marche bien. Mais c'est pas ce que je veux.


Pourquoi? Je ne vois pas de raison à cela.
La seule solution est que ton thread qui n'as pas créé le fenêtre ne créé
pas directment le bouton, mais envoie à la place un message au thread d'IHM
(via PostMessage par exemple) pour lui demander de créer le bouton.

Arnaud
Avatar
liard
"patrox" wrote in message news:<3f58e4c5$0$20163$...
Au risque de dire une enorme betise : AttachThreadInput ?

pat.





Oui, ca m'a aussi semblé être une bonne solution, sauf que cela ne
marche que si les threads a attacher est un thread d'interface
graphique. Or le thread devant créer les contrôles peut être le thread
principal de l'application (du genre le main). Du coup, j'ai essayé
plein de tests, mais cela ne marche pas. Pour mieux comprendre le
problème, voici un exemple de code (en fait, je cherche à coder une
libriaire proche de celle de Java).

#include "Cpp/Windows/Frame.h"
#include "Cpp/Windows/Components/Button.h"

int main(void) {

try {
Frame *frmMain = new Frame("Essai");
Button *btnTest = new Button("Ceci est un test");
frmMain->addComponent(btnTest);

frmMain->setSize(300,200);
frmMain->setLocation((1024-300)/2, (768-200)/2);
frmMain->setVisible(true);

} catch(Exception *exception) {
cerr << exception << endl;
delete exception;
exit(-1);
}

while(true) {
if (kbhit()) break;
Thread::sleep(100);
}

return 0;
}

Pour que chaque fenêtre soit indépendante des autres, elles lance sont
propre thread. Or le main, lui continu son exécution et créé d'autres
composants.

Je veux bien tenté de poster un message pour informer la fenêtre
principale de créer ses contrôles constitutifs dans son thread, mais
la librairie risque d'être relativement riche et donc la tache très
ardue.

C'est pour cela que je cherche plutôt à réassocié un composant
graphique Win32 avec un autre threads (ce qui me simplifierait la
tâche d'une manière indiscutable).

En espérant que vous ayez une solution.
Dominique

PS : la libriaire ainsi développé sera téléchargeable (elle est déjà
partiellement) à partir de l'adresse http://www.infini-fr.com.