Skip to content

Commit a120074

Browse files
committed
Change ToolTip form and it's handling a bit
Try to understand EXCEL7 window...
1 parent f741a84 commit a120074

File tree

8 files changed

+123
-66
lines changed

8 files changed

+123
-66
lines changed

Source/ExcelDna.IntelliSense.Host/AddIn.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public void AutoOpen()
1919

2020
public void AutoClose()
2121
{
22-
// CONSIDER: Do we implement an explicit call here, or is the AppDomain Unload event good enough
22+
// CONSIDER: Do we implement an explicit call here, or is the AppDomain Unload event good enough?
2323
}
2424
}
2525
}
Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
1-
using System;
2-
using System.ComponentModel;
3-
using ExcelDna.Integration;
1+
#if DEBUG
2+
using System;
3+
using System.ComponentModel;
4+
using ExcelDna.Integration;
45

5-
namespace ExcelDna.CustomAddin
6-
{
7-
// TODO: Remove these functions - they're jsut here for testing...
8-
public class MyFunctions
6+
namespace ExcelDna.CustomAddin
97
{
10-
[ExcelFunction(Description = "A useful test function that adds two numbers, and returns the product.")]
11-
public static double AddThem(
12-
[ExcelArgument(Name = "Augend", Description = "is the first number, to which will be multiplied")] double v1,
13-
[ExcelArgument(Name = "Addend", Description = "is the second number that will be multiplied")] double v2)
8+
// These functions - are just here for testing...
9+
public class MyFunctions
1410
{
15-
return v1 + v2;
16-
}
11+
[ExcelFunction(Description = "A useful test function that adds two numbers, and returns the product.")]
12+
public static double AddThem(
13+
[ExcelArgument(Name = "Augend", Description = "is the first number, to which will be multiplied")] double v1,
14+
[ExcelArgument(Name = "Addend", Description = "is the second number that will be multiplied")] double v2)
15+
{
16+
return v1 + v2;
17+
}
1718

18-
[Description("Test function for the amazing Excel-DNA IntelliSense feature")]
19-
public static string jDummyFunc()
20-
{
21-
return "Howzit !";
22-
}
19+
[Description("Test function for the amazing Excel-DNA IntelliSense feature")]
20+
public static string jDummyFunc()
21+
{
22+
return "Howzit !";
23+
}
2324

25+
}
2426
}
25-
}
27+
#endif

Source/ExcelDna.IntelliSense/FormattedText.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections;
22
using System.Collections.Generic;
33
using System.Drawing;
4+
using System.Linq;
45

56
namespace ExcelDna.IntelliSense
67
{
@@ -28,6 +29,11 @@ IEnumerator IEnumerable.GetEnumerator()
2829
{
2930
return GetEnumerator();
3031
}
32+
33+
public override string ToString()
34+
{
35+
return string.Join("\r\n", _lines.Select(l => l.ToString()));
36+
}
3137
}
3238

3339
class TextLine : IEnumerable<TextRun>
@@ -51,6 +57,11 @@ IEnumerator IEnumerable.GetEnumerator()
5157
{
5258
return GetEnumerator();
5359
}
60+
61+
public override string ToString()
62+
{
63+
return string.Concat(_runs.Select(r => r.Text));
64+
}
5465
}
5566

5667
class TextRun

Source/ExcelDna.IntelliSense/IntelliSenseDisplay.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,14 +189,18 @@ void UpdateMainWindow(IntPtr mainWindow)
189189
// Runs on the main thread
190190
void FormulaEditStart()
191191
{
192+
Debug.Print($"IntelliSenseDisplay - FormulaEditStart");
192193
if (_argumentsToolTip == null)
193194
_argumentsToolTip = new ToolTipForm(_mainWindow);
194195
}
195196

196197
// Runs on the main thread
197198
void FormulaEditEnd()
198199
{
199-
_argumentsToolTip.Hide();
200+
Debug.Print($"IntelliSenseDisplay - FormulaEditEnd");
201+
// _argumentsToolTip.Hide();
202+
_argumentsToolTip.Dispose();
203+
_argumentsToolTip = null;
200204
}
201205

202206
// Runs on the main thread
@@ -227,21 +231,27 @@ void FormulaEditTextChange(string formulaPrefix, Rect editWindowBounds, Rect exc
227231
}
228232

229233
// All other paths, we just clear the box
230-
_argumentsToolTip.Hide();
234+
//_argumentsToolTip.Hide();
235+
_argumentsToolTip.Dispose();
236+
_argumentsToolTip = null;
231237
}
232238

233239

234240
// Runs on the main thread
235241
void FunctionListShow()
236242
{
243+
Debug.Print($"IntelliSenseDisplay - FunctionListShow");
237244
if (_descriptionToolTip == null)
238245
_descriptionToolTip = new ToolTipForm(_mainWindow);
239246
}
240247

