2017-03-21 25 views
1

私はWindowsフォームで作業しています。このようなプログラムを開くときに表示されるスプラッシュ画面を設定しました。スプラッシュ画面の後にWindowsフォームが後で移動する

protected override void OnLoad(EventArgs e) 
{ 
    base.OnLoad(e); 
    this.FormBorderStyle = FormBorderStyle.None; 
} 

private void timer1_Tick(object sender, EventArgs e) 
{ 
    progressBar1.Increment(15); 
    if (progressBar1.Value == 30) timer1.Stop(); 
} 

プログレスバーとタイマーがあります。私はここに別の投稿からアイデアを得た。これは問題なく動作しています。スプラッシュ画面が表示されます。この後に表示されるウィンドウのフォームで私は持っています:

Thread t = new Thread(new ThreadStart(splash)); 
t.Start(); 
Thread.Sleep(2000); 

InitializeComponent(); 
t.Abort(); 

問題は次のとおりです。 exeを開くと、スプラッシュ画面が約2秒間表示され、消えると、次のフォームが2番目に表示され、次に開いたウィンドウが1つおきに表示されます。

どうすれば修正できますか?

アップデート1:

public void splash() 
{ 
    System.Windows.Forms.Application.Run(new Form2()); 
} 

この私のスプラッシュ画面で

最終更新日:

私はそれを得たが、このように動作します。

 Splash splash = new Splash(); 
     Instalador instalador = new Instalador(); 

     splash.Show(); 
     Thread.Sleep(2 * 1000); 
     splash.Close(); 

     Application.Run(instalador); 

これはメインです。私はこれがどのくらいOKか分かりませんが、うまくいきます。

+2

[メインウィンドウには、スプラッシュ画面の後に他のウィンドウの背後に表示されます](http://stackoverflow.com/questions/31277790/main-window-appears-の可能性のある重複背後にある他の窓fter-splash-screen) – Sinatr

+0

@Sinatrいいえ、私はしませんでした。したほうがいい? – TiraULTI

+0

'スプラッシュ'のコードを表示することができます –

答えて

0

私は同じ問題を持っていたし、非常に長い時間のためにstugglingた後、私は、スプラッシュ画面を閉じた後、メインフォームのLoadイベントに次のようにやってしまった:

「SetForegroundWindow」が定義されて
//Manually activate frmMain as it gets back in the Z-order by Windows when splash screen closes. 
NativeMethods.SetForegroundWindow(this.Handle); 
this.Activate(); 

/// <summary> 
/// Sets foreground window 
/// </summary> 
/// <param name="hWnd"></param> 
/// <returns></returns> 
[DllImport("user32.dll")] 
internal static extern bool SetForegroundWindow(IntPtr hWnd); 

あなたのコードをもっと見る必要があると言われています。

+0

これを動作させることができませんでした。 "SetForegroundWindow"はどこで定義しますか? – TiraULTI

1

あなただけthis.Activate()

InitializeComponent
Thread t = new Thread(new ThreadStart(splash)); 
t.Start(); 
Thread.Sleep(2000); 

InitializeComponent(); 
this.Activate(); 
t.Abort(); 

を追加することで逃げるかもしれない、あなたの特定の質問に答えるためにしかし、非常に少なくとも、いうだけでスレッドを中断するよりも、きれいにスプラッシュ画面をシャットダウンハンドシェイクを実装します。

また、スプラッシュ画面のスレッドで何を行っているかによって、さまざまな微妙な問題が発生する可能性があります。あなたが現在持っているZオーダーの問題。

一般的に、私はApplication.Run({main form})前にメイン()から私のスプラッシュ画面を起動しても、それのスレッドハンドラからApplication.Run({splashScreen})を呼び出します。 Application.Runはスレッドアフィニティを持っているので、スプラッシュ画面には、ApplicationContextがクローズ/クローズイベントを正常にフックしてスレッドをシャットダウンし、SplashScreen.Close()(通常はMainForm_Shownイベントハンドラから)を起動または呼び出すことによってThreadExitを発生させます。スプラッシュ画面を含むApplication.OpenFormsなどのその他の小さなメリットもあります。

このルートをとることで、私のバグやスプラッシュスクリーンの不満がほとんどなくなりました。

-Begin編集 -

より徹底した例は:

は、あなたが更新できるように追加SetProgress方法でMain()

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     Thread t = new Thread(new ThreadStart(splash)); 
     t.IsBackground = true; 
     t.SetApartmentState(ApartmentState.STA); 
     t.Start(); 
     Application.Run(new Form1()); 
    } 
    private static void splash() 
    { 
     Application.Run(new Form2()); 
    } 
} 

スプラッシュ画面における第二のスレッドとApplicationContextを起動

もしあなたが望むならば、それは外部的に。

public partial class Form2 : Form 
{ 

    public Form2() 
    { 
     InitializeComponent(); 
     timer1.Start(); 
    } 
    public void SetProgress() 
    { 
     if (this.InvokeRequired) //Should have been handled by SplashScreenHandler but check just in case. 
      this.BeginInvoke(new Action(SetProgress)); 
     progressBar1.Increment(15); 
    } 

    private void timer1_Tick(object sender, EventArgs e) 
    { 
     progressBar1.Increment(15); 
     if (progressBar1.Value == 30) timer1.Stop(); 
    } 
} 

メインフォーム:あなたは代わりにステータスの更新のためのタイマーに頼るつもりなら、コンストラクタでは何とShownイベントハンドラを注意しないが(参照して持ち運ぶことなく、スプラッシュ画面(複数可)をシャットダウンします。 )

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     //Simulate a long init 
     Thread.Sleep(2000); 

     InitializeComponent(); 
    } 

    private void Form1_Shown(object sender, EventArgs e) 
    { 
     foreach (var splashScreen in Application.OpenForms.OfType<Form2>()) 
     { 
      splashScreen.BeginInvoke((Action) delegate() { splashScreen.Close(); }); 
     } 
    } 
} 

-End編集 -

+0

Activateはそれを修正しませんでした。あなたが言ったことをもう一度見てみましょう – TiraULTI

関連する問題