|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
|
|
|
|
namespace JwKdsV.Component
|
|
|
|
|
{
|
|
|
|
|
public class DatePicker : DateTimePicker
|
|
|
|
|
{
|
|
|
|
|
private PopupWindowHelper popupHelper;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Color of the DatePicker header
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Description("Color of the DatePicker header")]
|
|
|
|
|
[Browsable(true), Category("DatePicker")]
|
|
|
|
|
public Color HeaderColor
|
|
|
|
|
{
|
|
|
|
|
get;
|
|
|
|
|
set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Button btn = new Button();
|
|
|
|
|
|
|
|
|
|
public DatePicker() : base()
|
|
|
|
|
{
|
|
|
|
|
this.ShowCheckBox = false;
|
|
|
|
|
this.ShowUpDown = false;
|
|
|
|
|
|
|
|
|
|
popupHelper = new PopupWindowHelper();
|
|
|
|
|
btn.Dock = System.Windows.Forms.DockStyle.Right;
|
|
|
|
|
btn.Image = Properties.Resources.calendar;
|
|
|
|
|
btn.Width = 36;
|
|
|
|
|
this.Controls.Add(btn);
|
|
|
|
|
btn.Click += ButtonClick;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnMouseDown(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseDown(e);
|
|
|
|
|
|
|
|
|
|
ButtonClick(btn, e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ButtonClick(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var btn = sender as Button;
|
|
|
|
|
Form f = FindForm();
|
|
|
|
|
var popup = new DateTimePickerEx2(HeaderColor);
|
|
|
|
|
popup.cmb_Cal = this;
|
|
|
|
|
popup.CurrentDate = Convert.ToDateTime(Value);
|
|
|
|
|
|
|
|
|
|
Value = popup.CurrentDate;
|
|
|
|
|
|
|
|
|
|
Point location = PointToScreen(new Point(btn.Left - Width + btn.Width, btn.Bottom));
|
|
|
|
|
popupHelper.ShowPopup(f, popup, location);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region Event Argument Classes
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Contains event information for a <see cref="PopupClosed"/> event.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class PopupClosedEventArgs : EventArgs
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The popup form.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private Form popup = null;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the popup form which is being closed.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Form Popup
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return this.popup;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Constructs a new instance of this class for the specified
|
|
|
|
|
/// popup form.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="popup">Popup Form which is being closed.</param>
|
|
|
|
|
public PopupClosedEventArgs(Form popup)
|
|
|
|
|
{
|
|
|
|
|
this.popup = popup;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Arguments to a <see cref="PopupCancelEvent"/>. Provides a
|
|
|
|
|
/// reference to the popup form that is to be closed and
|
|
|
|
|
/// allows the operation to be cancelled.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class PopupCancelEventArgs : EventArgs
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Whether to cancel the operation
|
|
|
|
|
/// </summary>
|
|
|
|
|
private bool cancel = false;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Mouse down location
|
|
|
|
|
/// </summary>
|
|
|
|
|
private Point location;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Popup form.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private Form popup = null;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Constructs a new instance of this class.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="popup">The popup form</param>
|
|
|
|
|
/// <param name="location">The mouse location, if any, where the
|
|
|
|
|
/// mouse event that would cancel the popup occured.</param>
|
|
|
|
|
public PopupCancelEventArgs(Form popup, Point location)
|
|
|
|
|
{
|
|
|
|
|
this.popup = popup;
|
|
|
|
|
this.location = location;
|
|
|
|
|
this.cancel = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the popup form
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Form Popup
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return this.popup;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the location that the mouse down which would cancel this
|
|
|
|
|
/// popup occurred
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Point CursorLocation
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return this.location;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets/sets whether to cancel closing the form. Set to
|
|
|
|
|
/// <c>true</c> to prevent the popup from being closed.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool Cancel
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return this.cancel;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
this.cancel = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Delegates
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represents the method which responds to a <see cref="PopupClosed"/> event.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public delegate void PopupClosedEventHandler(object sender, PopupClosedEventArgs e);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represents the method which responds to a <see cref="PopupCancel"/> event.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public delegate void PopupCancelEventHandler(object sender, PopupCancelEventArgs e);
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region PopupWindowHelper
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// A class to assist in creating popup windows like Combo Box drop-downs and Menus.
|
|
|
|
|
/// This class includes functionality to keep the title bar of the popup owner form
|
|
|
|
|
/// active whilst the popup is displayed, and to automatically cancel the popup
|
|
|
|
|
/// whenever the user clicks outside the popup window or shifts focus to another
|
|
|
|
|
/// application.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class PopupWindowHelper : NativeWindow
|
|
|
|
|
{
|
|
|
|
|
#region Unmanaged Code
|
|
|
|
|
[DllImport("user32", CharSet = CharSet.Auto)]
|
|
|
|
|
private extern static int SendMessage(IntPtr handle, int msg, int wParam, IntPtr lParam);
|
|
|
|
|
|
|
|
|
|
[DllImport("user32", CharSet = CharSet.Auto)]
|
|
|
|
|
private extern static int PostMessage(IntPtr handle, int msg, int wParam, IntPtr lParam);
|
|
|
|
|
|
|
|
|
|
private const int WM_ACTIVATE = 0x006;
|
|
|
|
|
private const int WM_ACTIVATEAPP = 0x01C;
|
|
|
|
|
private const int WM_NCACTIVATE = 0x086;
|
|
|
|
|
|
|
|
|
|
[DllImport("user32")]
|
|
|
|
|
private extern static void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
|
|
|
|
|
|
|
|
|
|
private const int KEYEVENTF_KEYUP = 0x0002;
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Member Variables
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Event Handler to detect when the popup window is closed
|
|
|
|
|
/// </summary>
|
|
|
|
|
private EventHandler popClosedHandler = null;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Message filter to detect mouse clicks anywhere in the application
|
|
|
|
|
/// whilst the popup window is being displayed.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private PopupWindowHelperMessageFilter filter = null;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The popup form that is being shown.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private Form popup = null;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The owner of the popup form that is being shown:
|
|
|
|
|
/// </summary>
|
|
|
|
|
private Form owner = null;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Whether the popup is showing or not.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private bool popupShowing = false;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Whether the popup has been cancelled, notified by PopupCancel,
|
|
|
|
|
/// rather than closed.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private bool skipClose = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Raised when the popup form is closed.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event PopupClosedEventHandler PopupClosed;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Raised when the Popup Window is about to be cancelled. The
|
|
|
|
|
/// <see cref="PopupCancelEventArgs.Cancel"/> property can be
|
|
|
|
|
/// set to <c>true</c> to prevent the form from being cancelled.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event PopupCancelEventHandler PopupCancel;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Shows the specified Form as a popup window, keeping the
|
|
|
|
|
/// Owner's title bar active and preparing to cancel the popup
|
|
|
|
|
/// should the user click anywhere outside the popup window.
|
|
|
|
|
/// <para>Typical code to use this message is as follows:</para>
|
|
|
|
|
/// <code>
|
|
|
|
|
/// frmPopup popup = new frmPopup();
|
|
|
|
|
/// Point location = this.PointToScreen(new Point(button1.Left, button1.Bottom));
|
|
|
|
|
/// popupHelper.ShowPopup(this, popup, location);
|
|
|
|
|
/// </code>
|
|
|
|
|
/// <para>Put as much initialisation code as possible
|
|
|
|
|
/// into the popup form's constructor, rather than the <see cref="System.Windows.Forms.Load"/>
|
|
|
|
|
/// event as this will improve visual appearance.</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="owner">Main form which owns the popup</param>
|
|
|
|
|
/// <param name="popup">Window to show as a popup</param>
|
|
|
|
|
/// <param name="location">Location relative to the screen to show the popup at.</param>
|
|
|
|
|
public void ShowPopup(Form owner, Form popup, Point location)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
this.owner = owner;
|
|
|
|
|
this.popup = popup;
|
|
|
|
|
|
|
|
|
|
// Start checking for the popup being cancelled
|
|
|
|
|
Application.AddMessageFilter(filter);
|
|
|
|
|
|
|
|
|
|
// Set the location of the popup form:
|
|
|
|
|
popup.StartPosition = FormStartPosition.Manual;
|
|
|
|
|
popup.Location = location;
|
|
|
|
|
// Make it owned by the window that's displaying it:
|
|
|
|
|
owner.AddOwnedForm(popup);
|
|
|
|
|
// Respond to the Closed event in case the popup
|
|
|
|
|
// is closed by its own internal means
|
|
|
|
|
popClosedHandler = new EventHandler(popup_Closed);
|
|
|
|
|
popup.Closed += popClosedHandler;
|
|
|
|
|
|
|
|
|
|
// Show the popup:
|
|
|
|
|
this.popupShowing = true;
|
|
|
|
|
popup.Show();
|
|
|
|
|
popup.Activate();
|
|
|
|
|
|
|
|
|
|
// A little bit of fun. We've shown the popup,
|
|
|
|
|
// but because we've kept the main window's
|
|
|
|
|
// title bar in focus the tab sequence isn't quite
|
|
|
|
|
// right. This can be fixed by sending a tab,
|
|
|
|
|
// but that on its own would shift focus to the
|
|
|
|
|
// second control in the form. So send a tab,
|
|
|
|
|
// followed by a reverse-tab.
|
|
|
|
|
|
|
|
|
|
// Send a Tab command:
|
|
|
|
|
keybd_event((byte)Keys.Tab, 0, 0, 0);
|
|
|
|
|
keybd_event((byte)Keys.Tab, 0, KEYEVENTF_KEYUP, 0);
|
|
|
|
|
|
|
|
|
|
// Send a reverse Tab command:
|
|
|
|
|
keybd_event((byte)Keys.ShiftKey, 0, 0, 0);
|
|
|
|
|
keybd_event((byte)Keys.Tab, 0, 0, 0);
|
|
|
|
|
keybd_event((byte)Keys.Tab, 0, KEYEVENTF_KEYUP, 0);
|
|
|
|
|
keybd_event((byte)Keys.ShiftKey, 0, KEYEVENTF_KEYUP, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Start filtering for mouse clicks outside the popup
|
|
|
|
|
filter.Popup = popup;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Responds to the <see cref="System.Windows.Forms.Form.Closed"/>
|
|
|
|
|
/// event from the popup form.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="sender">Popup form that has been closed.</param>
|
|
|
|
|
/// <param name="e">Not used.</param>
|
|
|
|
|
private void popup_Closed(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
ClosePopup();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Subclasses the owning form's existing Window Procedure to enables the
|
|
|
|
|
/// title bar to remain active when a popup is show, and to detect if
|
|
|
|
|
/// the user clicks onto another application whilst the popup is visible.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="m">Window Procedure Message</param>
|
|
|
|
|
protected override void WndProc(ref Message m)
|
|
|
|
|
{
|
|
|
|
|
base.WndProc(ref m);
|
|
|
|
|
if (this.popupShowing)
|
|
|
|
|
{
|
|
|
|
|
// check for WM_ACTIVATE and WM_NCACTIVATE
|
|
|
|
|
if (m.Msg == WM_NCACTIVATE)
|
|
|
|
|
{
|
|
|
|
|
// Check if the title bar will made inactive:
|
|
|
|
|
if (((int)m.WParam) == 0)
|
|
|
|
|
{
|
|
|
|
|
// If so reactivate it.
|
|
|
|
|
SendMessage(this.Handle, WM_NCACTIVATE, 1, IntPtr.Zero);
|
|
|
|
|
|
|
|
|
|
// Note it's no good to try and consume this message;
|
|
|
|
|
// if you try to do that you'll end up with windows
|
|
|
|
|
// that don't respond.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (m.Msg == WM_ACTIVATEAPP)
|
|
|
|
|
{
|
|
|
|
|
// Check if the application is being deactivated.
|
|
|
|
|
if ((int)m.WParam == 0)
|
|
|
|
|
{
|
|
|
|
|
// It is so cancel the popup:
|
|
|
|
|
ClosePopup();
|
|
|
|
|
// And put the title bar into the inactive state:
|
|
|
|
|
PostMessage(this.Handle, WM_NCACTIVATE, 0, IntPtr.Zero);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Called when the popup is being hidden.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void ClosePopup()
|
|
|
|
|
{
|
|
|
|
|
if (this.popupShowing)
|
|
|
|
|
{
|
|
|
|
|
if (!skipClose)
|
|
|
|
|
{
|
|
|
|
|
// Raise event to owner
|
|
|
|
|
OnPopupClosed(new PopupClosedEventArgs(this.popup));
|
|
|
|
|
}
|
|
|
|
|
skipClose = false;
|
|
|
|
|
|
|
|
|
|
// Make sure the popup is closed and we've cleaned
|
|
|
|
|
// up:
|
|
|
|
|
this.owner.RemoveOwnedForm(this.popup);
|
|
|
|
|
this.popupShowing = false;
|
|
|
|
|
this.popup.Closed -= popClosedHandler;
|
|
|
|
|
this.popClosedHandler = null;
|
|
|
|
|
this.popup.Close();
|
|
|
|
|
// No longer need to filter for clicks outside the
|
|
|
|
|
// popup.
|
|
|
|
|
Application.RemoveMessageFilter(filter);
|
|
|
|
|
|
|
|
|
|
// If we did something from the popup which shifted
|
|
|
|
|
// focus to a new form, like showing another popup
|
|
|
|
|
// or dialog, then Windows won't know how to bring
|
|
|
|
|
// the original owner back to the foreground, so
|
|
|
|
|
// force it here:
|
|
|
|
|
this.owner.Activate();
|
|
|
|
|
|
|
|
|
|
// Null out references for GC
|
|
|
|
|
this.popup = null;
|
|
|
|
|
this.owner = null;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Raises the <see cref="PopupClosed"/> event.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e"><see cref="PopupClosedEventArgs"/> describing the
|
|
|
|
|
/// popup form that is being closed.</param>
|
|
|
|
|
protected virtual void OnPopupClosed(PopupClosedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (this.PopupClosed != null)
|
|
|
|
|
{
|
|
|
|
|
this.PopupClosed(this, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void popup_Cancel(object sender, PopupCancelEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
OnPopupCancel(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Raises the <see cref="PopupCancel"/> event.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e"><see cref="PopupCancelEventArgs"/> describing the
|
|
|
|
|
/// popup form that about to be cancelled.</param>
|
|
|
|
|
protected virtual void OnPopupCancel(PopupCancelEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (this.PopupCancel != null)
|
|
|
|
|
{
|
|
|
|
|
this.PopupCancel(this, e);
|
|
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
|
|
|
|
skipClose = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Default constructor.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>Use the <see cref="System.Windows.Forms.NativeWindow.AssignHandle"/>
|
|
|
|
|
/// method to attach this class to the form you want to show popups from.</remarks>
|
|
|
|
|
public PopupWindowHelper()
|
|
|
|
|
{
|
|
|
|
|
filter = new PopupWindowHelperMessageFilter(this);
|
|
|
|
|
filter.PopupCancel += new PopupCancelEventHandler(popup_Cancel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region PopupWindowHelperMessageFilter
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// A Message Loop filter which detect mouse events whilst the popup form is shown
|
|
|
|
|
/// and notifies the owning <see cref="PopupWindowHelper"/> class when a mouse
|
|
|
|
|
/// click outside the popup occurs.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class PopupWindowHelperMessageFilter : IMessageFilter
|
|
|
|
|
{
|
|
|
|
|
private const int WM_LBUTTONDOWN = 0x201;
|
|
|
|
|
private const int WM_RBUTTONDOWN = 0x204;
|
|
|
|
|
private const int WM_MBUTTONDOWN = 0x207;
|
|
|
|
|
private const int WM_NCLBUTTONDOWN = 0x0A1;
|
|
|
|
|
private const int WM_NCRBUTTONDOWN = 0x0A4;
|
|
|
|
|
private const int WM_NCMBUTTONDOWN = 0x0A7;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Raised when the Popup Window is about to be cancelled. The
|
|
|
|
|
/// <see cref="PopupCancelEventArgs.Cancel"/> property can be
|
|
|
|
|
/// set to <c>true</c> to prevent the form from being cancelled.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event PopupCancelEventHandler PopupCancel;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The popup form
|
|
|
|
|
/// </summary>
|
|
|
|
|
private Form popup = null;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The owning <see cref="PopupWindowHelper"/> object.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private PopupWindowHelper owner = null;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Constructs a new instance of this class and sets the owning
|
|
|
|
|
/// object.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="owner">The <see cref="PopupWindowHelper"/> object
|
|
|
|
|
/// which owns this class.</param>
|
|
|
|
|
public PopupWindowHelperMessageFilter(PopupWindowHelper owner)
|
|
|
|
|
{
|
|
|
|
|
this.owner = owner;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets/sets the popup form which is being displayed.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Form Popup
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return this.popup;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
this.popup = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Checks the message loop for mouse messages whilst the popup
|
|
|
|
|
/// window is displayed. If one is detected the position is
|
|
|
|
|
/// checked to see if it is outside the form, and the owner
|
|
|
|
|
/// is notified if so.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="m">Windows Message about to be processed by the
|
|
|
|
|
/// message loop</param>
|
|
|
|
|
/// <returns><c>true</c> to filter the message, <c>false</c> otherwise.
|
|
|
|
|
/// This implementation always returns <c>false</c>.</returns>
|
|
|
|
|
public bool PreFilterMessage(ref Message m)
|
|
|
|
|
{
|
|
|
|
|
if (this.popup != null)
|
|
|
|
|
{
|
|
|
|
|
switch (m.Msg)
|
|
|
|
|
{
|
|
|
|
|
case WM_LBUTTONDOWN:
|
|
|
|
|
case WM_RBUTTONDOWN:
|
|
|
|
|
case WM_MBUTTONDOWN:
|
|
|
|
|
case WM_NCLBUTTONDOWN:
|
|
|
|
|
case WM_NCRBUTTONDOWN:
|
|
|
|
|
case WM_NCMBUTTONDOWN:
|
|
|
|
|
OnMouseDown();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Checks the mouse location and calls the OnCancelPopup method
|
|
|
|
|
/// if the mouse is outside the popup form.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void OnMouseDown()
|
|
|
|
|
{
|
|
|
|
|
// Get the cursor location
|
|
|
|
|
Point cursorPos = Cursor.Position;
|
|
|
|
|
// Check if it is within the popup form
|
|
|
|
|
if (!popup.Bounds.Contains(cursorPos))
|
|
|
|
|
{
|
|
|
|
|
// If not, then call to see if it should be closed
|
|
|
|
|
OnCancelPopup(new PopupCancelEventArgs(popup, cursorPos));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Raises the <see cref="PopupCancel"/> event.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e">The <see cref="PopupCancelEventArgs"/> associated
|
|
|
|
|
/// with the cancel event.</param>
|
|
|
|
|
protected virtual void OnCancelPopup(PopupCancelEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (this.PopupCancel != null)
|
|
|
|
|
{
|
|
|
|
|
this.PopupCancel(this, e);
|
|
|
|
|
}
|
|
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
|
|
|
|
//IsModal = false;
|
|
|
|
|
owner.ClosePopup();
|
|
|
|
|
//Debug.WriteLine(owner.IsModal.ToString());
|
|
|
|
|
// Clear reference for GC
|
|
|
|
|
popup = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|