Skip to content

Commit a703527

Browse files
authored
Merge pull request #2465 from comintern/next
Fix broken inspection result form captions (plus focus events for DockableToolwindows).
2 parents 69c3587 + f838509 commit a703527

File tree

11 files changed

+282
-125
lines changed

11 files changed

+282
-125
lines changed

RetailCoder.VBE/UI/DockableToolwindowPresenter.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
using System;
2-
using System.Configuration;
32
using System.Runtime.InteropServices;
43
using System.Windows.Forms;
54
using NLog;
65
using Rubberduck.Settings;
76
using Rubberduck.SettingsProvider;
7+
using Rubberduck.VBEditor.Extensions;
88
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
99

1010
namespace Rubberduck.UI
@@ -55,7 +55,7 @@ private IWindow CreateToolWindow(IDockableUserControl control)
5555
{
5656
var info = _vbe.Windows.CreateToolWindow(_addin, _DockableWindowHost.RegisteredProgId, control.Caption, control.ClassId);
5757
_userControlObject = info.UserControl;
58-
toolWindow = info.ToolWindow;
58+
toolWindow = info.ToolWindow;
5959
}
6060
catch (COMException exception)
6161
{
@@ -77,6 +77,9 @@ private IWindow CreateToolWindow(IDockableUserControl control)
7777

7878
EnsureMinimumWindowSize(toolWindow);
7979

80+
//Get the hwnd here - otherwise, FindWindowEx won't find it (because it's hidden).
81+
toolWindow.RealHwnd = toolWindow.ToHwnd();
82+
8083
toolWindow.IsVisible = _settings != null && _settings.IsWindowVisible(this);
8184

8285
userControlHost.AddUserControl(control as UserControl, new IntPtr(_vbe.MainWindow.HWnd));

RetailCoder.VBE/UI/Inspections/InspectionResultsControl.xaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -597,15 +597,15 @@
597597
<controls:LinkButton Margin="4"
598598
Visibility="{Binding CanExecuteQuickFixInModule, Converter={StaticResource BoolToVisibility}}"
599599
Command="{Binding QuickFixInModuleCommand}"
600-
Content="{Resx ResxName=Rubberduck.Inspections.InspectionsUI, Key=QuickFix_ThisModule}" />
600+
Content="{Resx ResxName=Rubberduck.Inspections.Resources.InspectionsUI, Key=QuickFix_ThisModule}" />
601601
<controls:LinkButton Margin="4"
602602
Visibility="{Binding CanExecuteQuickFixInProject, Converter={StaticResource BoolToVisibility}}"
603603
Command="{Binding QuickFixInProjectCommand}"
604-
Content="{Resx ResxName=Rubberduck.Inspections.InspectionsUI, Key=QuickFix_ThisProject}" />
604+
Content="{Resx ResxName=Rubberduck.Inspections.Resources.InspectionsUI, Key=QuickFix_ThisProject}" />
605605
<controls:LinkButton Margin="4"
606606
Visibility="{Binding CanDisableInspection, Converter={StaticResource BoolToVisibility}}"
607607
Command="{Binding DisableInspectionCommand}"
608-
Content="{Resx ResxName=Rubberduck.Inspections.InspectionsUI, Key=DisableThisInspection}" />
608+
Content="{Resx ResxName=Rubberduck.Inspections.Resources.InspectionsUI, Key=DisableThisInspection}" />
609609
</WrapPanel>
610610
</StackPanel>
611611
</Border>

Rubberduck.VBEEditor/Extensions/IDEExtensions.cs

Lines changed: 0 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using Rubberduck.VBEditor.Application;
66
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
77
using Rubberduck.VBEditor.SafeComWrappers.MSForms;
8-
using Exception = System.Exception;
98

109
namespace Rubberduck.VBEditor.Extensions
1110
{
@@ -205,100 +204,4 @@ public static bool HostSupportsUnitTests(this IVBE vbe)
205204
return false;
206205
}
207206
}
208-
209-
public static class VBProjectExtensions
210-
{
211-
/// <summary>
212-
/// Imports all source code files from target directory into project.
213-
/// </summary>
214-
/// <remarks>
215-
/// Only files with extensions "cls", "bas, "frm", and "doccls" are imported.
216-
/// It is the callers responsibility to remove any existing components prior to importing.
217-
/// </remarks>
218-
/// <param name="project"></param>
219-
/// <param name="filePath">Directory path containing the source files.</param>
220-
public static void ImportDocumentTypeSourceFiles(this IVBProject project, string filePath)
221-
{
222-
var dirInfo = new DirectoryInfo(filePath);
223-
224-
var files = dirInfo.EnumerateFiles()
225-
.Where(f => f.Extension == ComponentTypeExtensions.DocClassExtension);
226-
foreach (var file in files)
227-
{
228-
try
229-
{
230-
project.VBComponents.ImportSourceFile(file.FullName);
231-
}
232-
catch (IndexOutOfRangeException) { } // component didn't exist
233-
}
234-
}
235-
236-
public static void LoadAllComponents(this IVBProject project, string filePath)
237-
{
238-
var dirInfo = new DirectoryInfo(filePath);
239-
240-
var files = dirInfo.EnumerateFiles()
241-
.Where(f => f.Extension == ComponentTypeExtensions.StandardExtension ||
242-
f.Extension == ComponentTypeExtensions.ClassExtension ||
243-
f.Extension == ComponentTypeExtensions.DocClassExtension ||
244-
f.Extension == ComponentTypeExtensions.FormExtension
245-
)
246-
.ToList();
247-
248-
var exceptions = new List<Exception>();
249-
250-
foreach (var component in project.VBComponents)
251-
{
252-
try
253-
{
254-
var name = component.Name;
255-
project.VBComponents.RemoveSafely(component);
256-
257-
var file = files.SingleOrDefault(f => f.Name == name + f.Extension);
258-
if (file != null)
259-
{
260-
try
261-
{
262-
project.VBComponents.ImportSourceFile(file.FullName);
263-
}
264-
catch (IndexOutOfRangeException)
265-
{
266-
exceptions.Add(new IndexOutOfRangeException(string.Format(VBEEditorText.NonexistentComponentErrorText, Path.GetFileNameWithoutExtension(file.FullName))));
267-
}
268-
}
269-
}
270-
catch (Exception ex)
271-
{
272-
exceptions.Add(ex);
273-
}
274-
}
275-
276-
foreach (var file in files)
277-
{
278-
try
279-
{
280-
if (project.VBComponents.All(v => v.Name + file.Extension != file.Name))
281-
{
282-
try
283-
{
284-
project.VBComponents.ImportSourceFile(file.FullName);
285-
}
286-
catch (IndexOutOfRangeException)
287-
{
288-
exceptions.Add(new IndexOutOfRangeException(string.Format(VBEEditorText.NonexistentComponentErrorText, Path.GetFileNameWithoutExtension(file.FullName))));
289-
}
290-
}
291-
}
292-
catch (Exception ex)
293-
{
294-
exceptions.Add(ex);
295-
}
296-
}
297-
298-
if (exceptions.Count != 0)
299-
{
300-
throw new AggregateException(string.Empty, exceptions);
301-
}
302-
}
303-
}
304207
}
Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,104 @@
1-
namespace Rubberduck.VBEditor.Extensions
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
6+
7+
namespace Rubberduck.VBEditor.Extensions
28
{
9+
public static class VBProjectExtensions
10+
{
11+
/// <summary>
12+
/// Imports all source code files from target directory into project.
13+
/// </summary>
14+
/// <remarks>
15+
/// Only files with extensions "cls", "bas, "frm", and "doccls" are imported.
16+
/// It is the callers responsibility to remove any existing components prior to importing.
17+
/// </remarks>
18+
/// <param name="project"></param>
19+
/// <param name="filePath">Directory path containing the source files.</param>
20+
public static void ImportDocumentTypeSourceFiles(this IVBProject project, string filePath)
21+
{
22+
var dirInfo = new DirectoryInfo(filePath);
23+
24+
var files = dirInfo.EnumerateFiles()
25+
.Where(f => f.Extension == ComponentTypeExtensions.DocClassExtension);
26+
foreach (var file in files)
27+
{
28+
try
29+
{
30+
project.VBComponents.ImportSourceFile(file.FullName);
31+
}
32+
catch (IndexOutOfRangeException) { } // component didn't exist
33+
}
34+
}
35+
36+
public static void LoadAllComponents(this IVBProject project, string filePath)
37+
{
38+
var dirInfo = new DirectoryInfo(filePath);
39+
40+
var files = dirInfo.EnumerateFiles()
41+
.Where(f => f.Extension == ComponentTypeExtensions.StandardExtension ||
42+
f.Extension == ComponentTypeExtensions.ClassExtension ||
43+
f.Extension == ComponentTypeExtensions.DocClassExtension ||
44+
f.Extension == ComponentTypeExtensions.FormExtension
45+
)
46+
.ToList();
47+
48+
var exceptions = new List<Exception>();
49+
50+
foreach (var component in project.VBComponents)
51+
{
52+
try
53+
{
54+
var name = component.Name;
55+
project.VBComponents.RemoveSafely(component);
56+
57+
var file = files.SingleOrDefault(f => f.Name == name + f.Extension);
58+
if (file != null)
59+
{
60+
try
61+
{
62+
project.VBComponents.ImportSourceFile(file.FullName);
63+
}
64+
catch (IndexOutOfRangeException)
65+
{
66+
exceptions.Add(new IndexOutOfRangeException(string.Format(VBEEditorText.NonexistentComponentErrorText, Path.GetFileNameWithoutExtension(file.FullName))));
67+
}
68+
}
69+
}
70+
catch (Exception ex)
71+
{
72+
exceptions.Add(ex);
73+
}
74+
}
75+
76+
foreach (var file in files)
77+
{
78+
try
79+
{
80+
if (project.VBComponents.All(v => v.Name + file.Extension != file.Name))
81+
{
82+
try
83+
{
84+
project.VBComponents.ImportSourceFile(file.FullName);
85+
}
86+
catch (IndexOutOfRangeException)
87+
{
88+
exceptions.Add(new IndexOutOfRangeException(string.Format(VBEEditorText.NonexistentComponentErrorText, Path.GetFileNameWithoutExtension(file.FullName))));
89+
}
90+
}
91+
}
92+
catch (Exception ex)
93+
{
94+
exceptions.Add(ex);
95+
}
96+
}
97+
98+
if (exceptions.Count != 0)
99+
{
100+
throw new AggregateException(string.Empty, exceptions);
101+
}
102+
}
103+
}
3104
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.InteropServices;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using Microsoft.Office.Interop.Word;
8+
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
9+
using Rubberduck.VBEditor.SafeComWrappers.MSForms;
10+
11+
namespace Rubberduck.VBEditor.Extensions
12+
{
13+
public static class WindowExtensions
14+
{
15+
//The hWnd property on most of the VBE windows is completely worthless (it just returns 0). This will get its
16+
//*real* hWnd.
17+
public static IntPtr ToHwnd(this IWindow window)
18+
{
19+
//Try the obvious first.
20+
if (window.HWnd != 0)
21+
{
22+
return new IntPtr(window.HWnd);
23+
}
24+
//Try FindWindowEx next.
25+
var hwnd = NativeMethods.FindWindowEx(IntPtr.Zero, IntPtr.Zero, window.Type.ToClassName(), window.Caption);
26+
if (hwnd != IntPtr.Zero)
27+
{
28+
return hwnd;
29+
}
30+
//Try enum all the child windows last - ugh.
31+
var finder = new NativeMethods.ChildWindowFinder(window.Caption);
32+
finder.EnumWindowsProcToChildWindowByCaption(IntPtr.Zero, IntPtr.Zero);
33+
return finder.ResultHandle;
34+
}
35+
36+
public static string ToClassName(this WindowKind kind)
37+
{
38+
switch (kind)
39+
{
40+
case WindowKind.Designer:
41+
return "DesignerWindow";
42+
case WindowKind.Browser:
43+
return "DockingView";
44+
case WindowKind.CodeWindow:
45+
case WindowKind.Watch:
46+
case WindowKind.Locals:
47+
case WindowKind.Immediate:
48+
return "VbaWindow";
49+
case WindowKind.ProjectWindow:
50+
return "PROJECT";
51+
case WindowKind.PropertyWindow:
52+
return "wndclass_pbrs";
53+
case WindowKind.Find:
54+
case WindowKind.FindReplace:
55+
return "#32770 (Dialog)";
56+
case WindowKind.Toolbox:
57+
return "F3 MinFrame 77ec0000";
58+
case WindowKind.LinkedWindowFrame: //WTF is this?
59+
return string.Empty;
60+
case WindowKind.MainWindow:
61+
return "wndclass_desked_gsk";
62+
case WindowKind.ToolWindow:
63+
return "VBFloatingPalette";
64+
default:
65+
return string.Empty;
66+
}
67+
}
68+
}
69+
}

Rubberduck.VBEEditor/NativeMethods.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ public static class NativeMethods
3939
[DllImport("user32", ExactSpelling = true, CharSet = CharSet.Unicode)]
4040
internal static extern int EnumChildWindows(IntPtr parentWindowHandle, EnumChildWindowsDelegate lpEnumFunction, IntPtr lParam);
4141

42+
/// <param name="parentHandle"> Handle of the parent window. IntPtr.Zero is the desktop. </param>
43+
/// <param name="childAfter"> The child window to begin searching after. </param>
44+
/// <param name="lclassName"> The window class name (optional). </param>
45+
/// <param name="windowTitle"> The window caption (optional). </param>
46+
/// <returns> An IntPtr to the found windows hWnd, IntPtr.Zero if no match is found. </returns>
47+
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
48+
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);
49+
4250
/// <summary> Gets window text. </summary>
4351
///
4452
/// <param name="hWnd"> The window handle. </param>

