1- using System ;
1+ using ExcelDna . IntelliSense . Util ;
2+ using System ;
23using System . Diagnostics ;
34using System . Threading ;
45using System . Windows ;
@@ -71,11 +72,15 @@ public IntPtr FormulaEditWindow
7172 readonly SynchronizationContext _syncContextMain ;
7273
7374 readonly WindowWatcher _windowWatcher ; // Passed in
74- WindowLocationWatcher _windowLocationWatcher ; // Managed here
7575
76- IntPtr _hwndFormulaBar ;
77- IntPtr _hwndInCellEdit ;
78- FormulaEditFocus _formulaEditFocus ;
76+ WindowLocationWatcher _windowLocationWatcher ; // Managed here
77+ readonly RenewableDelayExecutor _updateEditStateAfterTimeout ;
78+
79+ IntPtr _hwndFormulaBar ;
80+ IntPtr _hwndInCellEdit ;
81+ FormulaEditFocus _formulaEditFocus ;
82+
83+ const int DelayBeforeStateUpdateMilliseconds = 100 ;
7984
8085 public FormulaEditWatcher ( WindowWatcher windowWatcher , SynchronizationContext syncContextAuto , SynchronizationContext syncContextMain )
8186 {
@@ -84,6 +89,7 @@ public FormulaEditWatcher(WindowWatcher windowWatcher, SynchronizationContext sy
8489 _windowWatcher = windowWatcher ;
8590 _windowWatcher . FormulaBarWindowChanged += _windowWatcher_FormulaBarWindowChanged ;
8691 _windowWatcher . InCellEditWindowChanged += _windowWatcher_InCellEditWindowChanged ;
92+ _updateEditStateAfterTimeout = new RenewableDelayExecutor ( DelayBeforeStateUpdateMilliseconds , ( ) => UpdateEditState ( ) ) ;
8793 }
8894
8995 // Runs on the Automation thread
@@ -95,13 +101,13 @@ void _windowWatcher_FormulaBarWindowChanged(object sender, WindowWatcher.WindowC
95101 if ( e . ObjectId == WindowWatcher . WindowChangedEventArgs . ChangeObjectId . Self )
96102 {
97103 SetEditWindow ( e . WindowHandle , ref _hwndFormulaBar ) ;
98- UpdateEditState ( ) ;
104+ _updateEditStateAfterTimeout . Signal ( ) ;
99105 }
100106 else if ( e . ObjectId == WindowWatcher . WindowChangedEventArgs . ChangeObjectId . Caret )
101107 {
102108 // We expect this on every text change
103109 // NOTE: Not anymore after some Excel / Windows update
104- UpdateEditStateDelayed ( ) ;
110+ _updateEditStateAfterTimeout . Signal ( ) ;
105111 }
106112 else
107113 {
@@ -126,29 +132,29 @@ void _windowWatcher_FormulaBarWindowChanged(object sender, WindowWatcher.WindowC
126132 SetEditWindow ( e . WindowHandle , ref _hwndFormulaBar ) ;
127133 }
128134 _formulaEditFocus = FormulaEditFocus . FormulaBar ;
129- UpdateEditState ( ) ;
135+ _updateEditStateAfterTimeout . Signal ( ) ;
130136 }
131137 break ;
132138 case WindowWatcher . WindowChangedEventArgs . ChangeType . Unfocus :
133139 if ( _formulaEditFocus == FormulaEditFocus . FormulaBar )
134140 {
135141 Logger . WindowWatcher . Verbose ( $ "FormulaEdit - FormulaBar Unfocus") ;
136142 _formulaEditFocus = FormulaEditFocus . None ;
137- UpdateEditState ( ) ;
143+ _updateEditStateAfterTimeout . Signal ( ) ;
138144 }
139145 break ;
140146 case WindowWatcher . WindowChangedEventArgs . ChangeType . Show :
141- Logger . WindowWatcher . Verbose ( $ "FormulaEdit - FormulaBar Show") ;
147+ Logger . WindowWatcher . Verbose ( $ "FormulaEdit - FormulaBar Show") ;
142148 break ;
143149 case WindowWatcher . WindowChangedEventArgs . ChangeType . Hide :
144- Logger . WindowWatcher . Verbose ( $ "FormulaEdit - FormulaBar Hide") ;
150+ Logger . WindowWatcher . Verbose ( $ "FormulaEdit - FormulaBar Hide") ;
145151 break ;
146152 case WindowWatcher . WindowChangedEventArgs . ChangeType . LocationChange :
147153 if ( e . ObjectId == WindowWatcher . WindowChangedEventArgs . ChangeObjectId . Caret )
148154 {
149155 // We expect this on every text change in newer Excel versions
150156 Debug . Print ( $ "-#-#-#- Text Changed ... ") ;
151- UpdateEditStateDelayed ( ) ;
157+ _updateEditStateAfterTimeout . Signal ( ) ;
152158 }
153159 else
154160 {
@@ -172,14 +178,14 @@ void _windowWatcher_InCellEditWindowChanged(object sender, WindowWatcher.WindowC
172178 if ( e . ObjectId == WindowWatcher . WindowChangedEventArgs . ChangeObjectId . Self )
173179 {
174180 SetEditWindow ( e . WindowHandle , ref _hwndInCellEdit ) ;
175- UpdateEditState ( ) ;
181+ _updateEditStateAfterTimeout . Signal ( ) ;
176182 }
177183 else if ( e . ObjectId == WindowWatcher . WindowChangedEventArgs . ChangeObjectId . Caret )
178184 {
179185 // We expect this on every text change
180186 // NOTE: Not anymore after some Excel / Windows update
181187 Debug . Print ( $ "-#-#-#- Text Changed ... ") ;
182- UpdateEditStateDelayed ( ) ;
188+ _updateEditStateAfterTimeout . Signal ( ) ;
183189 }
184190 else
185191 {
@@ -206,15 +212,15 @@ void _windowWatcher_InCellEditWindowChanged(object sender, WindowWatcher.WindowC
206212 Logger . WindowWatcher . Verbose ( $ "FormulaEdit - InCellEdit Focus") ;
207213
208214 _formulaEditFocus = FormulaEditFocus . InCellEdit ;
209- UpdateEditState ( ) ;
215+ _updateEditStateAfterTimeout . Signal ( ) ;
210216 }
211217 break ;
212218 case WindowWatcher . WindowChangedEventArgs . ChangeType . Unfocus :
213219 if ( _formulaEditFocus == FormulaEditFocus . InCellEdit )
214220 {
215221 Logger . WindowWatcher . Verbose ( $ "FormulaEdit - InCellEdit Unfocus") ;
216222 _formulaEditFocus = FormulaEditFocus . None ;
217- UpdateEditState ( ) ;
223+ _updateEditStateAfterTimeout . Signal ( ) ;
218224 }
219225 break ;
220226 case WindowWatcher . WindowChangedEventArgs . ChangeType . Show :
@@ -228,7 +234,7 @@ void _windowWatcher_InCellEditWindowChanged(object sender, WindowWatcher.WindowC
228234 {
229235 // We expect this on every text change in newer Excel versions
230236 Debug . Print ( $ "-#-#-#- Text Changed ... ") ;
231- UpdateEditStateDelayed ( ) ;
237+ _updateEditStateAfterTimeout . Signal ( ) ;
232238 }
233239 else
234240 {
@@ -313,22 +319,20 @@ void _windowLocationWatcher_LocationChanged(object sender, EventArgs e)
313319 // UpdateFormula(textChangedOnly: true);
314320 //}
315321
316- // TODO: Get rid of this somehow - added to make the mouse clicks in the in-cell editing work, by delaying the call to the PenHelper
317- void UpdateEditStateDelayed ( )
322+ void UpdateEditState ( bool moveOnly = false )
318323 {
319- _syncContextAuto . Post ( _ =>
320- {
321- Thread . Sleep ( 100 ) ;
322- UpdateEditState ( ) ;
323- } , null ) ;
324+ // Switches to our Main UI thread, updates current state and raises StateChanged event
325+ _syncContextMain . Post ( _ =>
326+ {
327+ UpdateEditStateImpl ( moveOnly ) ;
328+ } , null ) ;
324329 }
325330
326- // Switches to our Automation thread, updates current state and raises StateChanged event
327- void UpdateEditState ( bool moveOnly = false )
331+ void UpdateEditStateImpl ( bool moveOnly = false )
328332 {
329333 Logger . WindowWatcher . Verbose ( $ "> FormulaEdit UpdateEditState - Thread { Thread . CurrentThread . ManagedThreadId } ") ;
330334 Logger . WindowWatcher . Verbose ( $ "FormulaEdit UpdateEditState - Focus: { _formulaEditFocus } Window: { ( _formulaEditFocus == FormulaEditFocus . FormulaBar ? _hwndFormulaBar : _hwndInCellEdit ) } ") ;
331-
335+
332336 IntPtr hwnd = IntPtr . Zero ;
333337 bool prefixChanged = false ;
334338 if ( _formulaEditFocus == FormulaEditFocus . FormulaBar )
@@ -410,6 +414,9 @@ public void Dispose()
410414 Debug . Assert ( Thread . CurrentThread . ManagedThreadId == 1 ) ;
411415
412416 Logger . WindowWatcher . Verbose ( "FormulaEdit Dispose Begin" ) ;
417+
418+ _updateEditStateAfterTimeout . Dispose ( ) ;
419+
413420 _windowWatcher . FormulaBarWindowChanged -= _windowWatcher_FormulaBarWindowChanged ;
414421 _windowWatcher . InCellEditWindowChanged -= _windowWatcher_InCellEditWindowChanged ;
415422
@@ -419,7 +426,8 @@ public void Dispose()
419426 {
420427 tempWatcher . Dispose ( ) ;
421428 }
429+
422430 Logger . WindowWatcher . Verbose ( "FormulaEdit Dispose End" ) ;
423431 }
424432 }
425- }
433+ }
0 commit comments