Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 87 additions & 87 deletions TitleBarTabsOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ public class TitleBarTabsOverlay : Form
/// <summary>Semaphore to control access to <see cref="_tornTab" />.</summary>
protected static object _tornTabLock = new object();

protected static uint _doubleClickInterval = User32.GetDoubleClickTime();
protected static uint _doubleClickInterval = User32.GetDoubleClickTime();

/// <summary>Flag indicating whether or not the underlying window is active.</summary>
protected bool _active = false;
/// <summary>Flag indicating whether or not the underlying window is active.</summary>
protected bool _active = false;

/// <summary>Flag indicating whether we should draw the titlebar background (i.e. we are in a non-Aero environment).</summary>
protected bool _aeroEnabled = false;
Expand All @@ -69,9 +69,9 @@ public class TitleBarTabsOverlay : Form
/// <summary>Index of the tab, if any, whose close button is being hovered over.</summary>
protected int _isOverCloseButtonForTab = -1;

protected bool _isOverSizingBox = false;
protected bool _isOverSizingBox = false;

protected bool _isOverAddButton = true;
protected bool _isOverAddButton = true;

/// <summary>Queue of mouse events reported by <see cref="_hookproc" /> that need to be processed.</summary>
protected BlockingCollection<MouseEvent> _mouseEvents = new BlockingCollection<MouseEvent>();
Expand All @@ -82,10 +82,10 @@ public class TitleBarTabsOverlay : Form
/// <summary>Parent form for the overlay.</summary>
protected TitleBarTabs _parentForm;

protected long _lastLeftButtonClickTicks = 0;
protected long _lastLeftButtonClickTicks = 0;

protected bool _firstClick = true;
protected Point[] _lastTwoClickCoordinates = new Point[2];
protected Point _lastLeftButtonClickPoint = Point.Empty;

protected bool _parentFormClosing = false;

Expand Down Expand Up @@ -218,7 +218,7 @@ public static TitleBarTabsOverlay GetInstance(TitleBarTabs parentForm)
/// </summary>
protected void AttachHandlers()
{
FormClosing += TitleBarTabsOverlay_FormClosing;
FormClosing += TitleBarTabsOverlay_FormClosing;

_parentForm.FormClosing += _parentForm_FormClosing;
_parentForm.Disposed += _parentForm_Disposed;
Expand Down Expand Up @@ -252,31 +252,31 @@ protected void AttachHandlers()
}
}

private void TitleBarTabsOverlay_FormClosing(object sender, FormClosingEventArgs e)
{
private void TitleBarTabsOverlay_FormClosing(object sender, FormClosingEventArgs e)
{
if (!_parentFormClosing)
{
{
e.Cancel = true;
_parentFormClosing = true;
_parentForm.Close();
}
}

/// <summary>
/// Event handler that is called when <see cref="_parentForm" /> is in the process of closing. This uninstalls <see cref="_hookproc" /> from the low-
/// level hooks list and stops the consumer thread that processes those events.
/// </summary>
/// <param name="sender">Object from which this event originated, <see cref="_parentForm" /> in this case.</param>
/// <param name="e">Arguments associated with this event.</param>
private void _parentForm_FormClosing(object sender, CancelEventArgs e)
}
}

