2010-12-03 62 views
2

Je développe un plug-in (en cours de traitement) pour l'application et, dans le cadre de mon plug-in, je souhaite remplacer les info-bulles de l'application par les miennes. Cependant, il n'y a pas d'API disponible pour moi, alors j'ai décidé d'aller bas niveau.Intercepter et masquer une fenêtre avant qu'elle n'apparaisse

Je connais la classe de fenêtre de la pointe d'outil, mais la question est: comment puis-je la détecter et comment la fermer ensuite?

Voici ce que je pensais faire jusqu'à présent:

  1. Créer un système à l'échelle crochet WM_CREATE
  2. Quand on est pris, vérifier la classe et le processus de la cible WM_CREATE
  3. vérifier est en effet la fenêtre, je me soucie de:
    • Si le processus est celui que mon plug-in est assis dans
    • Et si la classe est du type correct
    • Et si l'application correcte est mise au point (en cas de multiples applications)
  4. Envoyer un WM_DESTROY à la fenêtre créée et créer ma propre fenêtre à sa position à la place

Comment ça sonne? En supposant qu'il n'y a en effet pas d'API pour gérer les infobulles, y a-t-il un moyen plus simple pour ce dont j'ai besoin?

Merci!

P.S Tagged as C++/C# que je compte écrire dans ces 2 langues (C++ pour crochet système, C# pour tout le reste)

+1

infobulles sont souvent fait en créant et en gardant juste * une fenêtre d'info-bulle * par fenêtre parent de niveau supérieur. Cette fenêtre d'info-bulle est ensuite ajustée et affichée en cas de besoin et masquée lorsqu'elle ne l'est pas. Donc, vous auriez besoin de suivre quand la fenêtre est montrée, pas quand elle est créée, et vous ne voudriez évidemment pas la détruire (vous pourriez vous en sortir en la cachant). –

+0

@Leo: Merci pour le commentaire. C'est peut-être très vrai. – VitalyB

Répondre

2

Si vous connaissez le type de fenêtre que vous souhaitez bloquer, vous pouvez simplement le sous-classer et gérer la destruction dans votre propre fenêtre WndProc. Utilisez GetClassLongPtr() avec GCL_WNDPROC sur la classe infobulle, utilisez SetClassLongPtr() avec GCL_WNDPROC pour définir votre propre WndProc et l'ont appelé DestroyWindow() sur WM_CREATE et appeler l'ancien WndProc pour le reste ..

+0

Je suis confus ... GetClassLongPtr() nécessite un HWND, mais en cas de l'info-bulle, il n'a pas encore été créé. Êtes-vous en train de dire que je peux utiliser GetClassLongPtr()/SetClassLongPtr() pour sous-classer une fenêtre qui n'existe pas encore? – VitalyB

+0

Ouais, vous devez d'abord créer une fenêtre d'infobulle factice et l'utiliser. – kichik

+0

@kichik: Intéressant ... Et si je fais cela, toutes les instances futures d'une fenêtre de cette classe utiliseront ce MessagePump? – VitalyB

0

Cela ne fonctionnera pas. Considérez la vue de l'application que vous remplacez les info-bulles de et en supposant que vous pourriez le dire pour détruire les fenêtres. Que se passe-t-il lorsque l'application décide qu'elle doit fermer l'info-bulle? Il n'a pas le handle de votre nouvelle fenêtre, il a le handle de l'ancienne fenêtre, que vous avez détruit. Il est temps que les choses aillent mal.

Votre système de plug-in doit explicitement prendre en charge le remplacement des info-bulles si vous voulez que cela fonctionne correctement. Peut-être qu'une partie facultative de l'infrastructure de plugin pourrait être une fonction RequestTooltip. S'il n'existe pas, ou retourne null, ou quoi que ce soit, les info-bulles par défaut sont utilisées, sinon les plugins fournis sont utilisés.

+0

En ce qui concerne la première partie. C'est vrai, c'est plus complexe que ça - j'ai besoin de commencer à suivre la souris par moi-même pour cacher ma propre fenêtre. L'application d'origine ne sera pas en mesure de cacher l'info-bulle pour moi, cependant, je ne vois pas pourquoi cela devrait causer un problème.Par exemple, s'il y a un problème avec la destruction de la "vieille" info-bulle, je peux essayer de la cacher à la place, alors la destruction fonctionnerait bien (en fait, je peux même accrocher la vieille info-bulle pour cacher ma nouvelle). – VitalyB

+0

En ce qui concerne le second problème: je crains que l'application n'ait pas d'API qui interroge l'existence d'info-bulles, donc je ne peux simplement pas le faire = \ – VitalyB