Rubberduck.VBEEditor/Rubberduck.VBEditor.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
<Compile Include="Events\ProjectEventArgs.cs" />
128128
<Compile Include="Events\ProjectRenamedEventArgs.cs" />
129129
<Compile Include="Extensions\MSAccessComponentTypeExtensions.cs" />
130+
<Compile Include="Extensions\WindowExtensions.cs" />
130131
<Compile Include="Native\WinEvents.cs" />
131132
<Compile Include="SafeComWrappers\Abstract\ISafeComWrapper.cs" />
132133
<Compile Include="SafeComWrappers\Abstract\IVBComponentsEventsSink.cs" />

Rubberduck.VBEEditor/SafeComWrappers/Abstract/IWindow.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace Rubberduck.VBEditor.SafeComWrappers.Abstract
55
{
66
public interface IWindow : ISafeComWrapper, IEquatable<IWindow>
77
{
8+
IntPtr RealHwnd { get; set; }
89
int HWnd { get; }
910
string Caption { get; }
1011
bool IsVisible { get; set; }

Rubberduck.VBEEditor/SafeComWrappers/VB6/Window.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public Window(VB.Window window)
1212
{
1313
}
1414

15+
public IntPtr RealHwnd { get; set; }
16+
1517
public int HWnd
1618
{
1719
get { return IsWrappingNullReference ? 0 : Target.HWnd; }

0 commit comments

Comments
 (0)