241248
// Runs on the main thread
242249
void FunctionListHide()
243250
{
244-
_descriptionToolTip.Hide();
251+
Debug.Print($"IntelliSenseDisplay - FunctionListHide");
252+
//_descriptionToolTip.Hide();
253+
_descriptionToolTip.Dispose();
254+
_descriptionToolTip = null;
245255
}
246256

247257
// Runs on the main thread
@@ -260,7 +270,7 @@ void FunctionListSelectedItemChange(string selectedItemText, Rect selectedItemBo
260270
}
261271
else
262272
{
263-
FunctionListHide();
273+
_descriptionToolTip.Hide();
264274
}
265275
}
266276

Source/ExcelDna.IntelliSense/IntelliSenseServer.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,10 @@ public static RegistrationInfo FromRegistrationString(string registrationString)
235235
Version = parts[2]
236236
};
237237
}
238-
catch
238+
catch (Exception ex)
239239
{
240240
// TODO: Log
241+
Debug.Print($"!!! ERROR: Invalid RegistrationString {registrationString}: {ex.Message}");
241242
return null;
242243
}
243244
}
@@ -380,10 +381,15 @@ static bool IsVersionMatch(string version, string versionPattern)
380381
// returns null if there are none registered
381382
static RegistrationInfo GetHighestPublishedRegistration()
382383
{
383-
return Environment.GetEnvironmentVariable(ServersVariable)
384-
.Split(';')
385-
.Select(str => RegistrationInfo.FromRegistrationString(str))
386-
.Max();
384+
var servers = Environment.GetEnvironmentVariable(ServersVariable);
385+
if (servers == null)
386+
{
387+
Debug.Print("!!! ERROR: ServersVariable not set");
388+
return null;
389+
}
390+
return servers.Split(';')
391+
.Select(str => RegistrationInfo.FromRegistrationString(str))
392+
.Max();
387393
}
388394
#endregion
389395

Source/ExcelDna.IntelliSense/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.0.0.0")]
36-
[assembly: AssemblyFileVersion("1.0.0.0")]
35+
[assembly: AssemblyVersion("0.1.*")]
36+
// [assembly: AssemblyFileVersion("0.0.0.0")]

