1- using System ;
1+ using ExcelDna . Integration ;
2+ using System ;
23using System . Diagnostics ;
34using System . Runtime . ExceptionServices ;
45using System . Runtime . InteropServices ;
56
67namespace ExcelDna . IntelliSense
78{
8- class XlCall
9+ class XlCallHelper
910 {
10- [ DllImport ( "XLCALL32.DLL" ) ]
11- static extern int LPenHelper ( int wCode , ref FmlaInfo fmlaInfo ) ; // 'long' return value means 'int' in C (so why different?)
12-
13- const int xlSpecial = 0x4000 ;
14- const int xlGetFmlaInfo = ( 14 | xlSpecial ) ;
15-
16- // Edit Modes
17- const int xlModeReady = 0 ; // not in edit mode
18- const int xlModeEnter = 1 ; // enter mode
19- const int xlModeEdit = 2 ; // edit mode
20- const int xlModePoint = 4 ; // point mode
21-
22- [ StructLayout ( LayoutKind . Sequential ) ]
23- struct FmlaInfo
24- {
25- public int wPointMode ; // current edit mode. 0 => rest of struct undefined
26- public int cch ; // count of characters in formula
27- public IntPtr lpch ; // pointer to formula characters. READ ONLY!!!
28- public int ichFirst ; // char offset to start of selection
29- public int ichLast ; // char offset to end of selection (may be > cch)
30- public int ichCaret ; // char offset to blinking caret
31- }
32-
3311 // This give a global mechanism to indicate shutdown as early as possible
3412 // Maybe helps with debugging...
3513 static bool _shutdownStarted = false ;
@@ -38,21 +16,17 @@ public static void ShutdownStarted()
3816 _shutdownStarted = true ;
3917 }
4018
19+ // This call must be made on the main thread
4120 // Returns null if not in edit mode
42- // TODO: What do we know about the threading constraints on this call?
43-
44- // NOTE: I've only seen this crash during shutdown
45- // We enable handling of the AccessViolation as best we can
46- [ HandleProcessCorruptedStateExceptions ]
4721 public static string GetFormulaEditPrefix ( )
4822 {
4923 if ( _shutdownStarted )
5024 return null ;
5125
5226 try
5327 {
54- var fmlaInfo = new FmlaInfo ( ) ;
55- var result = LPenHelper ( xlGetFmlaInfo , ref fmlaInfo ) ;
28+ var fmlaInfo = new XlCall . FmlaInfo ( ) ;
29+ var result = XlCall . PenHelper ( XlCall . xlGetFmlaInfo , ref fmlaInfo ) ;
5630 if ( result != 0 )
5731 {
5832 Logger . WindowWatcher . Warn ( $ "LPenHelper Failed. Result: { result } ") ;
@@ -62,7 +36,7 @@ public static string GetFormulaEditPrefix()
6236 // throw new InvalidOperationException("LPenHelper Failed. Result: " + result);
6337 return null ;
6438 }
65- if ( fmlaInfo . wPointMode == xlModeReady )
39+ if ( fmlaInfo . wPointMode == XlCall . xlModeReady )
6640 {
6741 Logger . WindowWatcher . Verbose ( $ "LPenHelper PointMode Ready") ;
6842 return null ;
@@ -76,11 +50,6 @@ public static string GetFormulaEditPrefix()
7650 var prefixLen = Math . Min ( Math . Max ( fmlaInfo . ichCaret , fmlaInfo . ichLast ) , fmlaInfo . cch ) ; // I've never seen ichLast > cch !?
7751 return Marshal . PtrToStringUni ( fmlaInfo . lpch , prefixLen ) ;
7852 }
79- catch ( AccessViolationException )
80- {
81- Logger . WindowWatcher . Warn ( "LPenHelper - Access Violation!" ) ;
82- return null ;
83- }
8453 catch ( Exception ex )
8554 {
8655 // Some unexpected error - for now we log as an error and re-throw
0 commit comments