我正在使用Windows表单。我在打开这样的程序时设置了一个启动画面。
class SharePrice
{
private:
double shareVal;
public:
SharePrice();
SharePrice(double price);
double getPrice() const { return shareVal; }
void setPrice(double price);
};
SharePrice::SharePrice()
{
setPrice(0);
}
SharePrice::SharePrice(double price)
{
setPrice(price);
}
void SharePrice::setPrice(double price)
{
if (price > 0)
shareVal = price;
else
shareVal = 0;
}
它有一个进度条和一个计时器。我从另一篇文章中得到了这个想法。这工作正常,启动画面正好应该出现。在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();
}
问题如下。当我打开exe时,启动屏幕会显示大约2秒钟,然后当它消失时,下一个表单会出现一秒钟,然后在我打开的每个其他窗口后面。
你知道我该怎么办呢?
更新1:
Thread t = new Thread(new ThreadStart(splash));
t.Start();
Thread.Sleep(2000);
InitializeComponent();
t.Abort();
这是我的启动画面
最终更新:
我让它以这种方式工作。
public void splash()
{
System.Windows.Forms.Application.Run(new Form2());
}
这是主要的。我不知道这有多好,但它确实有效。
答案 0 :(得分:3)
要回答您的具体问题,您可能只需在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})
之前从Main()启动启动画面,并从它的线程处理程序调用{{1}}。 Application.Run具有线程亲和性,因此启动屏幕将获得自己的Application.Run({splashScreen})
,它将正确挂钩Closing / Closed事件以关闭线程并仅通过调用或beginInvoking ApplicationContext
来引发ThreadExit
(通常来自SplashScreen.Close()
事件处理程序)。它还有其他一些小的好处,例如MainForm_Shown
包含启动画面。
采用这种方式几乎消除了我对启动画面的错误和挫折。
- 开始编辑 -
更全面的例子:
在Application.OpenForms
ApplicationContext
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());
}
}
方法的启动画面,以便您可以根据需要在外部进行更新。
SetProgress
主窗体:在构造函数中没有注意到任何内容,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
- 结束编辑 -
答案 1 :(得分:0)
我遇到了同样的问题,经过很长一段时间后,我在关闭启动画面后,在主窗体的Load事件中完成了以下操作:
//Manually activate frmMain as it gets back in the Z-order by Windows when splash screen closes.
NativeMethods.SetForegroundWindow(this.Handle);
this.Activate();
其中&#34; SetForegroundWindow&#34;定义如下:
/// <summary>
/// Sets foreground window
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("user32.dll")]
internal static extern bool SetForegroundWindow(IntPtr hWnd);
话虽如此,我们可能需要查看更多代码。
答案 2 :(得分:0)
经过长时间的努力,我找到了解决方案。 使用代码进入登录表单(Form_Load) this.Activate(); 示例:
private void login_Load(object sender, EventArgs e)
{
this.Activate();
}