/// <summary>
/// Event handler that is called when <see cref="_parentForm" /> is in the process of closing. This uninstalls <see cref="_hookproc" /> from the low-
/// level hooks list and stops the consumer thread that processes those events.
/// </summary>
/// <param name="sender">Object from which this event originated, <see cref="_parentForm" /> in this case.</param>
/// <param name="e">Arguments associated with this event.</param>
private void _parentForm_FormClosing(object sender, CancelEventArgs e)
{
if (e.Cancel)
{
_parentFormClosing = false;
return;
}

TitleBarTabs form = (TitleBarTabs) sender;
TitleBarTabs form = (TitleBarTabs) sender;

if (form == null)
{
Expand Down Expand Up @@ -436,11 +436,11 @@ protected void InterpretMouseEvents()
{
StartTooltipTimer();

Point relativeCursorPosition = GetRelativeCursorPosition(cursorPosition);
Point relativeCursorPosition = GetRelativeCursorPosition(cursorPosition);

// If we were over a close button previously, check to see if the cursor is still over that tab's
// close button; if not, re-render
if (_isOverCloseButtonForTab != -1 &&
// If we were over a close button previously, check to see if the cursor is still over that tab's
// close button; if not, re-render
if (_isOverCloseButtonForTab != -1 &&
(_isOverCloseButtonForTab >= _parentForm.Tabs.Count ||
!_parentForm.TabRenderer.IsOverCloseButton(_parentForm.Tabs[_isOverCloseButtonForTab], relativeCursorPosition)))
{
Expand All @@ -451,8 +451,8 @@ protected void InterpretMouseEvents()
// Otherwise, see if any tabs' close button is being hovered over
else
{
// ReSharper disable ForCanBeConvertedToForeach
for (int i = 0; i < _parentForm.Tabs.Count; i++)
// ReSharper disable ForCanBeConvertedToForeach
for (int i = 0; i < _parentForm.Tabs.Count; i++)
// ReSharper restore ForCanBeConvertedToForeach
{
if (_parentForm.TabRenderer.IsOverCloseButton(_parentForm.Tabs[i], relativeCursorPosition))
Expand All @@ -465,33 +465,33 @@ protected void InterpretMouseEvents()
}
}

if (_isOverCloseButtonForTab == -1 && _parentForm.TabRenderer.RendersEntireTitleBar)
{
if (_parentForm.TabRenderer.IsOverSizingBox(relativeCursorPosition))
{
_isOverSizingBox = true;
reRender = true;
}

else if (_isOverSizingBox)
{
_isOverSizingBox = false;
reRender = true;
}
}

if (_parentForm.TabRenderer.IsOverAddButton(relativeCursorPosition))
{
_isOverAddButton = true;
reRender = true;
}

else if (_isOverAddButton)
{
_isOverAddButton = false;
reRender = true;
}
}
if (_isOverCloseButtonForTab == -1 && _parentForm.TabRenderer.RendersEntireTitleBar)
{
if (_parentForm.TabRenderer.IsOverSizingBox(relativeCursorPosition))
{
_isOverSizingBox = true;
reRender = true;
}

else if (_isOverSizingBox)
{
_isOverSizingBox = false;
reRender = true;
}
}

if (_parentForm.TabRenderer.IsOverAddButton(relativeCursorPosition))
{
_isOverAddButton = true;
reRender = true;
}

else if (_isOverAddButton)
{
_isOverAddButton = false;
reRender = true;
}
}

else
{
Expand Down Expand Up @@ -556,28 +556,24 @@ protected void InterpretMouseEvents()
}
}

else if (nCode >= 0 && (int) WM.WM_LBUTTONDBLCLK == (int) wParam)
{
if (DesktopBounds.Contains(_lastTwoClickCoordinates[0]) && DesktopBounds.Contains(_lastTwoClickCoordinates[1]))
else if (nCode >= 0 && (int) WM.WM_LBUTTONDBLCLK == (int) wParam)
{
if (DesktopBounds.Contains(_lastLeftButtonClickPoint))
{
Invoke(new Action(() =>
{
_parentForm.WindowState = _parentForm.WindowState == FormWindowState.Maximized
? FormWindowState.Normal
: FormWindowState.Maximized;
if (_parentForm.Focused || _parentForm.ContainsFocus)
{
_parentForm.WindowState = _parentForm.WindowState == FormWindowState.Maximized
? FormWindowState.Normal
: FormWindowState.Maximized;
}
}));
}
}
}

else if (nCode >= 0 && (int) WM.WM_LBUTTONDOWN == (int) wParam)
{
if (!_firstClick)
{
_lastTwoClickCoordinates[1] = _lastTwoClickCoordinates[0];
}

_lastTwoClickCoordinates[0] = Cursor.Position;

_firstClick = false;
_wasDragging = false;
}
Expand Down Expand Up @@ -670,22 +666,26 @@ protected IntPtr MouseHookCallback(int nCode, IntPtr wParam, IntPtr lParam)

_mouseEvents.Add(mouseEvent);

if (nCode >= 0 && (int) WM.WM_LBUTTONDOWN == (int) wParam)
{
long currentTicks = DateTime.Now.Ticks;
if (nCode >= 0 && (int) WM.WM_LBUTTONDOWN == (int) wParam)
{
long currentTicks = DateTime.Now.Ticks;

if (_lastLeftButtonClickTicks > 0 && currentTicks - _lastLeftButtonClickTicks < _doubleClickInterval * 10000)
{
_mouseEvents.Add(new MouseEvent
{
nCode = nCode,
wParam = new IntPtr((int) WM.WM_LBUTTONDBLCLK),
lParam = lParam
});
}
var mouseData = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
var currentPoint = new Point(mouseData.pt.x, mouseData.pt.y);
var isSameClickPositionAsFirstClick = _lastLeftButtonClickPoint == currentPoint;
if (isSameClickPositionAsFirstClick && _lastLeftButtonClickTicks > 0 && currentTicks - _lastLeftButtonClickTicks < _doubleClickInterval * 10000)
{
_mouseEvents.Add(new MouseEvent
{
nCode = nCode,
wParam = new IntPtr((int) WM.WM_LBUTTONDBLCLK),
lParam = lParam
});
}

_lastLeftButtonClickTicks = currentTicks;
}
_lastLeftButtonClickTicks = currentTicks;
_lastLeftButtonClickPoint = currentPoint;
}

return User32.CallNextHookEx(_hookId, nCode, wParam, lParam);
}
Expand Down Expand Up @@ -804,7 +804,7 @@ protected void OnPosition()
: _parentForm.WindowState == FormWindowState.Maximized
? SystemInformation.VerticalResizeBorderThickness + borderPadding
: _parentForm.TabRenderer.RendersEntireTitleBar
? _parentForm.TabRenderer.IsWindows10
? _parentForm.TabRenderer.IsWindows10
? SystemInformation.BorderSize.Width
: 0
: borderPadding);
Expand Down Expand Up @@ -855,7 +855,7 @@ public void Render(Point cursorPosition, bool forceRedraw = false)
Point offset = _parentForm.WindowState != FormWindowState.Maximized && DisplayType == DisplayType.Classic && !_parentForm.TabRenderer.RendersEntireTitleBar
? new Point(0, SystemInformation.CaptionButtonSize.Height)
: _parentForm.WindowState != FormWindowState.Maximized && !_parentForm.TabRenderer.RendersEntireTitleBar
? new Point(0, SystemInformation.VerticalResizeBorderThickness - SystemInformation.BorderSize.Height)
? new Point(0, SystemInformation.VerticalResizeBorderThickness - SystemInformation.BorderSize.Height)
: new Point(0, 0);

// Render the tabs into the bitmap
Expand Down Expand Up @@ -975,9 +975,9 @@ protected override void WndProc(ref Message m)
}

else
{
{
base.WndProc(ref m);
}
}

break;

Expand Down