Pourquoi ne devriez-vous pas utiliser de handle lors de la création ou du streaming d'un composant ?

StackOverflow https://stackoverflow.com/questions/582721

Question

Je souhaite créer un contrôle VCL personnalisé qui enveloppe une surface de rendu SDL via la fonction SDL_CreateWindowFrom.SDL_CreateWindowFrom prend un handle HWND existant et y place un contexte de rendu hautes performances (il dispose de plusieurs backends disponibles, notamment DirectX et OpenGL).

Le HelpFile dit "Ne vous référez pas à la propriété Handle pendant la création de composants ou le streaming". Mais cela ne dit pas pourquoi.Il indique que la première fois que vous essayez d'accéder à la propriété Handle, il appellera HandleNeeded pour garantir qu'un handle valide existe.

J'ai donc deux questions.1:Quelle est la raison pour laquelle vous ne devriez pas référencer la propriété Handle lors de la création du composant ?2.Si le but du contrôle est d'envelopper une surface de rendu qui nécessite l'initialisation d'un HWND, quand est-il sûr d'effectuer l'initialisation qui (idéalement) devrait avoir lieu pendant la création/le streaming ?

Était-ce utile?

La solution

À la base, c’est une question de performance.Il existe potentiellement d’autres « mauvais » effets secondaires qui peuvent également survenir pendant le processus de streaming.Les choses sont en "mi-construction" et tout ce qui devrait normalement être là ne l'est probablement pas.

Lorsque vous référencez la propriété « Handle », cela lancera le processus de création de handle.En effet, la lecture de Handle appelle en fait GetHandle.Si vous le faites trop tôt dans le processus de streaming, vous risquez de vous retrouver avec, au mieux, des performances de streaming plus lentes, au pire, un « handle » partiellement configuré.

Si vous devez faire référence au handle correctement à partir d'un définisseur de propriétés, vous devez vérifier si le handle a été créé en vérifiant HandleAllocated, et alors seulement vous le référencez.Si vous deviez apporter des modifications à l'indicateur, comme appeler SetWindowLong() ou quelque chose du genre, vous devez alors "mettre en cache" cet état dans l'instance du composant, puis remplacer CreateWnd et appliquer ces paramètres à ce stade.Une autre option consiste à différer tous les accès aux handles pendant la diffusion (si csLoading dans ComponentState alors) jusqu'à ce que la méthode virtuelle Loaded soit appelée.

Enfin, vous devez être conscient des cas dans lesquels votre identifiant devra peut-être être recréé.Cela peut se produire si le formulaire environnant ou le handle du composant parent passe par un processus de recréation.Jusqu'aux versions plus récentes de Windows, la seule façon de modifier certains indicateurs de fenêtre consistait à détruire le handle et à le recréer avec de nouveaux indicateurs dans l'appel CreateWindowEx().De nombreux composants font encore cela.Vous savez si vous êtes dans une situation de recréation en vérifiant (csRecreating dans ControlState).

Donc, pour répondre directement à votre question, le meilleur endroit est de remplacer CreateWnd et d'y faire votre travail.CreateWnd ne sera appelé que lorsque le handle sera créé.Un composant correctement conçu ne devrait recevoir qu'un seul appel à CreateWnd juste avant d'être affiché.

Autres conseils

Pour répondre à votre deuxième question: En supposant que votre commande est TCustomControl vous devriez probablement passer outre CreateWindowHandle () . Ceci a l'avantage que toute initialisation est correctement répété chaque fois qu'une nouvelle poignée de fenêtre est créée pour le contrôle. Cela permet de changer certains indicateurs de style de fenêtre qui ne peut être activé ou désactivé sans recréer la fenêtre. Il ne permet également de conserver les ressources en libérant la poignée quand il est pas nécessaire, et le recréer plus tard.

Voir aussi cette question ce qui est-la-différence entre-CreateWnd et -createwindowhandle et plus encore les réponses détaillées sur ce qu'il faut faire et quand ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top