前段时间写的C#程序启动欢迎窗体实现,在运行时虽然能显示欢迎窗体,但运行后不能把主窗体提到最前。结合网上搜罗了好多资料,自己做了好几个方案来实现,最终可以解决了。
起因:
2000/XP 改变了SetForegroundWindow的执行方式,不允许随便把窗口提前,打扰用户的工作。
思路:
可以用附加本线程到最前面窗口的线程,从而欺骗windows。
实现:
原理:将显示欢迎窗体的线程作为Foreground的线程。
1. API函数的导入
public const int SW_HIDE = 0;
public const int SW_NORMAL = 1;
public const int SW_SHOWMINIMIZED = 2;
public const int SW_SHOWMAXIMIZED = 3;
[DllImport("User32.dll")]
public static extern void SetForegroundWindow(IntPtr hwnd);
[DllImport("User32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("User32.dll")]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, IntPtr pProcId);
[DllImport("User32.dll")]
public static extern bool AttachThreadInput(int idAttach, int idAttachTo, int fAttach);
[DllImport("User32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
2. 使用API函数实现
private static void ActivateMainInstance(IntPtr mainWindowHandle, int foreId)
{
int curId = GetWindowThreadProcessId(mainWindowHandle, IntPtr.Zero);
if (curId != foreId)
{
AttachThreadInput(foreId, curId, 1);
SetForegroundWindow(mainWindowHandle);
AttachThreadInput(foreId, curId, 0);
}
else
{
SetForegroundWindow(mainWindowHandle);
}
ShowWindowAsync(mainWindowHandle, SW_SHOWMAXIMIZED);
}
3. 调用:
private static ApplicationContext _context = null;
private static SplashScreen _splash = null;
private static MainFrame _mForm = null;
private static void OnAppIdle(object sender, EventArgs e)
{
if (_context.MainForm == null)
{
Application.Idle -= new EventHandler(OnAppIdle);
// Initialize main frame and show
_mForm.InitializeFrame(); // 花时间点
_context.MainForm = _mForm;
_context.MainForm.Show();
// Active main form
ActivateMainInstance(_mForm.Handle, _splash.ThreadId);
// Close splash screen
_splash.Close();
_splash = null;
}
}
4. Main函数中:
// Show splash screen
_splash = new SplashScreen();
_splash.Run();
// Application running
_mForm = new MainFrame();
_context = new ApplicationContext();
Application.Idle += new EventHandler(OnAppIdle);
Application.Run(_context);
5. SplashScreen的实现:
public class SplashScreen
{
private SplashForm _sForm = null;
private Thread _workThread = null;
///
///
private void Show()
{
_sForm = new SplashForm();
_sForm.ShowDialog();
}
///
///
public int ThreadId
{
get
{
return _workThread.ManagedThreadId;
}
}
///
///
public void Run()
{
_workThread = new Thread(new ThreadStart(Show));
_workThread.Start();
}
///
///
public void Close()
{
if (_sForm != null)
{
_sForm.HideSplash = true;
_workThread.Join();
_workThread = null;
}
}
}
。

妹妹带了那么多下重庆来,自己就留了4节香肠,给我托了40多节,腊肉也自己留了一小点,给我托了2大块,第二天装好了才告诉我,我好是感动,爸爸也特意打电话给妹妹说多给我托点,老家还有,下次爸爸下来就给妹妹再带。说到我的爸爸,我得说几句,他是一个特别爱家的好男人,能吃苦,又节约,爱我们有他特殊的方式,默默的为全家人付出,自己在外打工,舍不得吃好的,舍不得用好一点,我们给他买的新衣服,他也舍不得穿,都放在家里,好吃的都会留着带回家给妈妈吃(说到这里了,我又记起了小时候,爸爸去给人家家的干活,人家家里吃的好吃的,比如皮蛋,咸蛋,花生,糖果,老爸总舍不得在饭桌上吃,都带回来我跟妹妹分着吃,当时我跟妹妹特别希望爸爸去别家吃饭,就是希望给我们带好吃的回来),现在我们都大了,自己在外面工作了,想吃什么都可以自己买了,就唯一很掂记家里的腊肉香肠,是外面买都买不到的。爸爸妈妈心里头都明白,妈妈也特别自豪我们还是那么喜欢吃她做的,更自豪的是女婿也爱吃她做的腊肉,香肠,哈哈,我又想起了一句话:不是一家人不近一家门!!!
心里特别开心,(呵呵,我跟LG都是大馋猫猫)要在这里特别感谢我的家人,我爱你们!新的一年,我们全家都幸幸福福,健健康康,开开心心,顺顺利利,钱钱多多!!!!





Feed: