Question

Lors de l'utilisation System.Windows.Forms.ShowDialog(IWin32Window), dois-je être en mesure de passer dans un IWin32Window représentant une poignée de fenêtre et ont-il modal par rapport à cette fenêtre?

Dans le cadre d'un Internet Explorer 7 l'extension, je suis en train d'ouvrir une fenêtre modale par rapport à un onglet Internet Explorer. Ce n'est pas l'onglet sélectionné, mais je peux obtenir le HWND de l'onglet OK. Cependant, quand je passe à ce showDialog mon formulaire est affiché, mais il est pas modal par rapport à quoi que ce soit: je peux encore faire des choses dans Internet Explorer, y compris dans l'onglet qui est censé être le propriétaire. Ma forme est montrée flottant au-dessus des fenêtres Internet Explorer et il reste sur le dessus, il est pas comme il vient d'ouvrir comme une forme normale, mais ce n'est pas correctement modal.

Utilisation Spy ++ , Je peux trouver ma forme et il est propriétaire de la poignée est correctement réglée.

Est-ce que cela signifie que quelque chose a mal tourné, ou je fais quelque chose de mal? Comment puis-je faire mon formulaire modal correctement?

Pour votre information, j'utilise cette classe d'emballage pour créer un IWin32Window à partir d'un hwnd (merci Ryan ):

/// <summary>
/// Wrapper class so that we can return an IWin32Window given a hwnd
/// </summary>
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
    public WindowWrapper(IntPtr handle)
    {
        _hwnd = handle;
    }

    public IntPtr Handle
    {
        get { return _hwnd; }
    }

    private IntPtr _hwnd;
}

MISE À JOUR: Utilisation d'Internet Explorer 7 et .NET 2.0

MISE À JOUR: Jouer dans un peu plus avec Spy ++ et les poignées il expose, je trouve que si j'utilise un autre hwnd alors je peux faire mon modal fenêtre à l'onglet:

J'utilisais la hwnd de l'onglet comme suggéré par le IWebBrowser2.HWND doc , qui Spy ++ apparaît comme TabWindowClass de classe. Il a un enfant de classe Shell DocObject View, qui a un enfant de Internet_Explorer_Server. Si j'utilise le hwnd du Internet Explorer_Server il fonctionne correctement, par exemple, lorsque je clique avec la souris sur d'autres onglets, Internet Explorer réagit normalement. Lorsque je clique avec la souris sur l'onglet d'intérêt, il joue les fenêtres d'un son oh et ne fait rien.

Je ne sais pas encore comment obtenir le programatically hwnd de Internet_Explorer_Server, mais il devrait être possible.

En outre, pour ce que ça vaut, tout en jouant avec d'autres poignées de fenêtre, je suis généralement en mesure de faire mon formulaire modal à d'autres applications et boîtes de dialogue. Donc je suppose que la réponse à ma question est « beaucoup mais pas toutes les poignées » ... peut-être que cela dépend de l'application?

MISE À JOUR: Un autre côté note: La raison initiale que je voulais faire mon formulaire modal à l'onglet au lieu de la fenêtre entière est que l'ouverture d'un MessageBox de ma forme, en passant la forme en tant que propriétaire, le MessageBox ne serait pas toujours ouverte au-dessus de ma forme. Si un nouveau Internet Explorer onglet venait d'être ouverte mais n'a pas été actif alors le MessageBox serait caché et que l'onglet se met à clignoter. Cependant, depuis Internet Explorer a été désactivé avec ma forme ouverte modal, il était impossible de passer à cet onglet, si Internet Explorer serait gelé. Je pensais que l'ouverture de mon formulaire modal à l'onglet résoudrait, mais je l'ai trouvé une autre solution est d'éviter d'utiliser MessageBox: si j'utilise une deuxième forme et ShowDialog(this) de ma première forme, puis la deuxième forme s'ouvre correctement à l'avant. Il semble donc que Form.ShowDialog() fonctionne mieux que MessageBox.Show() dans certains cas. Discussion plus problèmes avec les boîtes de dialogue modales et MessageBoxes .

Était-ce utile?

La solution

Votre code est correct. Le problème que vous utilisez probablement en est que si IE a un modèle de thread en rapport avec ses onglets. Je ne connais pas les détails exacts, mais la version courte est que chaque boîte onglet et est en cours d'exécution probable sur un thread différent que les autres onglets.

La Modal'ness d'une boîte de dialogue est spécifique au fil où la boîte de dialogue est en cours d'exécution. L'interface utilisateur sur d'autres sujets ne sera pas affecté par une boîte de dialogue de modèle sur un autre thread. Il est tout à fait possible que vous êtes en mesure d'accéder aux onglets qui sont en cours d'exécution sur un thread différent pour cette raison.

Autres conseils

ShowDialog () fait deux choses importantes. Il commence à pomper une boucle de message de sorte qu'il agit au code modalement appelant. Et il désactive toutes les autres fenêtres dans l'application avec un appel API EnableWindow (false). Ce dernier est ce qui ne se produit pas dans votre cas. Pas tout à fait surprenant, étant donné que la fenêtre qui doit être désactivée est pas une fenêtre WF.

Vous devrez peut-être appeler EnableWindow () vous-même. Assurez-vous de réactiver avant la boîte de dialogue se ferme ou Windows aller à la chasse pour la fenêtre d'une autre application pour donner le focus à.

Voici une version plus concise de Ryan / Rory Code de WindowWrapper:

internal class WindowWrapper : IWin32Window
{
    public IntPtr Handle { get; private set; }
    public WindowWrapper(IntPtr hwnd) { Handle = hwnd; }
}

Je ne l'ai jamais essayé d'une extension IE, mais j'ai le pressentiment que IE ne peut pas « respecter » une fenêtre modale style Win32 de la même façon, il fait une fenêtre modale élevée de Javascript en utilisant window.open().

Avez-vous testé ce code contre autre chose que IE, juste pour confirmer qu'il fonctionne comme il le devrait pour d'autres applications?

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