-
Notifications
You must be signed in to change notification settings - Fork 4
/
WindowWatcher.cs
128 lines (108 loc) · 3.29 KB
/
WindowWatcher.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using EnvDTE80;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.TextManager.Interop;
using WordLight.EventAdapters;
namespace WordLight
{
public class WindowWatcher : IDisposable
{
private IDictionary<IVsTextView, TextView> _textViews;
private TextManagerEventAdapter _textManagerEvents;
private object _watcherSyncRoot = new object();
private DTE2 _application;
private IVsTextManager _textManager;
public WindowWatcher(DTE2 application)
{
if (application == null) throw new ArgumentNullException("application");
_application = application;
_textViews = new Dictionary<IVsTextView, TextView>();
_textManager = GetTextManager(application);
_textManagerEvents = new TextManagerEventAdapter(_textManager);
_textManagerEvents.ViewRegistered += new EventHandler<ViewRegistrationEventArgs>(ViewRegisteredHandler);
_textManagerEvents.ViewUnregistered += new EventHandler<ViewRegistrationEventArgs>(ViewUnregisteredHandler);
}
private IVsTextManager GetTextManager(DTE2 application)
{
using (ServiceProvider wrapperSP = new ServiceProvider((Microsoft.VisualStudio.OLE.Interop.IServiceProvider)application))
{
return (IVsTextManager)wrapperSP.GetService(typeof(SVsTextManager));
}
}
private void ViewRegisteredHandler(object sender, ViewRegistrationEventArgs e)
{
try
{
System.Threading.ThreadPool.QueueUserWorkItem((object state) =>
{
try
{
System.Threading.Thread.Sleep(200);
lock (_watcherSyncRoot)
{
if (e.View != null && !_textViews.ContainsKey(e.View))
{
var textView = new TextView(e.View);
_textViews.Add(e.View, textView);
Log.Debug("Registered view: {0}", e.View.GetHashCode());
}
}
}
catch (Exception ex)
{
Log.Error("Failed to register a view", ex);
}
});
}
catch (Exception ex)
{
Log.Error("Failed to enqueue a work item", ex);
}
}
private void ViewUnregisteredHandler(object sender, ViewRegistrationEventArgs e)
{
try
{
lock (_watcherSyncRoot)
{
if (e.View != null && _textViews.ContainsKey(e.View))
{
TextView view = _textViews[e.View];
_textViews.Remove(e.View);
view.Dispose();
Log.Debug("Unregistered view: {0}", e.View.GetHashCode().ToString());
}
}
}
catch (Exception ex)
{
Log.Error("Failed to unregister a view", ex);
}
}
public void Dispose()
{
lock (_watcherSyncRoot)
{
foreach (TextView view in _textViews.Values)
{
view.Dispose();
}
_textViews.Clear();
}
}
public TextView GetActiveTextView()
{
lock (_watcherSyncRoot)
{
IVsTextView activeVsView;
_textManager.GetActiveView(Convert.ToInt32(true), null, out activeVsView);
if (activeVsView != null && _textViews.ContainsKey(activeVsView))
return _textViews[activeVsView];
else
return null;
}
}
}
}