2009-12-22 6 views
1

Je souhaite effectuer un traitement lors de l'ouverture d'une boîte de dialogue particulière, mais je ne trouve aucun moyen d'obtenir une notification lorsque cette boîte de dialogue est ouverte.Notification lorsque la boîte de dialogue Windows est ouverte

Est-il possible d'obtenir une notification dans l'application pour l'ouverture d'une boîte de dialogue Windows particulière?

Les seules informations disponibles sur la boîte de dialogue sont son titre et son unique.

+0

modale ou non? dans votre processus? pourquoi ne sauriez-vous pas que le dialogue s'ouvrait avant l'ouverture? –

+0

C'est un dialogue modal et pas dans mon processus. Je veux juste obtenir une notification après son ouverture. – anand

+0

Je suis sûr que vous connaissez également la classe de la fenêtre. Lancez Spy ++ pour vérifier, et voyez si c'est aussi unique. L'utilisation de la classe de fenêtre est probablement beaucoup plus robuste. – IInspectable

Répondre

2

La solution générale est d'utiliser des crochets Windows, de filtrer vers WH_CBT, de filtrer vers WM_CREATE, ou quelque chose comme ça, obtenir le texte de la fenêtre et voir si c'est celui qui vous intéresse.

Un autre point important: dans hook vous devez utiliser SetWindowLongPtr() pour définir le processus de la fenêtre sur votre propre fonction, qui recevra en réalité l'événement WM_CREATE. Dans tous les appels, cette fonction devrait appeler la procédure de fenêtre d'origine.

+0

-1, WH_CALLWINDOWPROC est une mauvaise solution pour ce problème. Vous devriez écouter fondamentalement le système de message de CHAQUE fenêtre puisque vos seuls choix sont les crochets locaux (qui ne fonctionneront pas ici) ou les globaux. Vous pourriez aussi bien créer un fil et SPIN sur FindWindow il serait moins cher que d'écouter tous les systèmes de messagerie. –

+0

oui. Je suis désolé, ce n'est certainement pas WH_CALLWNDPROC. WH_CBT est ce que je voulais dire. – ironic

0

EDIT: Désolé n'a pas remarqué que vous n'avez pas le code vous-même, mais seulement le titre. Je pense donc que les autres postes solution est ce que vous avez besoin

La gestion des événements dans les applications win32 se fait via une procédure de fenêtres dite qui est une fonction de rappel avec la signature suivante:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 

Ce rappel est appelé par Windows chaque fois qu'il y a un message pour les fenêtres qui sont enregistrées avec cette fonction de rappel. L'un des premiers messages envoyés à une nouvelle fenêtre est le message WM_CREATE.

Si vous créez vos fenêtres «à la main» avec l'API win32, il devrait y avoir une fonction de rappel statique comme celle ci-dessous où vous pouvez filtrer le message WM_CREATE.

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch(message) 
    { 
    case WM_CREATE: 
     // do what ever you want 
     return 0; 

    case default: 
     return DefWndProc(hwnd, message, wParam, lParam); 

    } 
} 

Si vous utilisez des boîtes de dialogue MFC (CDialog), vous pouvez remplacer la fonction CDialog::OnInitDialog().

0

OK, la façon de faire est d'utiliser SetWindowsHookEx(WH_SYSMSGFILTER,...) Vous obtiendrez beaucoup plus de rappels que vous n'en avez vraiment besoin. et crochets globaux sont une véritable ponction sur les performances du système (ils peuvent forcer le système à sérialiser des choses qui normalement fonctionner indépendamment)

Assurez-vous de lire les remarques, en particulier cette partie:

SetWindowsHookEx peut être utilisé pour injecter une DLL dans un autre processus. Une DLL 32 bits ne peut pas être injectée dans un processus 64 bits et une DLL 64 bits ne peut pas être injectée dans un processus 32 bits. Si une application nécessite l'utilisation de hooks dans d'autres processus, une application 32 bits doit appeler SetWindowsHookEx pour injecter une DLL 32 bits dans les processus 32 bits et un appel d'application 64 bits SetWindowsHookEx pour injecter un 64 bits DLL dans les processus 64 bits. Les DLL 32 bits et 64 bits doivent avoir des noms différents.

Votre crochet doit vivre dans une dll et la dll finira chargé dans l'espace d'adressage d'un autre processus, de sorte que vous ne serez pas il ne sera pas avoir accès à l'espace d'adresses de votre procees, vous devrez mettre en place une sorte de communication interprocessus entre votre hook et votre application. Dans l'ensemble, je dirais que c'est une très mauvaise idée.

1

Vous pouvez également utiliser un CBT Hook pour voir les messages de création de fenêtre. Vous aurez accès au CREATSTRUCT utilisé pour créer la fenêtre actuelle, par exemple, le titre et le nom de la classe. Vous pouvez empêcher la fenêtre d'être créé dans votre crochet, modifier la taille, etc.

+0

cela ne fonctionne que si le titre de la fenêtre est défini lors de la création de la fenêtre. Ce qui est assez improbable. –

+0

Cela dépend de ce qu'il cherche. Il y a plus de façons d'identifier une fenêtre que le titre, disons, par ID, nom de classe et parent, etc ... –

Questions connexes