using System; using System.Windows.Forms; namespace SmartCoalApplication.SystemLayer { public sealed class FormEx : Control { private Form host; private RealParentWndProcDelegate realParentWndProc; private bool forceActiveTitleBar = false; public bool ForceActiveTitleBar { get { return this.forceActiveTitleBar; } set { this.forceActiveTitleBar = value; } } public FormEx(Form host, RealParentWndProcDelegate realParentWndProc) { this.host = host; this.realParentWndProc = realParentWndProc; } public class ProcessCmdKeyEventArgs : EventArgs { private bool handled; public bool Handled { get { return this.handled; } set { this.handled = value; } } private Keys keyData; public Keys KeyData { get { return this.keyData; } } public ProcessCmdKeyEventArgs(Keys keyData, bool handled) { this.keyData = keyData; this.handled = handled; } } public event EventHandler ProcessCmdKeyRelay; public bool RelayProcessCmdKey(Keys keyData) { bool handled = false; if (ProcessCmdKeyRelay != null) { ProcessCmdKeyEventArgs e = new ProcessCmdKeyEventArgs(keyData, false); ProcessCmdKeyRelay(this, e); handled = e.Handled; } return handled; } internal static FormEx FindFormEx(Form host) { if (host != null) { Control.ControlCollection controls = host.Controls; for (int i = 0; i < controls.Count; ++i) { FormEx formEx = controls[i] as FormEx; if (formEx != null) { return formEx; } } } return null; } private int ignoreNcActivate = 0; /// /// Manages some special handling of window messages. /// /// /// true if the message was handled, false if the caller should handle the message. public bool HandleParentWndProc(ref Message mess) { bool returnVal = true; switch (mess.Msg) { case NativeConstants.WM_NCPAINT: goto default; case NativeConstants.WM_NCACTIVATE: if (this.forceActiveTitleBar && mess.WParam == IntPtr.Zero) { if (ignoreNcActivate > 0) { --ignoreNcActivate; goto default; } else if (Form.ActiveForm != this.host || // Gets rid of: if you have the form active, then click on the desktop --> desktop refreshes !this.host.Visible) // Gets rid of: desktop refresh on exit { goto default; } else { bool locked = false; if (this.host.Owner == null && this.host.WindowState != FormWindowState.Minimized) { locked = true; } this.realParentWndProc(ref mess); SafeNativeMethods.SendMessageW(this.host.Handle, NativeConstants.WM_NCACTIVATE, new IntPtr(1), IntPtr.Zero); if (locked) { //UI.SetControlRedraw(this.host, true); //this.host.Invalidate(true); } break; } } else { goto default; } case NativeConstants.WM_ACTIVATE: goto default; case NativeConstants.WM_ACTIVATEAPP: this.realParentWndProc(ref mess); // Check if the app is being deactivated if (this.forceActiveTitleBar && mess.WParam == IntPtr.Zero) { // If so, put our titlebar in the inactive state SafeNativeMethods.PostMessageW(this.host.Handle, NativeConstants.WM_NCACTIVATE, IntPtr.Zero, IntPtr.Zero); ++ignoreNcActivate; } if (mess.WParam == new IntPtr(1)) { foreach (Form childForm in this.host.OwnedForms) { FormEx childFormEx = FindFormEx(childForm); if (childFormEx != null) { if (childFormEx.ForceActiveTitleBar && childForm.IsHandleCreated) { SafeNativeMethods.PostMessageW(childForm.Handle, NativeConstants.WM_NCACTIVATE, new IntPtr(1), IntPtr.Zero); } } } FormEx ownerEx = FindFormEx(this.host.Owner); if (ownerEx != null) { if (ownerEx.ForceActiveTitleBar && this.host.Owner.IsHandleCreated) { SafeNativeMethods.PostMessageW(this.host.Owner.Handle, NativeConstants.WM_NCACTIVATE, new IntPtr(1), IntPtr.Zero); } } } break; default: returnVal = false; break; } GC.KeepAlive(this.host); return returnVal; } } }