Source/ExcelDna.IntelliSense/ToolTipForm.cs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
namespace ExcelDna.IntelliSense
1010
{
11+
12+
// TODO: Drop shadow: http://stackoverflow.com/questions/16493698/drop-shadow-on-a-borderless-winform
1113
class ToolTipForm : Form
1214
{
1315
FormattedText _text;
@@ -32,7 +34,7 @@ protected override void DefWndProc(ref Message m)
3234
const int WM_MOUSEACTIVATE = 0x21;
3335
const int MA_NOACTIVATE = 0x0003;
3436

35-
switch(m.Msg)
37+
switch (m.Msg)
3638
{
3739
case WM_MOUSEACTIVATE:
3840
m.Result = (IntPtr)MA_NOACTIVATE;
@@ -59,10 +61,12 @@ public void ShowToolTip(FormattedText text, int left, int top)
5961
_text = text;
6062
if (!Visible)
6163
{
64+
Debug.Print($"Showing ToolTipForm: {_text.ToString()}");
6265
ShowToolTip();
6366
}
6467
else
6568
{
69+
Debug.Print($"Invalidating ToolTipForm: {_text.ToString()}");
6670
Invalidate();
6771
}
6872
Left = left;
@@ -100,26 +104,37 @@ protected override bool ShowWithoutActivation
100104
// }
101105
//}
102106

103-
107+
108+
// Sometimes has Invalid Handle error when calling base.CreateParams (called from Invalidate() for some reason)
109+
CreateParams _createParams;
104110
protected override CreateParams CreateParams
105111
{
106112
get
107113
{
108-
const int CS_DROPSHADOW = 0x00020000;
109-
const int WS_CHILD = 0x40000000;
110-
const int WS_EX_TOOLWINDOW = 0x00000080;
111-
const int WS_EX_NOACTIVATE = 0x08000000;
112-
// NOTE: I've seen exception with invalid handle in the base.CreateParams call here...
113-
CreateParams baseParams = base.CreateParams;
114-
baseParams.ClassStyle |= CS_DROPSHADOW;
115-
baseParams.Style |= WS_CHILD;
116-
baseParams.ExStyle |= ( WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW );
117-
return baseParams;
114+
//if (_createParams == null)
115+
{
116+
const int CS_DROPSHADOW = 0x00020000;
117+
const int WS_CHILD = 0x40000000;
118+
const int WS_EX_TOOLWINDOW = 0x00000080;
119+
const int WS_EX_NOACTIVATE = 0x08000000;
120+
// NOTE: I've seen exception with invalid handle in the base.CreateParams call here...
121+
_createParams = base.CreateParams;
122+
_createParams.ClassStyle |= CS_DROPSHADOW;
123+
// baseParams.Style |= WS_CHILD;
124+
_createParams.ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW);
125+
}
126+
return _createParams;
118127
}
119128
}
120129

130+
protected override void OnHandleDestroyed(EventArgs e)
131+
{
132+
base.OnHandleDestroyed(e);
133+
}
134+
121135
protected override void OnPaint(PaintEventArgs e)
122136
{
137+
Debug.Print($"Painting ToolTipForm: {_text.ToString()}");
123138
const int leftPadding = 3;
124139
const int linePadding = 2;
125140
const int widthPadding = 10;
@@ -233,6 +248,8 @@ void InitializeComponent()
233248

234249
}
235250

251+
252+
236253
class Win32Window : IWin32Window
237254
{
238255
public IntPtr Handle

Source/ExcelDna.IntelliSense/Watchers.cs

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ void _windowStateChangeHook_WinEventReceived(object sender, WinEventHook.WinEven
104104
switch (className)
105105
{
106106
case _mainWindowClass:
107+
case _mainWindowClass2:
107108
if (e.EventType == WinEventHook.WinEvent.EVENT_OBJECT_CREATE ||
108109
e.EventType == WinEventHook.WinEvent.EVENT_OBJECT_DESTROY ||
109110
e.EventType == WinEventHook.WinEvent.EVENT_OBJECT_SHOW ||
@@ -205,6 +206,7 @@ void _windowStateChangeHook_WinEventReceived(object sender, WinEventHook.WinEven
205206
}
206207
}
207208

209+
// Runs on our automation thread
208210
void UpdateMainWindow(IntPtr hWnd)
209211
{
210212
if (MainWindow != hWnd)
@@ -218,37 +220,46 @@ void UpdateMainWindow(IntPtr hWnd)
218220
{
219221
// Either fresh window, or children not yet set up
220222

221-
// Search for formulaBar
222-
// I've seen ElementNotAvailbleException here during shutdown
223-
AutomationElement mainWindow = AutomationElement.FromHandle(hWnd);
223+
//try // Anything can go wrong here, e.g. we're shutting down on the main thread
224+
//{
225+
226+
// Search for formulaBar
227+
228+
AutomationElement mainWindow = AutomationElement.FromHandle(hWnd);
224229
#if DEBUG
225-
var mainChildren = mainWindow.FindAll(TreeScope.Children, Condition.TrueCondition);
226-
foreach (AutomationElement child in mainChildren)
227-
{
228-
var hWndChild = (IntPtr)(int)child.GetCurrentPropertyValue(AutomationElement.NativeWindowHandleProperty);
229-
var classChild = (string)child.GetCurrentPropertyValue(AutomationElement.ClassNameProperty);
230-
// Debug.Print($"Child: {hWndChild}, Class: {classChild}");
231-
}
230+
var mainChildren = mainWindow.FindAll(TreeScope.Children, Condition.TrueCondition);
231+
foreach (AutomationElement child in mainChildren)
232+
{
233+
var hWndChild = (IntPtr)(int)child.GetCurrentPropertyValue(AutomationElement.NativeWindowHandleProperty);
234+
var classChild = (string)child.GetCurrentPropertyValue(AutomationElement.ClassNameProperty);
235+
// Debug.Print($"Child: {hWndChild}, Class: {classChild}");
236+
}
232237
#endif
233-
AutomationElement formulaBar = mainWindow.FindFirst(TreeScope.Children,
234-
new PropertyCondition(AutomationElement.ClassNameProperty, _formulaBarClass));
235-
if (formulaBar != null)
236-
{
237-
FormulaBarWindow = (IntPtr)(int)formulaBar.GetCurrentPropertyValue(AutomationElement.NativeWindowHandleProperty);
238+
AutomationElement formulaBar = mainWindow.FindFirst(TreeScope.Children,
239+
new PropertyCondition(AutomationElement.ClassNameProperty, _formulaBarClass));
240+
if (formulaBar != null)
241+
{
242+
FormulaBarWindow = (IntPtr)(int)formulaBar.GetCurrentPropertyValue(AutomationElement.NativeWindowHandleProperty);
238243

239-
// CONSIDER:
240-
// Watch WindowClose event for MainWindow?
244+
// CONSIDER:
245+
// Watch WindowClose event for MainWindow?
241246

242-
FormulaBarWindowChanged?.Invoke(this, EventArgs.Empty);
243-
}
244-
else
245-
{
246-
// Debug.Print("Could not get FormulaBar!");
247-
}
247+
FormulaBarWindowChanged?.Invoke(this, EventArgs.Empty);
248+
}
249+
else
250+
{
251+
// Debug.Print("Could not get FormulaBar!");
252+
}
253+
//}
254+
//catch (Exception ex)
255+
//{
256+
257+
//}
248258
}
249259
}
250260

251261
const string _mainWindowClass = "XLMAIN";
262+
const string _mainWindowClass2 = "EXCEL7"; // What / when ????????
252263
const string _formulaBarClass = "EXCEL<";
253264
const string _inCellEditClass = "EXCEL6";
254265
const string _popupListClass = "__XLACOOUTER";

0 commit comments

Comments
 (0)