/// <summary> /// Overrides the message pump for the window so that we can respond to click events on the tabs themselves /// </summary> /// <param name="m">Message received by the pump</param> protected override void WndProc(ref Message m) { switch ((WM)m.Msg) { case WM.WM_NCLBUTTONDOWN: case WM.WM_LBUTTONDOWN: Point relativeCursorPosition = GetRelativeCursorPosition(Cursor.Position); // If we were over a tab, set the capture state for the window so that we'll actually receive a WM_LBUTTONUP message if (ParentForm.TabRenderer.IsOverTab(ParentForm.Tabs, relativeCursorPosition) == null && !ParentForm.TabRenderer.IsOverAddButton(relativeCursorPosition)) { ParentForm.ForwardMessage(ref m); } else { TitleBarTab clickedTab = ParentForm.TabRenderer.IsOverTab(ParentForm.Tabs, relativeCursorPosition); if (clickedTab != null) { // If the user clicked the close button, remove the tab from the list if (!ParentForm.TabRenderer.IsOverCloseButton(clickedTab, relativeCursorPosition)) { ParentForm.ResizeTabContents(clickedTab); ParentForm.SelectedTabIndex = ParentForm.Tabs.IndexOf(clickedTab); Render(); } OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, Cursor.Position.X, Cursor.Position.Y, 0)); } ParentForm.Activate(); } break; case WM.WM_LBUTTONDBLCLK: ParentForm.ForwardMessage(ref m); break; // We always return HTCAPTION for the hit test message so that the underlying window doesn't have its focus removed case WM.WM_NCHITTEST: m.Result = new IntPtr((int)HT.HTCAPTION); break; case WM.WM_LBUTTONUP: case WM.WM_NCLBUTTONUP: case WM.WM_MBUTTONUP: case WM.WM_NCMBUTTONUP: Point relativeCursorPosition2 = GetRelativeCursorPosition(Cursor.Position); if (ParentForm.TabRenderer.IsOverTab(ParentForm.Tabs, relativeCursorPosition2) == null && !ParentForm.TabRenderer.IsOverAddButton(relativeCursorPosition2)) { ParentForm.ForwardMessage(ref m); } else { TitleBarTab clickedTab = ParentForm.TabRenderer.IsOverTab(ParentForm.Tabs, relativeCursorPosition2); if (clickedTab != null) { // If the user clicks the middle button/scroll wheel over a tab, close it if ((WM)m.Msg == WM.WM_MBUTTONUP || (WM)m.Msg == WM.WM_NCMBUTTONUP) { clickedTab.Content.Close(); Render(); } else { // If the user clicked the close button, remove the tab from the list if (ParentForm.TabRenderer.IsOverCloseButton(clickedTab, relativeCursorPosition2)) { clickedTab.Content.Close(); Render(); } else { ParentForm.OnTabClicked(new TitleBarTabEventArgs(TabControlAction.Selected, clickedTab, ParentForm.SelectedTabIndex, s_wasDragging)); } } } // Otherwise, if the user clicked the add button, call CreateTab to add a new tab to the list and select it else if (ParentForm.TabRenderer.IsOverAddButton(relativeCursorPosition2)) { ParentForm.AddNewTab(); } if ((WM)m.Msg == WM.WM_LBUTTONUP || (WM)m.Msg == WM.WM_NCLBUTTONUP) { OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, Cursor.Position.X, Cursor.Position.Y, 0)); } } break; default: base.WndProc(ref m); break; } }