Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions Rubberduck.VBEEditor/Events/VBENativeServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,13 @@ public static void VbeEventCallback(IntPtr hWinEventHook, uint eventType, IntPtr
{
OnSelectionChanged(hwnd);
}
else if (idObject == (int)ObjId.Window &&
(eventType == (uint)WinEvent.ObjectCreate || eventType == (uint)WinEvent.ObjectDestroy) &&
hwnd.ToWindowType() != WindowType.Indeterminate)
else if (idObject == (int)ObjId.Window && (eventType == (uint)WinEvent.ObjectCreate || eventType == (uint)WinEvent.ObjectDestroy))
{
var type = hwnd.ToWindowType();
if (type != WindowType.DesignerWindow && type != WindowType.VbaWindow)
{
return;
}
if (eventType == (uint) WinEvent.ObjectCreate)
{
AttachWindow(hwnd);
Expand All @@ -90,7 +93,7 @@ public static void VbeEventCallback(IntPtr hWinEventHook, uint eventType, IntPtr
{
//Test to see if it was a selection change in the project window.
var parent = User32.GetParent(hwnd);
if (parent != IntPtr.Zero && parent.ToWindowType() == WindowType.Project)
if (parent != IntPtr.Zero && parent.ToWindowType() == WindowType.Project && hwnd == User32.GetFocus())
{
FocusDispatcher(_vbe, new WindowChangedEventArgs(parent, null, null, FocusType.ChildFocus));
}
Expand Down
13 changes: 9 additions & 4 deletions Rubberduck.VBEEditor/WindowsApi/SubclassingWindow.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Rubberduck.Common.WinAPI;
Expand All @@ -12,6 +11,7 @@ public abstract class SubclassingWindow : IDisposable
private readonly IntPtr _hwnd;
private readonly SubClassCallback _wndProc;
private bool _listening;
private GCHandle _thisHandle;

private readonly object _subclassLock = new object();

Expand Down Expand Up @@ -43,7 +43,7 @@ protected SubclassingWindow(IntPtr subclassId, IntPtr hWnd)
public void Dispose()
{
ReleaseHandle();
GC.SuppressFinalize(this);
//GC.SuppressFinalize(this);
}

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

Debug.Assert(IsWindow(_hwnd));
//TODO: This should change to WM.DESTROY once subclassing\hooking consolidation is complete.
if ((uint)msg == (uint)WM.RUBBERDUCK_SINKING)
if ((uint)msg == (uint)WM.RUBBERDUCK_SINKING || (uint)msg == (uint)WM.DESTROY)
{
ReleaseHandle();
_thisHandle.Free();
}
return DefSubclassProc(hWnd, msg, wParam, lParam);
}
Expand Down
6 changes: 6 additions & 0 deletions Rubberduck.VBEEditor/WindowsApi/User32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ public static class User32
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
public static extern IntPtr GetActiveWindow();

[DllImport("user32.dll")]
public static extern IntPtr GetFocus();

/// <summary>
/// Gets the underlying class name for a window handle.
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms633582(v=vs.85).aspx
Expand Down