@@ -117,11 +117,11 @@ internal WindowChangedEventArgs(IntPtr windowHandle, WinEventHook.WinEvent winEv
117117 const string _nuiDialogClass = "NUIDialog" ;
118118 const string _selectDataSourceTitle = "Select Data Source" ; // TODO: How does localization work?
119119
120- private readonly SynchronizationContext _syncContextAuto ;
121- private readonly SynchronizationContext _syncContextMain ;
120+ readonly SynchronizationContext _syncContextAuto ;
121+ readonly SynchronizationContext _syncContextMain ;
122122
123123 List < WinEventHook > _windowStateChangeHooks = new List < WinEventHook > ( ) ;
124- private WinEventHook _locationChangeEventHook ;
124+ WinEventHook _locationChangeEventHook ;
125125
126126 // These track keyboard focus for Windows in the Excel process
127127 // Used to synthesize the 'Unfocus' change events
@@ -162,8 +162,6 @@ public WindowWatcher(SynchronizationContext syncContextAuto, SynchronizationCont
162162 // EVENT_OBJECT_SELECTIONREMOVE
163163 // EVENT_OBJECT_SELECTIONWITHIN
164164 // EVENT_OBJECT_STATECHANGE (0x800A = 32778)
165- // NB: Including the next event 'EVENT_OBJECT_LOCATIONCHANGE (0x800B = 32779)' will cause the Excel main window to lag when dragging.
166- // This drag issue seems to have been introduced with an Office update around November 2022.
167165 _windowStateChangeHooks . Add ( new WinEventHook ( WinEventHook . WinEvent . EVENT_OBJECT_CREATE , WinEventHook . WinEvent . EVENT_OBJECT_STATECHANGE , syncContextAuto , syncContextMain , IntPtr . Zero ) ) ;
168166 _windowStateChangeHooks . Add ( new WinEventHook ( WinEventHook . WinEvent . EVENT_SYSTEM_CAPTURESTART , WinEventHook . WinEvent . EVENT_SYSTEM_CAPTURESTART , syncContextAuto , syncContextMain , IntPtr . Zero ) ) ;
169167
@@ -175,8 +173,12 @@ public WindowWatcher(SynchronizationContext syncContextAuto, SynchronizationCont
175173 SetUpLocationChangeEventListener ( ) ;
176174 }
177175
178- private void SetUpLocationChangeEventListener ( )
176+ void SetUpLocationChangeEventListener ( )
179177 {
178+ // NB: Including the next event 'EVENT_OBJECT_LOCATIONCHANGE (0x800B = 32779)' will cause the Excel main window to lag when dragging.
179+ // This drag issue seems to have been introduced with an Office update around November 2022.
180+ // To workaround this, we unhook from this event upon encountering EVENT_SYSTEM_MOVESIZESTART and then hook again upon encountering
181+ // EVENT_SYSTEM_MOVESIZEEND (see UnhookFromLocationChangeUponDraggingExcelMainWindow).
180182 _locationChangeEventHook = new WinEventHook ( WinEventHook . WinEvent . EVENT_OBJECT_LOCATIONCHANGE , WinEventHook . WinEvent . EVENT_OBJECT_LOCATIONCHANGE , _syncContextAuto , _syncContextMain , IntPtr . Zero ) ;
181183 _locationChangeEventHook . WinEventReceived += _windowStateChangeHook_WinEventReceived ;
182184 }
@@ -228,6 +230,22 @@ bool UpdateFocus(IntPtr windowHandle, string windowClassName)
228230 return true ;
229231 }
230232
233+ // This allows us to temporarily stop listening to EVENT_OBJECT_LOCATIONCHANGE events when the user is dragging the Excel main window.
234+ // Otherwise we are going to bump into https://github.com/Excel-DNA/IntelliSense/issues/123. The rest of the time we need to stay
235+ // hooked to EVENT_OBJECT_LOCATIONCHANGE for IntelliSense to work correctly (see https://github.com/Excel-DNA/IntelliSense/issues/124).
236+ void UnhookFromLocationChangeUponDraggingExcelMainWindow ( WinEventHook . WinEventArgs e )
237+ {
238+ if ( e . EventType == WinEventHook . WinEvent . EVENT_SYSTEM_MOVESIZESTART )
239+ {
240+ _syncContextMain . Post ( _ => _locationChangeEventHook ? . Dispose ( ) , null ) ;
241+ }
242+
243+ if ( e . EventType == WinEventHook . WinEvent . EVENT_SYSTEM_MOVESIZEEND )
244+ {
245+ _syncContextMain . Post ( _ => SetUpLocationChangeEventListener ( ) , null ) ;
246+ }
247+ }
248+
231249 // This runs on the Automation thread, via SyncContextAuto passed in to WinEventHook when we created this WindowWatcher
232250 // CONSIDER: We would be able to run all the watcher updates from WinEvents, including Location and Selection changes,
233251 // but since WinEvents have no hwnd filter, UIAutomation events might be more efficient.
@@ -240,15 +258,7 @@ void _windowStateChangeHook_WinEventReceived(object sender, WinEventHook.WinEven
240258 Debug . Fail ( "WinEvent with window 0!?" ) ;
241259 }
242260
243- if ( e . EventType == WinEventHook . WinEvent . EVENT_SYSTEM_MOVESIZESTART )
244- {
245- _syncContextMain . Post ( _ => _locationChangeEventHook . Dispose ( ) , null ) ;
246- }
247-
248- if ( e . EventType == WinEventHook . WinEvent . EVENT_SYSTEM_MOVESIZEEND )
249- {
250- _syncContextMain . Post ( _ => SetUpLocationChangeEventListener ( ) , null ) ;
251- }
261+ UnhookFromLocationChangeUponDraggingExcelMainWindow ( e ) ;
252262
253263 if ( e . EventType == WinEventHook . WinEvent . EVENT_OBJECT_FOCUS )
254264 {
0 commit comments