Frage

Kennt jemand eine Möglichkeit, zu bestimmen, welche Fenster den Fokus erhalten wird, wenn ein Formular deaktiviert wird?

War es hilfreich?

Lösung

fand ich die Antwort. Statt an die aktivierten und deaktivieren Ereignisse zu abonnieren, behandeln die WM_ACTIVATE Nachricht in WndProc (sowohl für die Aktivierung und Deaktivierung verwendet wird). Da es der Griff des Fensters meldet aktiviert wird, kann ich diesen Griff an den Griffen meiner Formen vergleichen und festzustellen, ob Fokus auf einer von ihnen verändert sich.

const int WM_ACTIVATE = 0x0006;
const int WA_INACTIVE = 0;
const int WA_ACTIVE = 1;  
const int WA_CLICKACTIVE = 2;  

protected override void WndProc(ref Message m)  
{  
    if (m.Msg == WM_ACTIVATE)  
    {  
         // When m.WParam is WA_INACTIVE, the window is being deactivated and
         // m.LParam is the handle of the window that will be activated.

         // When m.WParam is WA_ACTIVE or WA_CLICKACTIVE, the window is being 
         // activated and m.LParam is the handle of the window that has been 
         // deactivated.
    }  

    base.WndProc(ref m);  
} 

Edit:. Diese Methode kann außerhalb des Fensters verwendet werden, es gilt (zum Beispiel außerhalb in einem Popup-Fenstern)

Sie können Native verwenden, um jedes Fenster auf seinem Griff und sehen seine Meldungsschleife auf Basis zu befestigen. Siehe folgende Codebeispiel:

public class Popup : Form
{
    const int WM_ACTIVATE = 0x0006;
    const int WA_INACTIVE = 0;
    private ParentWindowIntercept parentWindowIntercept;

    public Popup(IntPtr hWndParent)
    {
        this.parentWindowIntercept = new ParentWindowIntercept(hWndParent);
    }

    private class ParentWindowIntercept : NativeWindow
    {
        public ParentWindowIntercept(IntPtr hWnd)
        {
            this.AssignHandle(hWnd);
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_ACTIVATE)
            {
                if ((int)m.WParam == WA_INACTIVE)
                {
                    IntPtr windowFocusGoingTo = m.LParam;
                    // Compare handles here
                }
            }

            base.WndProc(ref m);
        } 
    }
}

Andere Tipps

Sie sollten die aktive Form mit der Form.ActiveForm statischen Eigenschaft, um bestimmen können.

Ich habe das gleiche Problem, wenn ein Autocomplete-Popup-Fenster (ähnlich wie IntelliSense-Fenster in VS) zu implementieren.

Problem mit dem WndProc Ansatz ist, dass Code in irgendeiner Form hinzugefügt werden muss, dass die Popup-Host passiert.

Alternative Ansatz ist es, einen Timer zu verwenden und überprüft Form.ActiveControl nach einer kurzen Pause. Auf diese Weise Code ist gekapselt besser, im Editor-Steuerelement oder das Popup-Formular .

Form _txPopup;

// Subscribe whenever convenient
public void IntializeControlWithPopup(Form _hostForm)
{
    _hostForm.Deactivate + OnHostFormDeactivate;
}

Timer _deactivateTimer;
Form _hostForm;
void OnHostFormDeactivate(object sender, EventArgs e)
{
    if (_deactivateTimer == null) 
    {
        _mainForm = sender as Form;
        _deactivateTimer = new Timer();
        _deactivateTimer.Interval = 10;
        _deactivateTimer.Tick += DeactivateTimerTick;
    }
    _deactivateTimer.Start();
}

void  DeactivateTimerTick(object sender, EventArgs e)
{
    _deactivateTimer.Stop();
    Form activeForm = Form.ActiveForm;
    if (_txPopup != null && 
        activeForm != _txPopup && 
        activeForm != _mainForm) 
    { 
        _txPopup.Hide(); 
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top