Skip to content

Commit 01dcc6a

Browse files
authored
Merge pull request #4490 from comintern/subclas
Address potential race condition and potentially un-disposed objects …
2 parents 0e1b4ec + b7ce4c9 commit 01dcc6a

File tree

1 file changed

+54
-25
lines changed

1 file changed

+54
-25
lines changed

Rubberduck.VBEEditor/WindowsApi/SubclassManager.cs

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,36 +37,65 @@ public SubclassingWindow Subclass(IntPtr hwnd)
3737
return null;
3838
}
3939

40-
if (_subclasses.TryGetValue(hwnd, out var existing))
40+
lock (ThreadLock)
41+
{
42+
if (_subclasses.TryGetValue(hwnd, out var existing))
43+
{
44+
return existing;
45+
}
46+
47+
// Any additional cases also need to be added to IsSubclassable above.
48+
switch (windowType)
49+
{
50+
case WindowType.CodePane:
51+
return TrackNewCodePane(hwnd);
52+
case WindowType.DesignerWindow:
53+
return TrackNewDesigner(hwnd);
54+
default:
55+
return null;
56+
}
57+
}
58+
}
59+
60+
private CodePaneSubclass TrackNewCodePane(IntPtr hwnd)
61+
{
62+
var codePane = new CodePaneSubclass(hwnd, null);
63+
try
4164
{
42-
return existing;
65+
if (_subclasses.TryAdd(hwnd, codePane))
66+
{
67+
codePane.ReleasingHandle += SubclassRemoved;
68+
codePane.CaptionChanged += AssociateCodePane;
69+
SubclassLogger.Trace($"Subclassed hWnd 0x{hwnd.ToInt64():X8} as CodePane.");
70+
return codePane;
71+
}
4372
}
73+
catch (Exception ex)
74+
{
75+
SubclassLogger.Error(ex);
76+
}
77+
codePane.Dispose();
78+
return null;
79+
}
4480

45-
// Any additional cases also need to be added to IsSubclassable above.
46-
switch (windowType)
81+
private DesignerWindowSubclass TrackNewDesigner(IntPtr hwnd)
82+
{
83+
var designer = new DesignerWindowSubclass(hwnd);
84+
try
85+
{
86+
if (_subclasses.TryAdd(hwnd, designer))
87+
{
88+
designer.ReleasingHandle += SubclassRemoved;
89+
SubclassLogger.Trace($"Subclassed hWnd 0x{hwnd.ToInt64():X8} as DesignerWindow.");
90+
return designer;
91+
}
92+
}
93+
catch (Exception ex)
4794
{
48-
case WindowType.CodePane:
49-
lock (ThreadLock)
50-
{
51-
var codePane = new CodePaneSubclass(hwnd, null);
52-
_subclasses.TryAdd(hwnd, codePane);
53-
codePane.ReleasingHandle += SubclassRemoved;
54-
codePane.CaptionChanged += AssociateCodePane;
55-
SubclassLogger.Trace($"Subclassed hWnd 0x{hwnd.ToInt64():X8} as CodePane.");
56-
return codePane;
57-
}
58-
case WindowType.DesignerWindow:
59-
lock (ThreadLock)
60-
{
61-
var designer = new DesignerWindowSubclass(hwnd);
62-
_subclasses.TryAdd(hwnd, designer);
63-
designer.ReleasingHandle += SubclassRemoved;
64-
SubclassLogger.Trace($"Subclassed hWnd 0x{hwnd.ToInt64():X8} as DesignerWindow.");
65-
return designer;
66-
}
67-
default:
68-
return null;
95+
SubclassLogger.Error(ex);
6996
}
97+
designer.Dispose();
98+
return null;
7099
}
71100

72101
private void SubclassRemoved(object sender, EventArgs eventArgs)

0 commit comments

Comments
 (0)