diff --git a/TitleBarTabsOverlay.cs b/TitleBarTabsOverlay.cs index e069fdfd..7f5c6e9b 100644 --- a/TitleBarTabsOverlay.cs +++ b/TitleBarTabsOverlay.cs @@ -46,10 +46,10 @@ public class TitleBarTabsOverlay : Form /// Semaphore to control access to . protected static object _tornTabLock = new object(); - protected static uint _doubleClickInterval = User32.GetDoubleClickTime(); + protected static uint _doubleClickInterval = User32.GetDoubleClickTime(); - /// Flag indicating whether or not the underlying window is active. - protected bool _active = false; + /// Flag indicating whether or not the underlying window is active. + protected bool _active = false; /// Flag indicating whether we should draw the titlebar background (i.e. we are in a non-Aero environment). protected bool _aeroEnabled = false; @@ -69,9 +69,9 @@ public class TitleBarTabsOverlay : Form /// Index of the tab, if any, whose close button is being hovered over. protected int _isOverCloseButtonForTab = -1; - protected bool _isOverSizingBox = false; + protected bool _isOverSizingBox = false; - protected bool _isOverAddButton = true; + protected bool _isOverAddButton = true; /// Queue of mouse events reported by that need to be processed. protected BlockingCollection _mouseEvents = new BlockingCollection(); @@ -82,10 +82,10 @@ public class TitleBarTabsOverlay : Form /// Parent form for the overlay. 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; @@ -218,7 +218,7 @@ public static TitleBarTabsOverlay GetInstance(TitleBarTabs parentForm) /// protected void AttachHandlers() { - FormClosing += TitleBarTabsOverlay_FormClosing; + FormClosing += TitleBarTabsOverlay_FormClosing; _parentForm.FormClosing += _parentForm_FormClosing; _parentForm.Disposed += _parentForm_Disposed; @@ -252,23 +252,23 @@ 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(); - } - } - - /// - /// Event handler that is called when is in the process of closing. This uninstalls from the low- - /// level hooks list and stops the consumer thread that processes those events. - /// - /// Object from which this event originated, in this case. - /// Arguments associated with this event. - private void _parentForm_FormClosing(object sender, CancelEventArgs e) + } + } + + /// + /// Event handler that is called when is in the process of closing. This uninstalls from the low- + /// level hooks list and stops the consumer thread that processes those events. + /// + /// Object from which this event originated, in this case. + /// Arguments associated with this event. + private void _parentForm_FormClosing(object sender, CancelEventArgs e) { if (e.Cancel) { @@ -276,7 +276,7 @@ private void _parentForm_FormClosing(object sender, CancelEventArgs e) return; } - TitleBarTabs form = (TitleBarTabs) sender; + TitleBarTabs form = (TitleBarTabs) sender; if (form == null) { @@ -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))) { @@ -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)) @@ -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 { @@ -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; } @@ -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); } @@ -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); @@ -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 @@ -975,9 +975,9 @@ protected override void WndProc(ref Message m) } else - { + { base.WndProc(ref m); - } + } break;