Skip to content

Commit

Permalink
Merge pull request #4490 from comintern/subclas
Browse files Browse the repository at this point in the history
Address potential race condition and potentially un-disposed objects …
  • Loading branch information
retailcoder authored Nov 6, 2018
2 parents 0e1b4ec + b7ce4c9 commit 01dcc6a
Showing 1 changed file with 54 additions and 25 deletions.
79 changes: 54 additions & 25 deletions Rubberduck.VBEEditor/WindowsApi/SubclassManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,36 +37,65 @@ public SubclassingWindow Subclass(IntPtr hwnd)
return null;
}

if (_subclasses.TryGetValue(hwnd, out var existing))
lock (ThreadLock)
{
if (_subclasses.TryGetValue(hwnd, out var existing))
{
return existing;
}

// Any additional cases also need to be added to IsSubclassable above.
switch (windowType)
{
case WindowType.CodePane:
return TrackNewCodePane(hwnd);
case WindowType.DesignerWindow:
return TrackNewDesigner(hwnd);
default:
return null;
}
}
}

private CodePaneSubclass TrackNewCodePane(IntPtr hwnd)
{
var codePane = new CodePaneSubclass(hwnd, null);
try
{
return existing;
if (_subclasses.TryAdd(hwnd, codePane))
{
codePane.ReleasingHandle += SubclassRemoved;
codePane.CaptionChanged += AssociateCodePane;
SubclassLogger.Trace($"Subclassed hWnd 0x{hwnd.ToInt64():X8} as CodePane.");
return codePane;
}
}
catch (Exception ex)
{
SubclassLogger.Error(ex);
}
codePane.Dispose();
return null;
}

// Any additional cases also need to be added to IsSubclassable above.
switch (windowType)
private DesignerWindowSubclass TrackNewDesigner(IntPtr hwnd)
{
var designer = new DesignerWindowSubclass(hwnd);
try
{
if (_subclasses.TryAdd(hwnd, designer))
{
designer.ReleasingHandle += SubclassRemoved;
SubclassLogger.Trace($"Subclassed hWnd 0x{hwnd.ToInt64():X8} as DesignerWindow.");
return designer;
}
}
catch (Exception ex)
{
case WindowType.CodePane:
lock (ThreadLock)
{
var codePane = new CodePaneSubclass(hwnd, null);
_subclasses.TryAdd(hwnd, codePane);
codePane.ReleasingHandle += SubclassRemoved;
codePane.CaptionChanged += AssociateCodePane;
SubclassLogger.Trace($"Subclassed hWnd 0x{hwnd.ToInt64():X8} as CodePane.");
return codePane;
}
case WindowType.DesignerWindow:
lock (ThreadLock)
{
var designer = new DesignerWindowSubclass(hwnd);
_subclasses.TryAdd(hwnd, designer);
designer.ReleasingHandle += SubclassRemoved;
SubclassLogger.Trace($"Subclassed hWnd 0x{hwnd.ToInt64():X8} as DesignerWindow.");
return designer;
}
default:
return null;
SubclassLogger.Error(ex);
}
designer.Dispose();
return null;
}

private void SubclassRemoved(object sender, EventArgs eventArgs)
Expand Down

0 comments on commit 01dcc6a

Please sign in to comment.