Skip to content

Commit 1a34d93

Browse files
committed
Force focus on setting the active code pane
For some reason the VBE dis not consistently move focus to the active code pane when activating a code pane. Accordingly, the selection was not visible to the user. This reintroduces forcing the focus, but on code pane activation instead of setting the selection.
1 parent eb592a1 commit 1a34d93

File tree

3 files changed

+72
-6
lines changed
  • Rubberduck.VBEEditor/SafeComWrappers/VB/Abstract
  • Rubberduck.VBEditor.VB6/SafeComWrappers/VB
  • Rubberduck.VBEditor.VBA/SafeComWrappers/VB

3 files changed

+72
-6
lines changed

Rubberduck.VBEEditor/SafeComWrappers/VB/Abstract/ICodeModule.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ public interface ICodeModule : ISafeComWrapper, IEquatable<ICodeModule>
66
{
77
IVBE VBE { get; }
88
IVBComponent Parent { get; }
9+
/// <summary>
10+
/// Returns the code pane associated with the cod module.
11+
/// Accessing this property will open the code pane if it is not open already.
12+
/// </summary>
913
ICodePane CodePane { get; }
1014
int CountOfDeclarationLines { get; }
1115
int CountOfLines { get; }

Rubberduck.VBEditor.VB6/SafeComWrappers/VB/VBE.cs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,42 @@ public VBE(VB.VBE target, bool rewrapping = false)
2929
public ICodePane ActiveCodePane
3030
{
3131
get => new CodePane(IsWrappingNullReference ? null : Target.ActiveCodePane);
32-
set
32+
set => SetActiveCodePane(value);
33+
}
34+
35+
private void SetActiveCodePane(ICodePane codePane)
36+
{
37+
if (IsWrappingNullReference || !(codePane is CodePane pane))
3338
{
34-
if (!IsWrappingNullReference)
39+
return;
40+
}
41+
42+
Target.ActiveCodePane = pane.Target;
43+
ForceFocus(codePane);
44+
}
45+
46+
private void ForceFocus(ICodePane codePane)
47+
{
48+
if (codePane.IsWrappingNullReference)
49+
{
50+
return;
51+
}
52+
53+
codePane.Show();
54+
55+
using (var mainWindow = MainWindow)
56+
using (var window = codePane.Window)
57+
{
58+
var mainWindowHandle = mainWindow.Handle();
59+
var handle = mainWindow.Handle().FindChildWindow(window.Caption);
60+
61+
if (handle != IntPtr.Zero)
62+
{
63+
NativeMethods.ActivateWindow(handle, mainWindowHandle);
64+
}
65+
else
3566
{
36-
Target.ActiveCodePane = (VB.CodePane)value.Target;
67+
_logger.Debug("VBE.ForceFocus() failed to get a handle on the MainWindow.");
3768
}
3869
}
3970
}

Rubberduck.VBEditor.VBA/SafeComWrappers/VB/VBE.cs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,42 @@ public VBE(VB.VBE target, bool rewrapping = false)
3131
public ICodePane ActiveCodePane
3232
{
3333
get => new CodePane(IsWrappingNullReference ? null : Target.ActiveCodePane);
34-
set
34+
set => SetActiveCodePane(value);
35+
}
36+
37+
private void SetActiveCodePane(ICodePane codePane)
38+
{
39+
if (IsWrappingNullReference || !(codePane is CodePane pane))
3540
{
36-
if (!IsWrappingNullReference)
41+
return;
42+
}
43+
44+
Target.ActiveCodePane = pane.Target;
45+
ForceFocus(codePane);
46+
}
47+
48+
private void ForceFocus(ICodePane codePane)
49+
{
50+
if (codePane.IsWrappingNullReference)
51+
{
52+
return;
53+
}
54+
55+
codePane.Show();
56+
57+
using (var mainWindow = MainWindow)
58+
using (var window = codePane.Window)
59+
{
60+
var mainWindowHandle = mainWindow.Handle();
61+
var handle = mainWindow.Handle().FindChildWindow(window.Caption);
62+
63+
if (handle != IntPtr.Zero)
64+
{
65+
NativeMethods.ActivateWindow(handle, mainWindowHandle);
66+
}
67+
else
3768
{
38-
Target.ActiveCodePane = (VB.CodePane)value.Target;
69+
_logger.Debug("VBE.ForceFocus() failed to get a handle on the MainWindow.");
3970
}
4071
}
4172
}

0 commit comments

Comments
 (0)