using System; using System.Drawing; using System.Drawing.Imaging; using System.Drawing.Text; using System.Windows.Forms; using System.ComponentModel; namespace DevComponents.DotNetBar { /// /// Represents overlay class to support bubble effects on BubbleBar control. /// [ToolboxItem(false)] internal class BubbleBarOverlay:Control { #region Private Variables private BubbleBar m_BubbleBar=null; private Timer m_VisibilityTimer=null; #endregion #region Internal Implementation public BubbleBarOverlay(BubbleBar parent) { if(parent==null) throw new InvalidOperationException("Parent BubbleBar object for BubbleBarOverlay cannot be null."); m_BubbleBar=parent; this.SetStyle(ControlStyles.UserPaint,true); this.SetStyle(ControlStyles.AllPaintingInWmPaint,true); this.SetStyle(ControlStyles.Opaque,true); this.SetStyle(ControlStyles.ResizeRedraw,true); //this.SetStyle(DisplayHelp.DoubleBufferFlag,true); this.SetStyle(ControlStyles.SupportsTransparentBackColor,true); this.SetStyle(ControlStyles.ContainerControl,false); this.SetStyle(ControlStyles.Selectable,false); this.BackColor=Color.Transparent; } protected override void OnPaint(PaintEventArgs e){} internal void UpdateWindow() { // Create bitmap for drawing onto Bitmap memoryBitmap = new Bitmap(this.Width, this.Height, PixelFormat.Format32bppArgb); using(Graphics g = Graphics.FromImage(memoryBitmap)) { // Draw the background area g.Clear(Color.Transparent); g.CompositingMode=System.Drawing.Drawing2D.CompositingMode.SourceCopy; g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; g.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.AntiAlias; PaintEventArgs p=new PaintEventArgs(g,this.DisplayRectangle); m_BubbleBar.OnPaintOverlay(p); // Get hold of the screen DC IntPtr hDC = NativeFunctions.GetDC(IntPtr.Zero); // Create a memory based DC compatible with the screen DC IntPtr memoryDC = WinApi.CreateCompatibleDC(hDC); // Get access to the bitmap handle contained in the Bitmap object IntPtr hBitmap = memoryBitmap.GetHbitmap(Color.FromArgb(0)); // Select this bitmap for updating the window presentation IntPtr oldBitmap = WinApi.SelectObject(memoryDC, hBitmap); // New window size NativeFunctions.SIZE ulwsize; ulwsize.cx = this.Width; ulwsize.cy = this.Height; // New window position NativeFunctions.POINT topPos; topPos.x = this.Left; topPos.y = this.Top; // Offset into memory bitmap is always zero NativeFunctions.POINT pointSource; pointSource.x = 0; pointSource.y = 0; // We want to make the entire bitmap opaque NativeFunctions.BLENDFUNCTION blend = new NativeFunctions.BLENDFUNCTION(); blend.BlendOp = (byte)NativeFunctions.Win23AlphaFlags.AC_SRC_OVER; blend.BlendFlags = 0; blend.SourceConstantAlpha = 255; blend.AlphaFormat = (byte)NativeFunctions.Win23AlphaFlags.AC_SRC_ALPHA; // Tell operating system to use our bitmap for painting NativeFunctions.UpdateLayeredWindow(this.Handle, hDC, ref topPos, ref ulwsize, memoryDC, ref pointSource, 0, ref blend, (int)NativeFunctions.Win32UpdateLayeredWindowsFlags.ULW_ALPHA); // Put back the old bitmap handle WinApi.SelectObject(memoryDC, oldBitmap); // Cleanup resources WinApi.ReleaseDC(IntPtr.Zero, hDC); WinApi.DeleteObject(hBitmap); WinApi.DeleteDC(memoryDC); } } protected override void OnMouseEnter(EventArgs e) { this.Capture=true; base.OnMouseEnter (e); } protected override void OnMouseMove(MouseEventArgs e) { if(!this.DisplayRectangle.Contains(e.X,e.Y)) this.Capture=false; m_BubbleBar.MouseMoveMessage(e); base.OnMouseMove (e); } protected override void OnMouseLeave(EventArgs e) { m_BubbleBar.MouseLeaveMessage(e); base.OnMouseLeave(e); } protected override void OnMouseDown(MouseEventArgs e) { m_BubbleBar.OverlayMouseDownMessage(e); base.OnMouseDown (e); } protected override void OnMouseUp(MouseEventArgs e) { m_BubbleBar.OverlayMouseUpMessage(e); base.OnMouseUp(e); } protected override void WndProc(ref Message m) { const int WM_MOUSEACTIVATE = 0x21; const int MA_NOACTIVATE = 3; if(m.Msg==WM_MOUSEACTIVATE) { m.Result=new System.IntPtr(MA_NOACTIVATE); return; } base.WndProc(ref m); } protected override CreateParams CreateParams { get { const uint WS_POPUP=0x80000000; const uint WS_CLIPSIBLINGS=0x04000000; const uint WS_CLIPCHILDREN=0x02000000; const int WS_EX_LAYERED=0x00080000; const int WS_EX_TOOLWINDOW=0x00000080; CreateParams p=base.CreateParams; p.ExStyle=(p.ExStyle | WS_EX_LAYERED | WS_EX_TOOLWINDOW); p.Style=unchecked((int)(WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)); p.Caption=""; return p; } } private void CreateTimer() { if(m_VisibilityTimer!=null) return; m_VisibilityTimer=new Timer(); m_VisibilityTimer.Tick+=new EventHandler(this.CheckVisibility); m_VisibilityTimer.Interval=500; m_VisibilityTimer.Enabled=true; m_VisibilityTimer.Start(); } private void DestroyTimer() { if(m_VisibilityTimer==null) return; m_VisibilityTimer.Stop(); m_VisibilityTimer.Enabled=false; m_VisibilityTimer.Dispose(); m_VisibilityTimer=null; } private void CheckVisibility(object sender,EventArgs e) { try { BubbleBar bar = m_BubbleBar; if (bar == null || bar.IsDisposed) { DestroyTimer(); return; } Form form = bar.FindForm(); IntPtr foregroundWindow = NativeFunctions.GetForegroundWindow(); Control c = null; if (foregroundWindow != IntPtr.Zero) c = Control.FromHandle(foregroundWindow); if (c == null) { OnOverlayInactive(); return; } if (form != null) { if (Form.ActiveForm == form) return; Form parentForm = form; while (parentForm.ParentForm != null) { if (parentForm.ParentForm == Form.ActiveForm) return; parentForm = parentForm.ParentForm; } if (form.IsMdiChild && form.MdiParent != null) { if (form.MdiParent.ActiveMdiChild == form) return; } } NativeFunctions.POINT p = new NativeFunctions.POINT(); Point pm = Control.MousePosition; p.x = pm.X; p.x = pm.Y; IntPtr window = IntPtr.Zero; if (bar.Parent != null) NativeFunctions.ChildWindowFromPoint(bar.Parent.Handle, p); if (window == IntPtr.Zero) { window = NativeFunctions.WindowFromPoint(p); } if (window != IntPtr.Zero && window != this.Handle && window != bar.Handle && bar.Parent != null && bar.Parent.Handle != window) { OnOverlayInactive(); } else { Point pc = this.PointToClient(pm); if (!this.DisplayRectangle.Contains(pc)) { bar.MouseLeaveMessage(e); } } } catch (NullReferenceException) { DestroyTimer(); } } private void OnOverlayInactive() { this.Capture=false; DestroyTimer(); m_BubbleBar.OverlayInactive(); } /// /// Called just before window is shown. /// internal void BeforeShow() { CreateTimer(); } /// /// Called after window is closed. /// internal void AfterClose() { DestroyTimer(); } #endregion } }