Skip to content

Commit 9c1aaed

Browse files
committed
First attempt at tracking ExcelToolTip in UIMonitor
1 parent 2ccb332 commit 9c1aaed

File tree

10 files changed

+252
-38
lines changed

10 files changed

+252
-38
lines changed

Source/ExcelDna.IntelliSense.Host/ExcelDna.IntelliSense.Host-AddIn.xll.config

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
<system.diagnostics>
44
<trace autoflush="true" indentsize="4"/>
55
<sources>
6-
<source name="ExcelDna.IntelliSense" switchValue="Off">
6+
<source name="ExcelDna.IntelliSense" switchValue="All">
77
<listeners>
88
<!--<remove name="Default" />-->
99
<!--<add name="LogDisplay" type="ExcelDna.Logging.LogDisplayTraceListener,ExcelDna.Integration">
1010
<filter type="System.Diagnostics.EventTypeFilter" initializeData="All"/>
1111
</add>-->
12-
<add name="File" type="System.Diagnostics.TextWriterTraceListener" initializeData="ExcelDna.IntelliSense.log" >
12+
<!--<add name="File" type="System.Diagnostics.TextWriterTraceListener" initializeData="ExcelDna.IntelliSense.log" >
1313
<filter type="System.Diagnostics.EventTypeFilter" initializeData="All"/>
14-
</add>
14+
</add>-->
1515
</listeners>
1616
</source>
1717
</sources>

Source/ExcelDna.IntelliSense/ExcelDna.IntelliSense.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
<Compile Include="Providers\ExcelDnaIntelliSenseProvider.cs" />
7878
<Compile Include="Providers\WorkbookIntelliSenseProvider.cs" />
7979
<Compile Include="Providers\XmlIntelliSenseProvider.cs" />
80+
<Compile Include="UIMonitor\ExcelToolTipWatcher.cs" />
8081
<Compile Include="UIMonitor\FormulaEditWatcher.cs" />
8182
<Compile Include="UIMonitor\FormulaParser.cs" />
8283
<Compile Include="IntelliSenseDisplay.cs" />

Source/ExcelDna.IntelliSense/IntelliSenseDisplay.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,20 +143,20 @@ void StateUpdate(object sender, UIStateUpdate update)
143143
case UIStateUpdate.UpdateType.FormulaEditStart:
144144
var fes = (UIState.FormulaEdit)update.NewState;
145145
UpdateFormulaEditWindow(fes.FormulaEditWindow);
146-
FormulaEditStart(fes.FormulaPrefix, fes.EditWindowBounds, fes.ExcelTooltipBounds);
146+
FormulaEditStart(fes.FormulaPrefix, fes.EditWindowBounds, fes.ExcelToolTipWindow);
147147
break;
148148
case UIStateUpdate.UpdateType.FormulaEditMove:
149149
var fem = (UIState.FormulaEdit)update.NewState;
150-
FormulaEditMove(fem.EditWindowBounds, fem.ExcelTooltipBounds);
150+
FormulaEditMove(fem.EditWindowBounds, fem.ExcelToolTipWindow);
151151
break;
152152
case UIStateUpdate.UpdateType.FormulaEditWindowChange:
153153
var fewc = (UIState.FormulaEdit)update.NewState;
154154
UpdateFormulaEditWindow(fewc.FormulaEditWindow);
155-
FormulaEditTextChange(fewc.FormulaPrefix, fewc.EditWindowBounds, fewc.ExcelTooltipBounds);
155+
FormulaEditTextChange(fewc.FormulaPrefix, fewc.EditWindowBounds, fewc.ExcelToolTipWindow);
156156
break;
157157
case UIStateUpdate.UpdateType.FormulaEditTextChange:
158158
var fetc = (UIState.FormulaEdit)update.NewState;
159-
FormulaEditTextChange(fetc.FormulaPrefix, fetc.EditWindowBounds, fetc.ExcelTooltipBounds);
159+
FormulaEditTextChange(fetc.FormulaPrefix, fetc.EditWindowBounds, fetc.ExcelToolTipWindow);
160160
break;
161161
case UIStateUpdate.UpdateType.FunctionListShow:
162162
var fls = (UIState.FunctionList)update.NewState;
@@ -233,7 +233,7 @@ void UpdateFunctionListWindow(IntPtr functionListWindow)
233233
}
234234

