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
6 changes: 4 additions & 2 deletions RetailCoder.VBE/Common/RubberduckHooks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public class RubberduckHooks : IRubberduckHooks
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
private readonly User32.WndProc _newWndProc;
private RawInput _rawinput;
private IRawDevice _kb;
private IRawDevice _mouse;
private RawKeyboard _kb;
private RawMouse _mouse;
private readonly IGeneralConfigService _config;
private readonly IEnumerable<CommandBase> _commands;
private readonly IList<IAttachable> _hooks = new List<IAttachable>();
Expand Down Expand Up @@ -186,6 +186,8 @@ public void Dispose()
{
Detach();
User32.SetWindowLong(_mainWindowHandle, (int)WindowLongFlags.GWL_WNDPROC, _oldWndProc);
_mouse.RawMouseInputReceived -= Mouse_RawMouseInputReceived;
_kb.RawKeyInputReceived -= Keyboard_RawKeyboardInputReceived;
}

private IntPtr WindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
Expand Down
10 changes: 10 additions & 0 deletions RetailCoder.VBE/Common/WinAPI/RawKeyboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,15 @@ private int VirtualKeyCorrection(int virtualKey, bool isE0BitSet, int makeCode,

return correctedVKey;
}

~RawKeyboard()
{
var rid = new RawInputDevice[1];
rid[0].UsagePage = HidUsagePage.GENERIC;
rid[0].Usage = HidUsage.Mouse;
rid[0].Flags = (RawInputDeviceFlags.REMOVE);
rid[0].Target = IntPtr.Zero;
User32.RegisterRawInputDevices(rid, (uint) rid.Length, (uint) Marshal.SizeOf(rid[0]));
}
}
}
10 changes: 10 additions & 0 deletions RetailCoder.VBE/Common/WinAPI/RawMouse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,15 @@ public void ProcessRawInput(InputData _rawBuffer)
RawMouseInputReceived(this, args);
}
}

~RawMouse()
{
var rid = new RawInputDevice[1];
rid[0].UsagePage = HidUsagePage.GENERIC;
rid[0].Usage = HidUsage.Mouse;
rid[0].Flags = (RawInputDeviceFlags.REMOVE);
rid[0].Target = IntPtr.Zero;
User32.RegisterRawInputDevices(rid, (uint) rid.Length, (uint) Marshal.SizeOf(rid[0]));
}
}
}
22 changes: 21 additions & 1 deletion RetailCoder.VBE/Common/WinAPI/User32.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Rubberduck.Common.WinAPI
{
Expand Down Expand Up @@ -69,7 +70,7 @@ public static class User32
/// <returns>If the function succeeds, the return value is the number of characters copied to the buffer, not including the terminating null character.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.</returns>
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int GetClassName(IntPtr hWnd, string lpClassName, int nMaxCount);
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

/// <summary>
/// Retrieves the identifier of the thread that created the specified window and, optionally,
Expand Down Expand Up @@ -183,6 +184,10 @@ public static class User32
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr SendMessage(IntPtr hWnd, WM msg, IntPtr wParam, IntPtr lParam);

public delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);
[DllImport("user32.dll")]
public static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);

/// <summary>
/// A helper function that returns <c>true</c> when the specified handle is that of the foreground window.
/// </summary>
Expand All @@ -198,5 +203,20 @@ public static bool IsVbeWindowActive(IntPtr mainWindowHandle)

return (IntPtr)hThread == (IntPtr)vbeThread;
}

public enum WindowType
{
Indeterminate,
VbaWindow,
DesignerWindow
}

public static WindowType ToWindowType(this IntPtr hwnd)
{
var name = new StringBuilder(128);
GetClassName(hwnd, name, name.Capacity);
WindowType id;
return Enum.TryParse(name.ToString(), out id) ? id : WindowType.Indeterminate;
}
}
}
4 changes: 4 additions & 0 deletions RetailCoder.VBE/Common/WinAPI/WM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,10 @@ public enum WM : uint
/// Private message to signal focus set/lost for a DockableWindowHost. Set wParam to the DockableWindowHost hWnd, lParam to zero for lost focus, non-zero for gained focus.
/// </summary>
RUBBERDUCK_CHILD_FOCUS = USER + 0x0F00,
/// <summary>
/// Private message to signal focus RD shutdown. No parameters.
/// </summary>
RUBBERDUCK_SINKING = USER + 0x0D1E,

/// <summary>
/// The accessibility state has changed.
Expand Down
17 changes: 13 additions & 4 deletions RetailCoder.VBE/Extension.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Extensibility;
using System.Text;
using Extensibility;
using Ninject;
using Ninject.Extensions.Factory;
using Rubberduck.Common.WinAPI;
using Rubberduck.Root;
using Rubberduck.UI;
using System;
Expand Down Expand Up @@ -53,7 +55,7 @@ public void OnConnection(object Application, ext_ConnectMode ConnectMode, object
{
var vbe = (Microsoft.Vbe.Interop.VBE) Application;
_ide = new VBEditor.SafeComWrappers.VBA.VBE(vbe);

var addin = (Microsoft.Vbe.Interop.AddIn)AddInInst;
_addin = new VBEditor.SafeComWrappers.VBA.AddIn(addin) { Object = this };
}
Expand Down Expand Up @@ -104,12 +106,13 @@ public void OnStartupComplete(ref Array custom)
public void OnBeginShutdown(ref Array custom)
{
_isBeginShutdownExecuted = true;
User32.EnumChildWindows(_ide.MainWindow.Handle(), EnumCallback, new IntPtr(0));
ShutdownAddIn();
}

// ReSharper disable InconsistentNaming
public void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom)
{
{
switch (RemoveMode)
{
case ext_DisconnectMode.ext_dm_UserClosed:
Expand Down Expand Up @@ -213,8 +216,14 @@ private void ShutdownAddIn()
{
_logger.Error(e);
}

GC.WaitForPendingFinalizers();
_isInitialized = false;
}

private static int EnumCallback(IntPtr hwnd, IntPtr lparam)
{
User32.SendMessage(hwnd, WM.RUBBERDUCK_SINKING, IntPtr.Zero, IntPtr.Zero);
return 1;
}
}
}
13 changes: 9 additions & 4 deletions RetailCoder.VBE/UI/DockableWindowHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ public SubClassingWindow(IntPtr handle, IntPtr vbeHwnd)

protected override void WndProc(ref Message msg)
{
var closing = false;
switch ((uint)msg.Msg)
{
case (uint)WM.SIZE:
Expand All @@ -145,14 +146,18 @@ protected override void WndProc(ref Message msg)
case (uint)WM.KILLFOCUS:
User32.SendMessage(_vbeHwnd, WM.RUBBERDUCK_CHILD_FOCUS, Handle, IntPtr.Zero);
break;
case (uint)WM.RUBBERDUCK_SINKING:
closing = true;
break;
}
base.WndProc(ref msg);
if (closing) ReleaseHandle();
}

~SubClassingWindow()
{
ReleaseHandle();
}
//~SubClassingWindow()
//{
// ReleaseHandle();
//}
}
}
}
12 changes: 11 additions & 1 deletion Rubberduck.VBEEditor/SafeComWrappers/VBA/VBE.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,17 @@ public ICommandBars CommandBars

public IWindow MainWindow
{
get { return new Window(IsWrappingNullReference ? null : Target.MainWindow); }
get
{
try
{
return new Window(IsWrappingNullReference ? null : Target.MainWindow);
}
catch (InvalidComObjectException ex)
{
return null;
}
}
}

public IVBComponent SelectedVBComponent
Expand Down