This repository has been archived by the owner on Apr 29, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
OfficeUIManager.cs
361 lines (333 loc) · 9.7 KB
/
OfficeUIManager.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
/*
* $HeadURL$
* $LastChangedBy$
* $Date$
* $Revision$
*/
using System;
using System.Collections;
using Microsoft.Office.Core;
namespace BlueprintIT.Office
{
/// <summary>
/// Represents a method to receive events about Office based windows
/// </summary>
public delegate void WindowEventHandler(OfficeWindow window);
/// <summary>
/// Manages the user interface for an Office based addin.
/// </summary>
/// <remarks>
/// The manager allows addins to specify their user interface requirements
/// through the use of the toolbar objects. These are then translated into CommandBars when
/// office windows are opened.
/// </remarks>
public abstract class OfficeUIManager: IDisposable
{
/// <summary>
/// Occurs when an Office window is opened.
/// </summary>
public event WindowEventHandler WindowOpen;
/// <summary>
/// Occurs when an Office window is closed.
/// </summary>
public event WindowEventHandler WindowClose;
/// <summary>
/// Maps from the command control tag to the <see cref="OfficeWindow">OfficeWindow</see> instance.
/// </summary>
private IDictionary controlWindowMap;
/// <summary>
/// Maps from the command control tag to the ToolbarControl.
/// </summary>
private IDictionary controlControlMap;
/// <summary>
/// Maps from the command control tag to the CommandBarControl instance.
/// </summary>
private IDictionary controlProxyMap;
/// <summary>
/// Holds the COM ProgID of the addin using the UI Manager.
/// </summary>
private string progid;
/// <summary>
/// Holds the event handler for combo box events.
/// </summary>
private _CommandBarComboBoxEvents_ChangeEventHandler comboBoxChange;
/// <summary>
/// Holds the event handler for button events.
/// </summary>
private _CommandBarButtonEvents_ClickEventHandler buttonClick;
/// <summary>
/// Creates a new UI manager for the addin with the given COM ProgID.
/// </summary>
/// <param name="progid">The COM ProgID of the addin usin the UI manager</param>
protected OfficeUIManager(string progid)
{
this.progid=progid;
controlControlMap = new Hashtable();
controlWindowMap = new Hashtable();
controlProxyMap = new Hashtable();
comboBoxChange = new _CommandBarComboBoxEvents_ChangeEventHandler(combo_Change);
buttonClick = new _CommandBarButtonEvents_ClickEventHandler(button_Click);
}
/// <summary>
/// Disposes the manager if it has not already happened.
/// </summary>
~OfficeUIManager()
{
Dispose();
}
/// <summary>
/// Returns a list of <see cref="OfficeWindow">OfficeWindows</see> currently open
/// </summary>
public abstract IList Windows
{
get;
}
/// <summary>
/// Returns the addins COM ProgID
/// </summary>
public string AddinProgID
{
get
{
return progid;
}
}
/// <summary>
/// Disposes of the manager cleanly, releasing all COM objects.
/// </summary>
public virtual void Dispose()
{
foreach (CommandBarControl control in controlProxyMap.Values)
{
UnbindControl(control);
#if (COMRELEASE)
System.Runtime.InteropServices.Marshal.ReleaseComObject(control);
#endif
}
controlControlMap.Clear();
controlWindowMap.Clear();
controlProxyMap.Clear();
GC.SuppressFinalize(this);
}
/// <summary>
/// This method should return the Toolbars that need to be applied to a given
/// OfficeWindow.
/// </summary>
/// <remarks>
/// Managers for particular office applications should define this method.
/// </remarks>
/// <param name="window">A window that has just opened.</param>
/// <returns>The Toolbars to apply to the window.</returns>
protected abstract Toolbars GetWindowToolbars(OfficeWindow window);
/// <summary>
/// Registers a newly created command bar with the UI manager.
/// </summary>
/// <param name="bar">The CommandBar created.</param>
/// <param name="window">The OfficeWindow the command bar was created on.</param>
/// <param name="toolbar">The Toolbar that the command bar was created from.</param>
internal void RegisterCommandBar(CommandBar bar, OfficeWindow window, Toolbar toolbar)
{
}
/// <summary>
/// Registers a new command bar control.
/// </summary>
/// <remarks>
/// The UI manager will begin listening out for events happening to this control
/// and dispatch them to the correct listeners.
/// </remarks>
/// <param name="control">The CommandBarControl created.</param>
/// <param name="window">The OfficeWindow holding the control.</param>
/// <param name="tcontrol">The ToolbarControl that the control was created from.</param>
internal void RegisterCommandBarControl(CommandBarControl control, OfficeWindow window, ToolbarControl tcontrol)
{
if (!controlControlMap.Contains(control.Tag))
{
controlControlMap[control.Tag]=tcontrol;
}
else
{
CommandBarControl oldcontrol = (CommandBarControl)controlProxyMap[control.Tag];
UnbindControl(oldcontrol);
#if (COMRELEASE)
System.Runtime.InteropServices.Marshal.ReleaseComObject(oldcontrol);
#endif
}
BindControl(control);
controlProxyMap[control.Tag]=control;
controlWindowMap[control.Tag]=window;
}
/// <summary>
/// Applies the defined interface to all currently open windows.
/// </summary>
public void ApplyInterface()
{
foreach (OfficeWindow window in Windows)
{
GetWindowToolbars(window).Apply(window);
}
}
/// <summary>
/// Occurs when a new window has been opened.
/// </summary>
/// <remarks>
/// Applies the necessary user interface to the window.
/// </remarks>
/// <param name="window">The window that has just opened.</param>
protected void OnWindowOpen(OfficeWindow window)
{
Toolbars bars = GetWindowToolbars(window);
bars.Apply(window);
if (WindowOpen!=null)
{
WindowOpen(window);
}
}
/// <summary>
/// Occurs when a window has been closed.
/// </summary>
/// <remarks>
/// Unregisters and toolbar buttons on the window and releases their COM objects.
/// </remarks>
/// <param name="window"></param>
protected void OnWindowClose(OfficeWindow window)
{
if (WindowClose!=null)
{
WindowClose(window);
}
foreach (string tag in controlControlMap.Keys)
{
if (controlControlMap[tag]==window)
{
controlControlMap.Remove(tag);
controlWindowMap.Remove(tag);
CommandBarControl control = (CommandBarControl)controlProxyMap[tag];
UnbindControl(control);
#if (COMRELEASE)
System.Runtime.InteropServices.Marshal.ReleaseComObject(control);
#endif
controlProxyMap.Remove(tag);
}
}
}
/// <summary>
/// Binds to a control to hear events.
/// </summary>
/// <param name="control">The control to bind to.</param>
private void BindControl(CommandBarControl control)
{
if (control is CommandBarButton)
{
CommandBarButton button = control as CommandBarButton;
button.Click+=buttonClick;
}
else if (control is CommandBarPopup)
{
CommandBarPopup popup = control as CommandBarPopup;
}
else if (control is CommandBarComboBox)
{
CommandBarComboBox combo = control as CommandBarComboBox;
combo.Change+=comboBoxChange;
}
}
/// <summary>
/// Removes event handlers from a control.
/// </summary>
/// <param name="control">The control to unbind from.</param>
private void UnbindControl(CommandBarControl control)
{
if (control is CommandBarButton)
{
((CommandBarButton)control).Click-=buttonClick;
}
else if (control is CommandBarPopup)
{
}
else if (control is CommandBarComboBox)
{
((CommandBarComboBox)control).Change-=comboBoxChange;
}
}
/// <summary>
/// Hears button clicks for any custom CommandBarButtons.
/// <seealso cref="Microsoft.Office._CommandBarButtonEvents_ClickEventHandler"/>
/// </summary>
/// <param name="Ctrl">The control that was clicked.</param>
/// <param name="CancelDefault">Whether to cancel the default action.</param>
private void button_Click(CommandBarButton Ctrl, ref bool CancelDefault)
{
ToolbarButton control = (ToolbarButton)controlControlMap[Ctrl.Tag];
OfficeWindow window = (OfficeWindow)controlWindowMap[Ctrl.Tag];
control.OnClick(window);
}
/// <summary>
/// Hears button clicks for any custom CommandBarComboBox.
/// <seealso cref="Microsoft.Office._CommandBarComboBoxEvents_ChangeEventHandler"/>
/// </summary>
/// <param name="Ctrl">The combo box that was changed.</param>
private void combo_Change(CommandBarComboBox Ctrl)
{
ToolbarComboBox control = (ToolbarComboBox)controlControlMap[Ctrl.Tag];
OfficeWindow window = (OfficeWindow)controlWindowMap[Ctrl.Tag];
control.OnChange(window);
}
}
/// <summary>
/// An abstract OfficeWindow
/// </summary>
/// <remarks>
/// UI managers for specific office applications should define their own specific
/// classes from this.
/// </remarks>
public abstract class OfficeWindow
{
/// <summary>
/// The CommandBars for the OfficeWindow.
/// </summary>
public abstract CommandBars CommandBars
{
get;
}
/// <summary>
/// Activates the window, bringing it to the front of the display.
/// </summary>
public abstract void Activate();
/// <summary>
/// Closes the window.
/// </summary>
public abstract void Close();
/// <summary>
/// The x-coordinate of the left of the window in pixels.
/// </summary>
public abstract int Left
{
get;
set;
}
/// <summary>
/// The y-coordinate of the top of the window in pixels.
/// </summary>
public abstract int Top
{
get;
set;
}
/// <summary>
/// The width of the window in pixels.
/// </summary>
public abstract int Width
{
get;
set;
}
/// <summary>
/// The height of the window in pixels.
/// </summary>
public abstract int Height
{
get;
set;
}
}
}