Skip to content

Commit 92d4961

Browse files
authored
Merge pull request #2713 from comintern/next
Status event tweaks, bug fixes.
2 parents ed27dce + eb45a04 commit 92d4961

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

Rubberduck.VBEEditor/Events/VBENativeServices.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,13 @@ public static void VbeEventCallback(IntPtr hWinEventHook, uint eventType, IntPtr
7373
{
7474
OnSelectionChanged(hwnd);
7575
}
76-
else if (idObject == (int)ObjId.Window &&
77-
(eventType == (uint)WinEvent.ObjectCreate || eventType == (uint)WinEvent.ObjectDestroy) &&
78-
hwnd.ToWindowType() != WindowType.Indeterminate)
76+
else if (idObject == (int)ObjId.Window && (eventType == (uint)WinEvent.ObjectCreate || eventType == (uint)WinEvent.ObjectDestroy))
7977
{
78+
var type = hwnd.ToWindowType();
79+
if (type != WindowType.DesignerWindow && type != WindowType.VbaWindow)
80+
{
81+
return;
82+
}
8083
if (eventType == (uint) WinEvent.ObjectCreate)
8184
{
8285
AttachWindow(hwnd);
@@ -90,7 +93,7 @@ public static void VbeEventCallback(IntPtr hWinEventHook, uint eventType, IntPtr
9093
{
9194
//Test to see if it was a selection change in the project window.
9295
var parent = User32.GetParent(hwnd);
93-
if (parent != IntPtr.Zero && parent.ToWindowType() == WindowType.Project)
96+
if (parent != IntPtr.Zero && parent.ToWindowType() == WindowType.Project && hwnd == User32.GetFocus())
9497
{
9598
FocusDispatcher(_vbe, new WindowChangedEventArgs(parent, null, null, FocusType.ChildFocus));
9699
}

Rubberduck.VBEEditor/WindowsApi/SubclassingWindow.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Concurrent;
32
using System.Diagnostics;
43
using System.Runtime.InteropServices;
54
using Rubberduck.Common.WinAPI;
@@ -12,6 +11,7 @@ public abstract class SubclassingWindow : IDisposable
1211
private readonly IntPtr _hwnd;
1312
private readonly SubClassCallback _wndProc;
1413
private bool _listening;
14+
private GCHandle _thisHandle;
1515

1616
private readonly object _subclassLock = new object();
1717

@@ -43,7 +43,7 @@ protected SubclassingWindow(IntPtr subclassId, IntPtr hWnd)
4343
public void Dispose()
4444
{
4545
ReleaseHandle();
46-
GC.SuppressFinalize(this);
46+
//GC.SuppressFinalize(this);
4747
}
4848

4949
private void AssignHandle()
@@ -55,6 +55,11 @@ private void AssignHandle()
5555
{
5656
throw new Exception("SetWindowSubClass Failed");
5757
}
58+
//DO NOT REMOVE THIS CALL. Dockable windows are instantiated by the VBE, not directly by RD. On top of that,
59+
//since we have to inherit from UserControl we don't have to keep handling window messages until the VBE gets
60+
//around to destroying the control's host or it results in an access violation when the base class is disposed.
61+
//We need to manually call base.Dispose() ONLY in response to a WM_DESTROY message.
62+
_thisHandle = GCHandle.Alloc(this, GCHandleType.Normal);
5863
_listening = true;
5964
}
6065
}
@@ -85,10 +90,10 @@ public virtual int SubClassProc(IntPtr hWnd, IntPtr msg, IntPtr wParam, IntPtr l
8590
}
8691

8792
Debug.Assert(IsWindow(_hwnd));
88-
//TODO: This should change to WM.DESTROY once subclassing\hooking consolidation is complete.
89-
if ((uint)msg == (uint)WM.RUBBERDUCK_SINKING)
93+
if ((uint)msg == (uint)WM.RUBBERDUCK_SINKING || (uint)msg == (uint)WM.DESTROY)
9094
{
9195
ReleaseHandle();
96+
_thisHandle.Free();
9297
}
9398
return DefSubclassProc(hWnd, msg, wParam, lParam);
9499
}

Rubberduck.VBEEditor/WindowsApi/User32.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ public static class User32
5656
[DllImport("user32.dll")]
5757
public static extern IntPtr GetForegroundWindow();
5858

59+
[DllImport("user32.dll")]
60+
public static extern IntPtr GetActiveWindow();
61+
62+
[DllImport("user32.dll")]
63+
public static extern IntPtr GetFocus();
64+
5965
/// <summary>
6066
/// Gets the underlying class name for a window handle.
6167
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms633582(v=vs.85).aspx

0 commit comments

Comments
 (0)