235235
// Runs on the main thread
236-
void FormulaEditStart(string formulaPrefix, Rect editWindowBounds, Rect excelTooltipBounds)
236+
void FormulaEditStart(string formulaPrefix, Rect editWindowBounds, IntPtr excelToolTipWindow)
237237
{
238238
Debug.Print($"IntelliSenseDisplay - FormulaEditStart - FormulaEditWindow: {_formulaEditWindow}, ArgumentsToolTip: {_argumentsToolTip}");
239239
if (_formulaEditWindow != IntPtr.Zero && _argumentsToolTip == null)
@@ -242,7 +242,7 @@ void FormulaEditStart(string formulaPrefix, Rect editWindowBounds, Rect excelToo
242242
// Normally we would have no formula at this point.
243243
// One exception is after mouse-click on the formula list, we then need to process it.
244244
if (!string.IsNullOrEmpty(formulaPrefix))
245-
FormulaEditTextChange(formulaPrefix, editWindowBounds, excelTooltipBounds);
245+
FormulaEditTextChange(formulaPrefix, editWindowBounds, excelToolTipWindow);
246246
}
247247

248248
// Runs on the main thread
@@ -259,7 +259,7 @@ void FormulaEditEnd()
259259
}
260260

261261
// Runs on the main thread
262-
void FormulaEditMove(Rect editWindowBounds, Rect excelTooltipBounds)
262+
void FormulaEditMove(Rect editWindowBounds, IntPtr excelToolTipWindow)
263263
{
264264
Debug.Print($"IntelliSenseDisplay - FormulaEditMove");
265265
if (_argumentsToolTip == null)
@@ -271,7 +271,7 @@ void FormulaEditMove(Rect editWindowBounds, Rect excelTooltipBounds)
271271
}
272272

