2009-05-15 5 views
0

Lors de la création d'une classe de fenêtre pour une utilisation avec un DialogBox vous devez ajouter à DLGWINDOWEXTRA cbWndExtra. Si vous ajoutez un espace de données supplémentaire à une classe DialogBox accessible par GetWindowLongPtr, devriez-vous ajouter DLGWINDOWEXTRA pour accéder à cet espace supplémentaire?Si vous ajoutez un espace de données supplémentaire à une classe DialogBox accessible par GetWindowLongPtr, devez-vous ajouter DLGWINDOWEXTRA pour accéder à cet espace supplémentaire?

(je vous avoue que je pense que je connais la réponse, et de cette façon le code ne se casse pas. Mais, je veux vous assurer que mes raisons concordent avec la sagesse collective.)

La principale raison pourquoi les dialogues sont utilisés avec leur propre classe (plutôt que par défaut) est de permettre à chaque classe de dialogue d'avoir sa propre icône. Deux éléments séparés de données supplémentaires sont également attachés à chaque fenêtre.

...  
wndclass.cbWndExtra = DLGWINDOWEXTRA+EXTRASPACE; 
wndclass.lpfnWndProc = (WNDPROC) DefDlgProc; 
wndclass.hIcon = LoadIcon(hInstance, "ICON_MAIN"); 
wndclass.lpszClassName = WND_CLASS_VLIST_POPUP; 
wndclass.hIconSm = LoadImage(hInstance, 
           "ICON_MAIN", 
           IMAGE_ICON, 
           16, 
           16, 
           LR_DEFAULTCOLOR); 
... 

modifier tardif (supprimé le GWLP_USERDATA incorrect et remplacé par 0):

la question est effectivly:

GetWindowLongPtr(hWnd, 0 + DLGWINDOWEXTRA + SOMETHING_IN_EXTRASPACE); 

ou

GetWindowLongPtr(hWnd, 0 + SOMETHING_IN_EXTRASPACE); 

?

+0

Apparemment, cette question est considérée subjective par le bot d'aide? Je parie que c'est l'expression "compte avec la sagesse collective". –

+0

Helper bot n'est pas si intelligent. :) C'est le "vous" dans le sujet ... Le bot pense que vous faites référence à moi à la place de vous-même. – Shog9

+0

La prochaine fois, je vais utiliser la voix passive! –

Répondre

2

En fait ... Je pense que tu fais une erreur. La valeur à GWLP_USERDATA et l'espace alloué selon cbWndExtra sont deux choses distinctes ...

La valeur GWLP_USERDATA fait partie de l'espace Windows alloue pour chaque fenêtre. Il est si courant que les classes de fenêtres aient besoin d'un espace de stockage de la taille d'un pointeur que Windows inclut dans le coût de base d'une fenêtre, avec tous les autres «mots de fenêtre» prédéfinis. Regardez la documentation pour le paramètre nIndex-GetWindowLongPtr():

Indique le décalage de base zéro à la valeur à récupérer. Les valeurs valides sont comprises entre zéro et le nombre d'octets de mémoire de fenêtre supplémentaire, moins la taille d'un entier.

Ainsi, GetWindowLongPtr(hWnd, 0) récupère les premiers sizeof(LONG_PTR) octets alloués en réponse à cbWndExtra, GetWindowLongPtr(hWnd, sizeof(LONG_PTR)) vous donne les prochaines données de taille du pointeur, et ainsi de suite. Comme son nom l'indique, nIndex agit comme un index dans un tableau d'octets (bien qu'il renvoie toujours une valeur de taille pointeur). Maintenant, jetez un oeil aux valeurs d'index assignées aux constantes de données de fenêtre prédéfinies: elles sont toutes négatives, y compris GWLP_USERDATA! En effet, GetWindowLongPtr() commence à indexer au milieu des données de la fenêtre, avec les données communes à toutes les fenêtres résidant "avant" l'index 0, et toutes les données spécifiques à la classe de fenêtre résidant après.

Les fenêtres de dialogue sont construites au-dessus du support de base prévues pour les fenêtres normales. Comme ils nécessitent plus de données que les fenêtres normales, vous devez spécifier au moins DLGWINDOWEXTRA octets dans cbWndExtra. Comme toutes les autres données, il est accessible via une valeur positive passée à GetWindowLongPtr().

Par conséquent, lorsque vous demandez

GetWindowLongPtr(hWnd, GWLP_USERDATA + DLGWINDOWEXTRA + 0); 

...vous obtenez réellement les données à l'index -21 + 30 + 0 = 9: une valeur quelque part dans les propres données du gestionnaire de dialogue. Pas ce que tu veux!

A présent, vous devez vous rendre compte que lors de l'accès aux données allouées via cbWndExtra = DLGWINDOWEXTRA + extra vous avez seulement besoin de compenser votre demande par DLGWINDOWEXTRA. Donc:

GetWindowLongPtr(hWnd, DLGWINDOWEXTRA + 0); 

... vous obtiendrez le premier élément de données supplémentaires. GWLP_USERDATA doit être utilisé seulement lorsque vous souhaitez obtenir ou définir le pointeur unique des données utilisateur toujours allouées associées à chaque fenêtre.

+0

Pour une raison quelconque, je m'étais convaincu que GWLP_USERDATA était 0 (pas -21), même si je savais que les autres valeurs étaient négatives. J'ai besoin de relire ceci et de le penser à travers un peu plus. –

+0

J'ai corrigé la question, et mon code (le code qui ne s'est pas crashé) a définitivement utilisé '0' et non GWLP_USERDATA. Je ne suis pas tout à fait sûr d'où je viens, probablement en lisant la documentation MSDN en écrivant la question. Et avec la question maintenant corrigée le premier résultat est celui qui a réellement fonctionné (en accord avec ce que vous dites). Je pensais que j'avais une mauvaise odeur de code. Heureux que j'avais vraiment une mauvaise odeur de question. –

+0

Ah, beaucoup mieux :-) – Shog9

Questions connexes