Skip to content

Commit f040a16

Browse files
committed
Remove IUnknown, add Refresh, release SCWs, and test to make sure we don't tell the desktop to stop painting (ooops).
1 parent 24b9afe commit f040a16

File tree

3 files changed

+54
-82
lines changed
  • Rubberduck.VBEEditor/SafeComWrappers/VB/Abstract
  • Rubberduck.VBEditor.VB6/SafeComWrappers/VB
  • Rubberduck.VBEditor.VBA/SafeComWrappers/VB

3 files changed

+54
-82
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ namespace Rubberduck.VBEditor.SafeComWrappers.Abstract
55
public interface IWindow : ISafeComWrapper, IEquatable<IWindow>
66
{
77
int HWnd { get; }
8-
IntPtr IUnknown { get; }
98
string Caption { get; }
109
bool IsVisible { get; set; }
1110
int Left { get; set; }
@@ -25,5 +24,6 @@ public interface IWindow : ISafeComWrapper, IEquatable<IWindow>
2524
void Detach();
2625
void Attach(int lWindowHandle);
2726
bool ScreenUpdating { get; set; }
27+
void Refresh();
2828
}
2929
}

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

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Runtime.InteropServices;
32
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
43
using Rubberduck.VBEditor.WindowsApi;
54
using VB = Microsoft.Vbe.Interop.VB6;
@@ -21,41 +20,6 @@ public IntPtr Handle()
2120
return (IntPtr)HWnd;
2221
}
2322

24-
private IntPtr _unknown;
25-
public IntPtr IUnknown
26-
{
27-
get
28-
{
29-
if (IsWrappingNullReference)
30-
{
31-
return IntPtr.Zero;
32-
}
33-
34-
if (_unknown == IntPtr.Zero)
35-
{
36-
try
37-
{
38-
try
39-
{
40-
_unknown = Marshal.GetIUnknownForObject(Target);
41-
}
42-
catch
43-
{
44-
// If GetIUnknownForObject throws us here, we're fine - it just means that the wrapper itself is invalid.
45-
}
46-
Marshal.Release(_unknown);
47-
}
48-
catch
49-
{
50-
// If Marshal.Release threw us here, we're probably screwed anyway, so we might as well just wait for the
51-
// zombie process when the VBE tries to close.
52-
_logger.Warn("Marshal.Release failed for IWindow after a successful call to Marshal.GetIUnknownForObject. Process may hang on close.");
53-
}
54-
}
55-
return _unknown;
56-
}
57-
}
58-
5923
public IVBE VBE => new VBE(IsWrappingNullReference ? null : Target.VBE);
6024

6125
public IWindows Collection => new Windows(IsWrappingNullReference ? null : Target.Collection);
@@ -79,13 +43,35 @@ public bool ScreenUpdating
7943
return;
8044
}
8145

82-
var window = VBE.MainWindow;
83-
var handle = window.Handle().FindChildWindow(Caption);
46+
using (var window = VBE.MainWindow)
47+
{
48+
var handle = window.Handle().FindChildWindow(Caption);
49+
if (handle.Equals(IntPtr.Zero))
50+
{
51+
return;
52+
}
53+
if (NativeMethods.SendMessage(handle, (int)WM.SETREDRAW, new IntPtr(value ? -1 : 0), IntPtr.Zero) == IntPtr.Zero)
54+
{
55+
_screenUpdating = value;
56+
}
57+
}
58+
}
59+
}
8460

85-
if (NativeMethods.SendMessage(handle, (int)WM.SETREDRAW, new IntPtr(value ? -1 : 0), IntPtr.Zero) == IntPtr.Zero)
61+
public void Refresh()
62+
{
63+
if (!_screenUpdating)
64+
{
65+
return;
66+
}
67+
using (var window = VBE.MainWindow)
68+
{
69+
var handle = window.Handle().FindChildWindow(Caption);
70+
if (handle.Equals(IntPtr.Zero))
8671
{
87-
_screenUpdating = value;
72+
return;
8873
}
74+
NativeMethods.RedrawWindow(handle, IntPtr.Zero, IntPtr.Zero, RedrawWindowFlags.AllChildren | RedrawWindowFlags.UpdateNow);
8975
}
9076
}
9177

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

Lines changed: 27 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Runtime.InteropServices;
32
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
43
using Rubberduck.VBEditor.WindowsApi;
54
using VB = Microsoft.Vbe.Interop;
@@ -21,41 +20,6 @@ public IntPtr Handle()
2120
return (IntPtr)HWnd;
2221
}
2322

24-
private IntPtr _unknown;
25-
public IntPtr IUnknown
26-
{
27-
get
28-
{
29-
if (IsWrappingNullReference)
30-
{
31-
return IntPtr.Zero;
32-
}
33-
34-
if (_unknown == IntPtr.Zero)
35-
{
36-
try
37-
{
38-
try
39-
{
40-
_unknown = Marshal.GetIUnknownForObject(Target);
41-
}
42-
catch
43-
{
44-
// If GetIUnknownForObject throws us here, we're fine - it just means that the wrapper itself is invalid.
45-
}
46-
Marshal.Release(_unknown);
47-
}
48-
catch
49-
{
50-
// If Marshal.Release threw us here, we're probably screwed anyway, so we might as well just wait for the
51-
// zombie process when the VBE tries to close.
52-
_logger.Warn("Marshal.Release failed for IWindow after a successful call to Marshal.GetIUnknownForObject. Process may hang on close.");
53-
}
54-
}
55-
return _unknown;
56-
}
57-
}
58-
5923
public IVBE VBE => new VBE(IsWrappingNullReference ? null : Target.VBE);
6024

6125
public IWindows Collection => new Windows(IsWrappingNullReference ? null : Target.Collection);
@@ -79,16 +43,38 @@ public bool ScreenUpdating
7943
return;
8044
}
8145

82-
var window = VBE.MainWindow;
83-
var handle = window.Handle().FindChildWindow(Caption);
84-
85-
if (NativeMethods.SendMessage(handle, (int) WM.SETREDRAW, new IntPtr(value ? -1 : 0), IntPtr.Zero) == IntPtr.Zero)
46+
using (var window = VBE.MainWindow)
8647
{
87-
_screenUpdating = value;
48+
var handle = window.Handle().FindChildWindow(Caption);
49+
if (handle.Equals(IntPtr.Zero))
50+
{
51+
return;
52+
}
53+
if (NativeMethods.SendMessage(handle, (int)WM.SETREDRAW, new IntPtr(value ? -1 : 0), IntPtr.Zero) == IntPtr.Zero)
54+
{
55+
_screenUpdating = value;
56+
}
8857
}
8958
}
9059
}
9160

61+
public void Refresh()
62+
{
63+
if (!_screenUpdating)
64+
{
65+
return;
66+
}
67+
using (var window = VBE.MainWindow)
68+
{
69+
var handle = window.Handle().FindChildWindow(Caption);
70+
if (handle.Equals(IntPtr.Zero))
71+
{
72+
return;
73+
}
74+
NativeMethods.RedrawWindow(handle, IntPtr.Zero, IntPtr.Zero, RedrawWindowFlags.AllChildren | RedrawWindowFlags.UpdateNow);
75+
}
76+
}
77+
9278
public int Left
9379
{
9480
get => IsWrappingNullReference ? 0 : Target.Left;

0 commit comments

Comments
 (0)