تحديد أين تفعيل يحدث عندما يكون النموذج هو إبطال مفعولها

StackOverflow https://stackoverflow.com/questions/813356

سؤال

لا أحد يعرف من طريقة لتحديد أي نافذة سوف تتلقى التركيز عندما يكون النموذج قد تم تعطيله ؟

هل كانت مفيدة؟

المحلول

وجدت الجواب.بدلا من الاشتراك في تفعيل وتنشيط الفعاليات التعامل مع WM_ACTIVATE رسالة (تستخدم في كل التفعيل والتعطيل) في WndProc.لأنه التقارير مقبض النافذة التي يجري تفعيلها, لا يمكن مقارنة هذا المؤشر إلى مقابض من أشكال تحديد ما إذا كان التركيز هو تغيير إلى أي منهم.

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);  
} 

تحرير: هذه الطريقة يمكن استخدامها خارج النافذة الأمر ينطبق على (مثلا ، خارج في نافذة منبثقة).

يمكنك استخدام NativeWindow أن نعلق على أي نافذة على التعامل مع عرض حلقة الرسالة.انظر المثال التعليمات البرمجية أدناه:

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);
        } 
    }
}

نصائح أخرى

ويجب أن تكون قادرا على تحديد النموذج النشط باستخدام خاصية ثابتة Form.ActiveForm.

أنا أعاني من نفس المشكلة عند تنفيذ الإكمال التلقائي نافذة منبثقة (على غرار التحسس نافذة في مقابل).

المشكلة مع WndProc النهج هو أن رمز يجب أن تضاف إلى أي شكل الذي يحدث المضيف المنبثقة.

النهج البديل هو استخدام الموقت شكل الاختيار.ActiveControl بعد فترة وجيزة.هذا الطريق هو رمز مغلف أفضل ، داخل محرر التحكم أو المنبثقة شكل.

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(); 
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top