bonjour
est ce possible d'encapsuler un WndMainProc, cest a dire avoir un truc du genre :
LRESULT CALLBACK MyClass::WndMainProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
?
merci
Version imprimable
bonjour
est ce possible d'encapsuler un WndMainProc, cest a dire avoir un truc du genre :
LRESULT CALLBACK MyClass::WndMainProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
?
merci
Si elle est statique ça ne pose aucun problème.
Après si tu as une classe qui représente une fenêtre, et que tu veux une technique pour dispatcher les messages vers une fonction membre spécifique de la bonne instance, il y a aussi moyen (avec un peu de bidouille).
ok
effectivement, j'ai une classe qui représente une fenetre et mon pb est que si "LRESULT CALLBACK MyClass::WndMainProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ,
est static alors elle ne peut pas accéder aux membres non static (et privé) de MyClass
cest là quentre en jeu une bidouille mais je ne vois pas laquelle
merci
Tu passes un pointeur vers ton instance (this) en tant que dernier paramètre de Createwindow, afin de la récupérer plus tard.
Ensuite il faut intercepter l'évènement WM_CREATE, récupérer l'instance de la fenêtre et l'associer au HWND d'une manière ou d'une autre. Une méthode couramment utilisée est de la stocker dans les user data :
Ensuite lorsque tu interceptes un message dans ta callback globale, tu le dispatches à l'instance de cette manière :Code:
1
2
3
4
5
6 if (Message == WM_CREATE) { long This = reinterpret_cast<long>(reinterpret_cast<CREATESTRUCT*>(LParam)->lpCreateParams); SetWindowLongPtr(Handle, GWLP_USERDATA, This); }
Il y a aussi une méthode qui consiste à associer le HWND et l'instance dans une table globale juste après CreateWindow, mais avec ça tu perds tous les messages qui interviennent entre WM_CREATE et la fin de l'appel à CreateWindow.Code:
1
2
3 MyClass* Window = reinterpret_cast<MyClass*>(GetWindowLongPtr(Handle, GWLP_USERDATA)); Window->OnMessage(Message, Lparam, Wparam);
super merci, je vais essayer
ca donne qqch comme ca ?:
Code:
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 LRESULT CALLBACK WCapturer::WndMainProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_CREATE) { long This = reinterpret_cast<long>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams); SetWindowLongPtr(hwnd, GWLP_USERDATA, This); } else { WCapturer* wcapturer = reinterpret_cast<WCapturer*>(GetWindowLongPtr(hwnd, GWLP_USERDATA)); switch (message) { case WM_SIZE: wcapturer->ResizeVideoWindow(); break; case WM_CLOSE: wcapturer->hideWindow() ; break; case WM_DESTROY: PostQuitMessage(0); return 0; } } return DefWindowProc (hwnd , message, wParam, lParam); }
Ca a l'air, oui. Reste plus qu'à vérifier que ça fonctionne bien ;)
Bon alors ya un souci, il rentre dabord dans la second block (donc plante puisque que this pas encore mis dans les data user) et ne passe pas dans la premier block
(jen suis sur, jai utiliser le débugueur de vs2005 pour ca)
une idée ?
je vais essayer de voir ce que vaut le premier message exactement
ok erf, il y a des messages avant le message CREATE (je suppose), donc jai modifié comme suit et c'est bon:
Code:
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 LRESULT CALLBACK WCapturer::WndMainProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static bool isCreated = false ; if (message == WM_CREATE) { long This = reinterpret_cast<long>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams); SetWindowLongPtr(hwnd, GWLP_USERDATA, This); isCreated = true ; } else if (isCreated) { WCapturer* wcapturer = reinterpret_cast<WCapturer*>(GetWindowLongPtr(hwnd, GWLP_USERDATA)); switch (message) { case WM_SIZE: wcapturer->ResizeVideoWindow(); break; case WM_CLOSE: wcapturer->hideWindow() ; break; case WM_DESTROY: PostQuitMessage(0); return 0; } } return DefWindowProc (hwnd , message, wParam, lParam); }
Effectivement il y a quelques messages avant WM_CREATE (qu'il est impossible de dispatcher à l'instance dans ton cas).
La feinte du booléen ne fonctionnera que pour la première fenêtre. Une meilleure méthode est simplement de tester le pointeur wcapturer (il sera nul tant que tu n'auras pas intercepté WM_CREATE).
ok merci bcp, comme j'instancie qune fenetre, jai pas vu le pb venir (la mauvaise rustine koi)
et bien merci pour toute ton aide, c'est un peu plus cair dans ma tete maintenant
hum non en fait, le WCapturer est deja instancié à ce moment la, cest ca le pb.
Le WCapturer ne représente pas vraiment une feneter, cest juste lui qui la crée et la gère.
la finte me suffira pour lutilisation que jen fait.
encore merci
N'hésite pas à cliquer sur :resolu: si tout est ok ;)
ah oui cest vrai
Oups je n'avais pas vu ton dernier message.
Il est déjà instancié, mais tu ne l'as pas placé dans les user data de la fenêtre. D'ailleurs ça plante bien parce que tu récupères un wcapturer qui vaut NULL, non ?Citation:
hum non en fait, le WCapturer est deja instancié à ce moment la, cest ca le pb.
Le WCapturer ne représente pas vraiment une feneter, cest juste lui qui la crée et la gère.
la finte me suffira pour lutilisation que jen fait.
oui le serpent se mort la queue là
Pas vraiment non.Citation:
Envoyé par jhonnyBravo
quel problème est-ce que cela te pose ?
bah effectivement je peux creer qune fenetre mais comme jen veux qune, et que je développe une API vraiment de test, je changerai plus tard si besoin
merci
Je parlais de l'autre solution, qui permet de créer plusieurs fenêtres. C'est ce que j'utilise toujours et je n'ai jamais eu de problème.
Au fait: Utiliser des LONG_PTR et non des long pour les appels à SetWindowLongPtr().