273273
// Runs on the main thread
274-
void FormulaEditTextChange(string formulaPrefix, Rect editWindowBounds, Rect excelTooltipBounds)
274+
void FormulaEditTextChange(string formulaPrefix, Rect editWindowBounds, IntPtr excelToolTipWindow)
275275
{
276276
Debug.Print($"^^^ FormulaEditStateChanged. CurrentPrefix: {formulaPrefix}, Thread {Thread.CurrentThread.ManagedThreadId}");
277277
string functionName;

Source/ExcelDna.IntelliSense/IntelliSenseServer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ public static void Refresh()
117117

118118
private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
119119
{
120+
// CONSIDER: We get this quite late in the shutdown
121+
// We should try to find a way to identify Excel shutdown a lot earlier
120122
Logger.Initialization.Verbose("IntelliSenseServer ProcessExit Begin");
121123
if (_isActive)
122124
{
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading;
4+
using System.Windows;
5+
6+
namespace ExcelDna.IntelliSense
7+
{
8+
class ExcelToolTipWatcher : IDisposable
9+
{
10+
public enum ToolTipChangeType
11+
{
12+
Show,
13+
Hide,
14+
// Move
15+
}
16+
17+
public class ToolTipChangeEventArgs : EventArgs
18+
{
19+
public ToolTipChangeType ChangeType { get; private set; }
20+
public IntPtr Handle { get; private set; }
21+
22+
public ToolTipChangeEventArgs(ToolTipChangeType changeType, IntPtr handle)
23+
{
24+
ChangeType = changeType;
25+
Handle = handle;
26+
}
27+
28+
public override string ToString() => $"{ChangeType}:0x{Handle:x}";
29+
}
30+
31+
// NOTE: Event will always be raised on our automation thread
32+
public event EventHandler<ToolTipChangeEventArgs> ToolTipChanged; // Either text or location
33+
34+
// CONSIDER: What should this look like?
35+
public IEnumerable<IntPtr> GetToolTips() => _toolTips;
36+
// CONSIDER: Rather a Stack? Check the assumption that Hide happens in reverse order
37+
HashSet<IntPtr> _toolTips = new HashSet<IntPtr>();
38+
SynchronizationContext _syncContextAuto; // Not used...
39+
WindowWatcher _windowWatcher;
40+
41+
public ExcelToolTipWatcher (WindowWatcher windowWatcher, SynchronizationContext syncContextAuto)
42+
{
43+
_syncContextAuto = syncContextAuto;
44+
_windowWatcher = windowWatcher;
45+
_windowWatcher.ExcelToolTipWindowChanged += _windowWatcher_ExcelToolTipWindowChanged;
46+
}
47+
48+
// Runs on our automation thread
49+
void _windowWatcher_ExcelToolTipWindowChanged(object sender, WindowWatcher.WindowChangedEventArgs e)
50+
{
51+
switch (e.Type)
52+
{
53+
case WindowWatcher.WindowChangedEventArgs.ChangeType.Show:
54+
if (_toolTips.Add(e.WindowHandle))
55+
ToolTipChanged?.Invoke(this, new ToolTipChangeEventArgs(ToolTipChangeType.Show, e.WindowHandle));
56+
break;
57+
case WindowWatcher.WindowChangedEventArgs.ChangeType.Hide:
58+
case WindowWatcher.WindowChangedEventArgs.ChangeType.Destroy:
59+
if (_toolTips.Remove(e.WindowHandle))
60+
ToolTipChanged?.Invoke(this, new ToolTipChangeEventArgs(ToolTipChangeType.Hide, e.WindowHandle));
61+
break;
62+
case WindowWatcher.WindowChangedEventArgs.ChangeType.Create:
63+
case WindowWatcher.WindowChangedEventArgs.ChangeType.Focus:
64+
case WindowWatcher.WindowChangedEventArgs.ChangeType.Unfocus:
65+
default:
66+
// Ignoring these....
67+
break;
68+
}
69+
}
70+
71+
public void Dispose()
72+
{
73+
Logger.WindowWatcher.Info($"ExcelToolTip Dispose Begin");
74+
_windowWatcher.ExcelToolTipWindowChanged -= _windowWatcher_ExcelToolTipWindowChanged;
75+
_windowWatcher = null;
76+
77+
//_syncContextAuto.Send(delegate
78+
//{
79+
// Debug.Print("Disposing ExcelToolTipWatcher - In Automation context");
80+
//}, null);
81+
Logger.WindowWatcher.Info($"ExcelToolTip Dispose End");
82+
}
83+
}
84+
}

Source/ExcelDna.IntelliSense/UIMonitor/PopupListWatcher.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ class PopupListWatcher : IDisposable
1717
// NOTE: Event will always be raised on our automation thread
1818
public event EventHandler SelectedItemChanged; // Either text or location
1919

20-
public bool IsVisible{ get; set; } = false;
21-
public string SelectedItemText { get; set; } = string.Empty;
22-
public Rect SelectedItemBounds { get; set; } = Rect.Empty;
23-
public Rect ListBounds { get; set; } = Rect.Empty;
20+
public bool IsVisible{ get; private set; } = false;
21+
public string SelectedItemText { get; private set; } = string.Empty;
22+
public Rect SelectedItemBounds { get; private set; } = Rect.Empty;
23+
public Rect ListBounds { get; private set; } = Rect.Empty;
2424
public IntPtr PopupListHandle => _hwndPopupList;
2525

2626
SynchronizationContext _syncContextAuto;

0 commit comments

Comments
 (0)