Domanda

Quando si utilizza System.Windows.Forms.ShowDialog(IWin32Window), dovrei essere in grado di passare in un IWin32Window che rappresenta qualsiasi maniglia della finestra e l'abbiano in essere modale rispetto a quella finestra?

Nell'ambito di un'estensione di Internet Explorer 7 che sto cercando di aprire una finestra modale rispetto ad uno scheda Internet Explorer. Non è la scheda attualmente selezionata, ma posso ottenere il hwnd della scheda OK. Tuttavia, quando mi passa questo per showDialog mia forma è mostrato, ma non è modale rispetto a qualsiasi cosa: posso ancora fare le cose in Internet Explorer, inclusi nella scheda che dovrebbe essere il proprietario. La mia forma è mostrato galleggiante sopra le finestre di Internet Explorer e rimane in cima, quindi non è come è appena aperto come una forma normale, ma non è correttamente modale.

Spy ++ , posso trovare la mia forma ed è maniglia proprietario è impostato correttamente.

Questo significa che qualcosa è andato storto, o sto facendo qualcosa di sbagliato? Come faccio a fare il mio modulo correttamente modale?

Cordiali saluti, sto usando questa classe wrapper per creare un IWin32Window da un hwnd (grazie 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;
}

UPDATE: Utilizzo di Internet Explorer 7 e .NET 2.0

UPDATE: Giocando in giro un po 'di più con Spy ++ e le maniglie si espone, trovo che se io uso un hwnd diversa allora posso fare la mia finestra modale alla scheda:

Stavo usando hwnd della scheda, come suggerito dal IWebBrowser2.HWND doc , che a sua Spy appare ++ come classe TabWindowClass. Ha un figlio di classe Shell DocObject View, che ha un figlio di Internet_Explorer_Server. Se uso il hwnd del Internet Explorer_Server allora funziona correttamente, per esempio, quando si fa clic con il mouse su altre schede, Internet Explorer reagisce normalmente. Quando clicco con il mouse sulla scheda di interesse, si svolge il finestre d'oh suono e non fa nulla.

Non so ancora come ottenere programatically il hwnd Internet_Explorer_Server, ma dovrebbe essere possibile.

Inoltre, per quel che vale, mentre gioca con altra finestra maniglie sono stato generalmente in grado di fare il mio modulo modale verso altre applicazioni e finestre di dialogo. Quindi credo che la risposta alla mia domanda è 'molti ma non tutti gli handle' ... forse dipende l'applicazione?

UPDATE: Un altro lato-nota: Il motivo originale che volevo fare il mio modulo modale alla scheda, invece di tutta la finestra è che quando si apre un MessageBox dalla mia forma, passando il modulo come proprietario, il MessageBox non sarebbe sempre aperta in cima alla mia forma. Se una nuova scheda di Internet Explorer era stato appena aperto, ma non era attiva allora la MessageBox sarebbe nascosto e che sarebbe scheda inizia a lampeggiare. Tuttavia, dal momento che Internet Explorer è stato disattivato con la mia forma aperta modale non è stato possibile passare a quella scheda, quindi Internet Explorer sarebbe congelato. Ho pensato che aprire il mio modulo modale alla scheda risolverebbe questo, ma ho trovato un'altra soluzione è evitare di utilizzare MessageBox: se uso una seconda forma e ShowDialog(this) dalla mia prima forma poi il secondo modulo si apre correttamente verso la parte anteriore. Così sembra che Form.ShowDialog() funziona meglio di MessageBox.Show() in alcuni casi. Più discussione in problemi con le finestre di dialogo modali e messageboxes .

È stato utile?

Soluzione

Il codice è corretto. Il problema è probabile che in esecuzione in se è che IE ha un modello di threading legati alle sue schede. Non conosco i dettagli esatti, ma la versione breve è che ogni scheda può e probabilmente è in esecuzione su un thread diverso rispetto alle altre schede.

Il Modal'ness di una finestra di dialogo è specifica per il thread in cui la finestra di dialogo è in esecuzione. Interfaccia utente su altri thread sarà influenzato da una finestra di modello su un altro thread. E 'del tutto possibile si è in grado di accedere a schede che sono in esecuzione su un thread diverso per questo motivo.

Altri suggerimenti

ShowDialog () fa due cose importanti. Si inizia a pompare un ciclo di messaggi in modo agisce modale al codice chiamante. E si disattiva tutte le altre finestre nell'applicazione con un EnableWindow (false) chiamata API. Quest'ultimo è ciò che non sta accadendo nel vostro caso. Non del tutto sorprendente, considerando che la finestra che deve essere disabilitato non è una finestra WF.

Potrebbe essere necessario chiamare EnableWindow () da soli. Assicurati di riattivarlo in prima che la finestra di dialogo si chiude o Windows andrà a caccia di finestra di un'altra applicazione per dare la messa a fuoco.

Ecco una versione più concisa di Ryan / code WindowWrapper di Rory:

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

Non ho mai provato questo da un interno di IE, ma ho la sensazione che IE non può finestra modale "rispetto" uno stile di Win32 nello stesso modo in cui funziona una finestra modale sollevato da JavaScript utilizzando window.open().

Avete testato questo codice contro qualcosa di diverso da IE, giusto per confermare che funziona come dovrebbe per altre applicazioni?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top