关于 Application.DoEvents 的实现
想在 C# 中使用 DoEvents 的功能,在 MSDN 中找到了与 VB6 中 DoEvents 对应的 Application.DoEvents()。忍不住使用 Relfector 看了一下 SDK 的代码,好麻烦啊!
Application.DoEvents
1 public static void DoEvents()
2 {
3 ThreadContext.FromCurrent().RunMessageLoop(2, null);
4 }
1 public static void DoEvents()
2 {
3 ThreadContext.FromCurrent().RunMessageLoop(2, null);
4 }
RunMessageLoop
1 internal void RunMessageLoop(int reason, ApplicationContext context)
2 {
3 IntPtr zero = IntPtr.Zero;
4 if (Application.useVisualStyles)
5 {
6 zero = UnsafeNativeMethods.ThemingScope.Activate();
7 }
8 try
9 {
10 this.RunMessageLoopInner(reason, context);
11 }
12 finally
13 {
14 UnsafeNativeMethods.ThemingScope.Deactivate(zero);
15 }
16 }
1 internal void RunMessageLoop(int reason, ApplicationContext context)
2 {
3 IntPtr zero = IntPtr.Zero;
4 if (Application.useVisualStyles)
5 {
6 zero = UnsafeNativeMethods.ThemingScope.Activate();
7 }
8 try
9 {
10 this.RunMessageLoopInner(reason, context);
11 }
12 finally
13 {
14 UnsafeNativeMethods.ThemingScope.Deactivate(zero);
15 }
16 }
RunMessageLoopInner
1 private void RunMessageLoopInner(int reason, ApplicationContext context)
2 {
3 if ((reason == 4) && !SystemInformation.UserInteractive)
4 {
5 throw new InvalidOperationException(SR.GetString("CantShowModalOnNonInteractive"));
6 }
7 if (reason == -1)
8 {
9 this.SetState(8, false);
10 }
11 if (totalMessageLoopCount++ == 0)
12 {
13 baseLoopReason = reason;
14 }
15 this.messageLoopCount++;
16 if (reason == -1)
17 {
18 if (this.messageLoopCount != 1)
19 {
20 throw new InvalidOperationException(SR.GetString("CantNestMessageLoops"));
21 }
22 this.applicationContext = context;
23 this.applicationContext.ThreadExit += new EventHandler(this.OnAppThreadExit);
24 if (this.applicationContext.MainForm != null)
25 {
26 this.applicationContext.MainForm.Visible = true;
27 }
28 }
29 Form currentForm = this.currentForm;
30 if (context != null)
31 {
32 this.currentForm = context.MainForm;
33 }
34 bool flag = false;
35 bool flag2 = false;
36 HandleRef hWnd = new HandleRef(null, IntPtr.Zero);
37 if (reason == -2)
38 {
39 flag2 = true;
40 }
41 if ((reason == 4) || (reason == 5))
42 {
43 flag = true;
44 bool enable = (this.currentForm != null) && this.currentForm.Enabled;
45 this.BeginModalMessageLoop(context);
46 hWnd = new HandleRef(null, UnsafeNativeMethods.GetWindowLong(new HandleRef(this.currentForm, this.currentForm.Handle), -8));
47 if (hWnd.Handle != IntPtr.Zero)
48 {
49 if (SafeNativeMethods.IsWindowEnabled(hWnd))
50 {
51 SafeNativeMethods.EnableWindow(hWnd, false);
52 }
53 else
54 {
55 hWnd = new HandleRef(null, IntPtr.Zero);
56 }
57 }
58 if (((this.currentForm != null) && this.currentForm.IsHandleCreated) && (SafeNativeMethods.IsWindowEnabled(new HandleRef(this.currentForm, this.currentForm.Handle)) != enable))
59 {
60 SafeNativeMethods.EnableWindow(new HandleRef(this.currentForm, this.currentForm.Handle), enable);
61 }
62 }
63 try
64 {
65 if (this.messageLoopCount == 1)
66 {
67 WindowsFormsSynchronizationContext.InstallIfNeeded();
68 }
69 if (flag && (this.currentForm != null))
70 {
71 this.currentForm.Visible = true;
72 }
73 if ((!flag && !flag2) || (this.ComponentManager is Application.ComponentManager))
74 {
75 this.ComponentManager.FPushMessageLoop(this.componentID, reason, 0);
76 }
77 else if ((reason == 2) || (reason == -2))
78 {
79 this.LocalModalMessageLoop(null);
80 }
81 else
82 {
83 this.LocalModalMessageLoop(this.currentForm);
84 }
85 }
86 finally
87 {
88 if (flag)
89 {
90 this.EndModalMessageLoop(context);
91 if (hWnd.Handle != IntPtr.Zero)
92 {
93 SafeNativeMethods.EnableWindow(hWnd, true);
94 }
95 }
96 this.currentForm = currentForm;
97 totalMessageLoopCount--;
98 this.messageLoopCount--;
99 if (this.messageLoopCount == 0)
100 {
101 WindowsFormsSynchronizationContext.Uninstall(false);
102 }
103 if (reason == -1)
104 {
105 this.Dispose(true);
106 }
107 else if ((this.messageLoopCount == 0) && (this.componentManager != null))
108 {
109 this.RevokeComponent();
110 }
111 }
112 }
1 private void RunMessageLoopInner(int reason, ApplicationContext context)
2 {
3 if ((reason == 4) && !SystemInformation.UserInteractive)
4 {
5 throw new InvalidOperationException(SR.GetString("CantShowModalOnNonInteractive"));
6 }
7 if (reason == -1)
8 {
9 this.SetState(8, false);
10 }
11 if (totalMessageLoopCount++ == 0)
12 {
13 baseLoopReason = reason;
14 }
15 this.messageLoopCount++;
16 if (reason == -1)
17 {
18 if (this.messageLoopCount != 1)
19 {
20 throw new InvalidOperationException(SR.GetString("CantNestMessageLoops"));
21 }
22 this.applicationContext = context;
23 this.applicationContext.ThreadExit += new EventHandler(this.OnAppThreadExit);
24 if (this.applicationContext.MainForm != null)
25 {
26 this.applicationContext.MainForm.Visible = true;
27 }
28 }
29 Form currentForm = this.currentForm;
30 if (context != null)
31 {
32 this.currentForm = context.MainForm;
33 }
34 bool flag = false;
35 bool flag2 = false;
36 HandleRef hWnd = new HandleRef(null, IntPtr.Zero);
37 if (reason == -2)
38 {
39 flag2 = true;
40 }
41 if ((reason == 4) || (reason == 5))
42 {
43 flag = true;
44 bool enable = (this.currentForm != null) && this.currentForm.Enabled;
45 this.BeginModalMessageLoop(context);
46 hWnd = new HandleRef(null, UnsafeNativeMethods.GetWindowLong(new HandleRef(this.currentForm, this.currentForm.Handle), -8));
47 if (hWnd.Handle != IntPtr.Zero)
48 {
49 if (SafeNativeMethods.IsWindowEnabled(hWnd))
50 {
51 SafeNativeMethods.EnableWindow(hWnd, false);
52 }
53 else
54 {
55 hWnd = new HandleRef(null, IntPtr.Zero);
56 }
57 }
58 if (((this.currentForm != null) && this.currentForm.IsHandleCreated) && (SafeNativeMethods.IsWindowEnabled(new HandleRef(this.currentForm, this.currentForm.Handle)) != enable))
59 {
60 SafeNativeMethods.EnableWindow(new HandleRef(this.currentForm, this.currentForm.Handle), enable);
61 }
62 }
63 try
64 {
65 if (this.messageLoopCount == 1)
66 {
67 WindowsFormsSynchronizationContext.InstallIfNeeded();
68 }
69 if (flag && (this.currentForm != null))
70 {
71 this.currentForm.Visible = true;
72 }
73 if ((!flag && !flag2) || (this.ComponentManager is Application.ComponentManager))
74 {
75 this.ComponentManager.FPushMessageLoop(this.componentID, reason, 0);
76 }
77 else if ((reason == 2) || (reason == -2))
78 {
79 this.LocalModalMessageLoop(null);
80 }
81 else
82 {
83 this.LocalModalMessageLoop(this.currentForm);
84 }
85 }
86 finally
87 {
88 if (flag)
89 {
90 this.EndModalMessageLoop(context);
91 if (hWnd.Handle != IntPtr.Zero)
92 {
93 SafeNativeMethods.EnableWindow(hWnd, true);
94 }
95 }
96 this.currentForm = currentForm;
97 totalMessageLoopCount--;
98 this.messageLoopCount--;
99 if (this.messageLoopCount == 0)
100 {
101 WindowsFormsSynchronizationContext.Uninstall(false);
102 }
103 if (reason == -1)
104 {
105 this.Dispose(true);
106 }
107 else if ((this.messageLoopCount == 0) && (this.componentManager != null))
108 {
109 this.RevokeComponent();
110 }
111 }
112 }