Skip to content

Commit 274f8c4

Browse files
committed
Initial version for providing equivalent to DoEvents to allow pumping of message pumps in VBE thread for COM object marshalling.
1 parent dc17662 commit 274f8c4

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

Rubberduck.Parsing/UIContext/UiDispatcher.cs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
using System;
2+
using System.Runtime.InteropServices;
23
using System.Threading;
34
using System.Threading.Tasks;
45

56
namespace Rubberduck.Parsing.UIContext
67
{
78
public static class UiDispatcher
89
{
10+
static UiDispatcher()
11+
{
12+
_version = DllVersion.Unknown;
13+
}
14+
915
// thanks to Pellared on http://stackoverflow.com/a/12909070/1188513
1016

1117
private static SynchronizationContext UiContext { get; set; }
@@ -113,5 +119,69 @@ public static void Shutdown()
113119
// Dispatcher.CurrentDispatcher.InvokeShutdown();
114120
//});
115121
}
122+
123+
/// <summary>
124+
/// Used to pump any pending COM messages. This should be used only as a part of
125+
/// synchronizing or to effect a block until all other threads has finished with
126+
/// their pending COM calls.
127+
/// </summary>
128+
public static void DoEvents()
129+
{
130+
Invoke(() => ExecuteDoEvents());
131+
}
132+
133+
private static int ExecuteDoEvents()
134+
{
135+
switch (_version)
136+
{
137+
case DllVersion.Vbe7:
138+
return rtcDoEvents7();
139+
case DllVersion.Vbe6:
140+
return rtcDoEvents6();
141+
default:
142+
return DetermineVersionAndExecute();
143+
}
144+
}
145+
146+
private enum DllVersion
147+
{
148+
Unknown,
149+
Vbe6,
150+
Vbe7
151+
}
152+
153+
private static DllVersion _version;
154+
155+
[DllImport("vbe6.dll", EntryPoint = "rtcDoEvents")]
156+
private static extern int rtcDoEvents6();
157+
158+
[DllImport("vbe7.dll", EntryPoint = "rtcDoEvents")]
159+
private static extern int rtcDoEvents7();
160+
161+
private static int DetermineVersionAndExecute()
162+
{
163+
int result;
164+
try
165+
166+
{
167+
result = rtcDoEvents7();
168+
_version = DllVersion.Vbe7;
169+
}
170+
catch
171+
{
172+
try
173+
{
174+
result = rtcDoEvents6();
175+
_version = DllVersion.Vbe6;
176+
}
177+
catch
178+
{
179+
// we shouldn't be here....
180+
throw new InvalidOperationException("Cannot execute DoEvents; the VBE dll could not be located.");
181+
}
182+
}
183+
184+
return result;
185+
}
116186
}
117187
}

0 commit comments

Comments
 (0)