/// <summary> /// Hide the containing form (and thus the list box as a whole). /// </summary> public void HideForm() { CheckDisposed(); // The order of the following two lines is very important! On some // machines the LT-2962 issue will show itself if this is changed. // The summary statement is that making the form not visible causes // the system to activate another application, and with out telling // it before hand what to activate it would get confused and cycle // through the applications that were currently running. By // activating the main form first and then hiding the little form // the bug is not seen (and maybe not present... // but that's much like the forest and a falling tree debate.) // // ** Dont change the order of the following two lines ** if (m_previousForm != null) // Somehow may not be, if no form is active when launched! m_previousForm.Activate(); if (m_listForm != null) m_listForm.Visible = false; // reset HighlightedItem to current selected. HighlightedIndex = SelectedIndex; if (m_comboMessageFilter != null) { Application.RemoveMessageFilter(m_comboMessageFilter); m_comboMessageFilter.Dispose(); m_comboMessageFilter = null; } }
/// <summary> /// Launch the ComboListBox. /// Typical usage, where 'this' is a control that the list should appear below: /// m_listBox.Launch(Parent.RectangleToScreen(Bounds), Screen.GetWorkingArea(this)); /// Or, where rect is a rectangle in the client area of control 'this': /// m_listBox.Launch(RectangleToScreen(rect), Screen.GetWorkingArea(this); /// (Be sure to set the height and width of the ComboListBox first.) /// </summary> /// <param name="launcherBounds">A rectangle in 'screen' coordinates indicating where to display the list. Typically, as shown /// above, the location of something the user clicked to make the list display. It's significance is that /// the list will usually be shown with its top left just to the right of the bottom left of the rectangle, and /// (if the list width has not already been set explicitly) its width will match the rectangle. If there is not /// room to displya the list below this rectangle, it will be displayed above instead.</param> /// <param name="screenBounds">A rectangle in 'screen' coordinates indicating the location of the actual screen /// that the list is to appear on.</param> public void Launch(Rectangle launcherBounds, Rectangle screenBounds) { CheckDisposed(); m_previousForm = Form.ActiveForm; #if __MonoCS__ // FWNX-908: Crash closing combobox. // Somehow on Mono, Form.ActiveForm can sometimes return m_listForm at this point. if (m_previousForm == null || m_previousForm == m_listForm) m_previousForm = LaunchingForm; #endif m_listForm.ShowInTaskbar = false; // this is mainly to prevent it showing in the task bar. //Figure where to put it. First try right below the main combo box. // Pathologically the list box may be bigger than the available height. If so shrink it. int maxListHeight = Math.Max(launcherBounds.Top - screenBounds.Top, screenBounds.Bottom - launcherBounds.Bottom); if (m_listForm.Height > maxListHeight) m_listForm.Height = maxListHeight; // This is the default position right below the combo. var popupBounds = new Rectangle(launcherBounds.Left, launcherBounds.Bottom, m_listForm.Width, m_listForm.Height); if (screenBounds.Bottom < popupBounds.Bottom) { // extends below the bottom of the screen. Use a rectangle above instead. // We already made sure it will fit in one place or the other. popupBounds = new Rectangle(launcherBounds.Left, launcherBounds.Top - m_listForm.Height, m_listForm.Width, m_listForm.Height); } if (screenBounds.Right < popupBounds.Right) { // Extends too far to the right; adjust (amount is negative to move left). popupBounds.Offset(screenBounds.Right - popupBounds.Right, 0); } if (screenBounds.Left > popupBounds.Left) { // Extends too far to the left; adjust (amount is positive to move right). popupBounds.Offset(screenBounds.Left - popupBounds.Left, 0); } m_listForm.Location = new Point(popupBounds.Left, popupBounds.Top); if (m_activateOnShow) m_listForm.Show(m_previousForm); else ShowInactiveTopmost(m_previousForm, m_listForm); if (m_comboMessageFilter != null) { // losing our ref to m_comboMessageFilter, while it's still added to the Application Message Filter, // would mean it would never get removed. (Which would be very bad.) Application.RemoveMessageFilter(m_comboMessageFilter); m_comboMessageFilter.Dispose(); } m_comboMessageFilter = new FwComboMessageFilter(this); Application.AddMessageFilter(m_comboMessageFilter); if (m_activateOnShow) FocusAndCapture(); }
/// <summary> /// Launch the ComboListBox. /// Typical usage, where 'this' is a control that the list should appear below: /// m_listBox.Launch(Parent.RectangleToScreen(Bounds), Screen.GetWorkingArea(this)); /// Or, where rect is a rectangle in the client area of control 'this': /// m_listBox.Launch(RectangleToScreen(rect), Screen.GetWorkingArea(this); /// (Be sure to set the height and width of the ComboListBox first.) /// </summary> /// <param name="launcherBounds">A rectangle in 'screen' coordinates indicating where to display the list. Typically, as shown /// above, the location of something the user clicked to make the list display. It's significance is that /// the list will usually be shown with its top left just to the right of the bottom left of the rectangle, and /// (if the list width has not already been set explicitly) its width will match the rectangle. If there is not /// room to displya the list below this rectangle, it will be displayed above instead.</param> /// <param name="screenBounds">A rectangle in 'screen' coordinates indicating the location of the actual screen /// that the list is to appear on.</param> public void Launch(Rectangle launcherBounds, Rectangle screenBounds) { CheckDisposed(); m_previousForm = Form.ActiveForm; m_listForm.ShowInTaskbar = false; // this is mainly to prevent it showing in the task bar. //Figure where to put it. First try right below the main combo box. // Pathologically the list box may be bigger than the available height. If so shrink it. int maxListHeight = Math.Max(launcherBounds.Top - screenBounds.Top, screenBounds.Bottom - launcherBounds.Bottom); if (m_listForm.Height > maxListHeight) m_listForm.Height = maxListHeight; // This is the default position right below the combo. Rectangle popupBounds = new Rectangle(launcherBounds.Left, launcherBounds.Bottom, m_listForm.Width, m_listForm.Height); if (screenBounds.Bottom < popupBounds.Bottom) { // extends below the bottom of the screen. Use a rectangle above instead. // We already made sure it will fit in one place or the other. popupBounds = new Rectangle(launcherBounds.Left, launcherBounds.Top - m_listForm.Height, m_listForm.Width, m_listForm.Height); } if (screenBounds.Right < popupBounds.Right) { // Extends too far to the right; adjust (amount is negative to move left). popupBounds.Offset(screenBounds.Right - popupBounds.Right, 0); } if (screenBounds.Left > popupBounds.Left) { // Extends too far to the left; adjust (amount is positive to move right). popupBounds.Offset(screenBounds.Left - popupBounds.Left, 0); } m_listForm.Location = new Point(popupBounds.Left, popupBounds.Top); m_listForm.Show(); m_comboMessageFilter = new FwComboMessageFilter(this); Application.AddMessageFilter(m_comboMessageFilter); this.FocusAndCapture(); }
// Region last reviewed: never /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { System.Diagnostics.Debug.WriteLineIf(!disposing, "****************** Missing Dispose() call for " + GetType().Name + " ******************"); // Must not be run more than once. if (IsDisposed) return; if (disposing) { // Don't call Controls.Clear() - we need to dispose the controls it contains. // This will be done in base class. if (m_listForm != null) { m_listForm.Deactivate -= m_ListForm_Deactivate; m_listForm.Controls.Remove(this); if (m_listForm.Visible) m_listForm.Close(); m_listForm.Dispose(); } if (m_comboMessageFilter != null) { Application.RemoveMessageFilter(m_comboMessageFilter); m_comboMessageFilter.Dispose(); } } m_listForm = null; m_button = null; m_comboMessageFilter = null; base.Dispose(disposing); }
// Region last reviewed: never /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { //Debug.WriteLineIf(!disposing, "****************** " + GetType().Name + " 'disposing' is false. ******************"); // Must not be run more than once. if (IsDisposed) return; if (disposing) { Controls.Clear(); if (m_listForm != null) { m_listForm.Deactivate -= new EventHandler(m_ListForm_Deactivate); m_listForm.Controls.Clear(); // 'this' is its control, so must be removed. m_listForm.Close(); } if (m_comboMessageFilter != null) { Application.RemoveMessageFilter(m_comboMessageFilter); m_comboMessageFilter.Dispose(); } } m_listForm = null; m_button = null; m_comboMessageFilter = null; base.Dispose(disposing); }