технология создания Splash-окна
От: yg  
Дата: 24.11.04 09:28
Оценка:
Предлагаю покончить с размножением веток с подобными сабжами, разъяснив непонятливым (я в том числе), как создавать Splash-окна. Главное правило, которого я придерживался, создать сплеш в дополнительном потоке и все операции с ним проводить через Invoke. Вот код, который у меня получился:

public class CFrmMain : System.Windows.Forms.Form
{
    ///...
    public delegate void VoidDel();
    //=======================================================================================
    public CFrmMain()
    {
        VoidDel del = new VoidDel(this.SplashShow);
        Thread th = new Thread(new ThreadStart(del));
        th.Start();                        //выполняется в ГЛАВНОМ потоке

        InitializeComponent();
    }
    //=======================================================================================
    ///...
    //=======================================================================================
    void SplashShow()
    {
        CSplash.Instance.ShowDialog();    //выполняется в ПОБОЧНОМ потоке
    }
    //=======================================================================================
    public void InvokeSplashClose()
    {
        VoidDel del = new VoidDel(SplashClose);
        CSplash.Instance.Invoke(del);    //выполняется в ГЛАВНОМ потоке
    }
    //=======================================================================================
    public void SplashClose()
    {
        CSplash.Instance.CloseWin();    //выполняется в ПОБОЧНОМ потоке
    }
    //=======================================================================================
    public void CFrmMain_VisibleChanged(object sender, System.EventArgs e)
    {
        if (!this.Visible)
            return;
        SetForegroundWindow(this.Handle);
        P.InvokeSplashClose();            //выполняется в ГЛАВНОМ потоке
    }
    //=========================================================================================
}

Класс Splash'a
public class CSplash : System.Windows.Forms.Form
{
    static CSplash self;
    //=========================================================================================
    private CSplash()
    {
        InitializeComponent();
    }
    //=========================================================================================
    static public CSplash Instance
    {
        get
        {
            if (CSplash.self == null)
                CSplash.self = new CSplash();
            return CSplash.self;
        }
    }
    //=========================================================================================
    public void CloseWin()
    {
        if (CSplash.self != null)
            CSplash.self.Close();
        CSplash.self = null;
    }
    //=========================================================================================
}

В обычном режиме все работает неплохо.

А теперь о печальном : Запускаю программу, жду, пока отработает. Запускаю Magnifier, она же лупа. И ТУТ: или сразу выпадает DisposeException для одного из объектов на главной форме или если, например, щелкнуть кнопку "восстановить" — ArgumentNullException. Если без сплеша, то все сработает нормально.
Мелочь, а неприятно: все-таки знаешь, что где-то с потоками напортачил — возможно вылетать будет и в каких-то других случаях.

PS: Интересно, что же такое делает Лупа со всеми открытыми окнами при запуске...


24.11.04 16:20: Перенесено модератором из '.NET' — AndrewVK
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.