private static IntPtr ShellProc(int code, IntPtr wParam, IntPtr lParam) { if (code == PI.HSHELL_REDRAW) { try { if (_forms.TryGetValue(wParam, out Form f)) { FlashEvent(f, (int)lParam == 1); } } catch { // } } return(PI.CallNextHookEx(_hHook, code, wParam, lParam)); }
/// <summary> /// Process Windows-based messages. /// </summary> /// <param name="m">A Windows-based message.</param> protected override void WndProc(ref Message m) { // We need to snoop the need to show a context menu if (m.Msg == PI.WM_CONTEXTMENU) { // Only interested in overriding the behavior when we have a krypton context menu... if (KryptonContextMenu != null) { // Extract the screen mouse position (if might not actually be provided) Point mousePt = new Point(PI.LOWORD(m.LParam), PI.HIWORD(m.LParam)); // If keyboard activated, the menu position is centered if (((int)((long)m.LParam)) == -1) { mousePt = new Point(Width / 2, Height / 2); } else { mousePt = PointToClient(mousePt); // Mouse point up and left 1 pixel so that the mouse overlaps the top left corner // of the showing context menu just like it happens for a ContextMenuStrip. mousePt.X -= 1; mousePt.Y -= 1; } // If the mouse posiiton is within our client area if (ClientRectangle.Contains(mousePt)) { // Show the context menu KryptonContextMenu.Show(this, PointToScreen(mousePt)); // We eat the message! return; } } } if (!IsDisposed) { base.WndProc(ref m); } }
private bool ProcessMouseMoveWithCMS(ref Message m) { if (_current == null) { return(false); } // Convert the client position to screen point Point screenPt = CommonHelper.ClientMouseMessageToScreenPt(m); // Convert from a class to a structure PI.POINT screenPIPt = new PI.POINT { x = screenPt.X, y = screenPt.Y }; // Get the window handle of the window under this screen point IntPtr hWnd = PI.WindowFromPoint(screenPIPt); // Is the window handle that of the currently tracking popup if (_current.Handle == hWnd) { return(true); } // Search all the stacked popups for any that match the window handle VisualPopup[] popups = _stack.ToArray(); for (int i = 0; i < popups.Length; i++) { if (!popups[i].IsDisposed) { if (popups[i].Handle == hWnd) { return(true); } } } // Mouse move is not over a popup, so allow it return(false); }
static FlashWindowExListener() { int processId = PI.GetCurrentThreadId(); // create an instance of the delegate that // won't be garbage collected to avoid: // Managed Debugging Assistant 'CallbackOnCollectedDelegate' :** // 'A callback was made on a garbage collected delegate of type // 'WpfApp1!WpfApp1.MainWindow+NativeMethods+CBTProc::Invoke'. // This may cause application crashes, corruption and data loss. // When passing delegates to unmanaged code, they must be // kept alive by the managed application until it is guaranteed // that they will never be called.' _hookProc = ShellProc; // we are interested in listening to WH_SHELL events, mainly the HSHELL_REDRAW event. _hHook = PI.SetWindowsHookEx(PI.WH_.SHELL, _hookProc, IntPtr.Zero, processId); Application.ApplicationExit += delegate { PI.UnhookWindowsHookEx(_hHook); }; }
private bool ProcessNonClientMouseDown(ref Message m) { // Extract the x and y mouse position from message Point screenPt = new Point(PI.LOWORD((int)m.LParam), PI.HIWORD((int)m.LParam)); // Ask the popup if this message causes the entire stack to be killed if (_current.DoesCurrentMouseDownEndAllTracking(m, ScreenPtToClientPt(screenPt))) { EndAllTracking(); } // Do any of the current popups want the mouse down to be eaten? bool processed = false; if (_current != null) { processed = _current.DoesMouseDownGetEaten(m, screenPt); if (!processed) { // Search from end towards the front, the last entry is the most recent 'Push' VisualPopup[] popups = _stack.ToArray(); for (int i = 0; i < popups.Length; i++) { // Ignore disposed popups VisualPopup popup = popups[i]; if (!popup.IsDisposed) { processed = popup.DoesMouseDownGetEaten(m, screenPt); if (processed) { break; } } } } } return(processed); }
private static string InternalShow(IWin32Window owner, string prompt, string caption, string defaultResponse) { IWin32Window showOwner = null; // If do not have an owner passed in then get the active window and use that instead if (owner == null) { showOwner = Control.FromHandle(PI.GetActiveWindow()); } else { showOwner = owner; } // Show input box window as a modal dialog and then dispose of it afterwards using (KryptonInputBox ib = new KryptonInputBox(prompt, caption, defaultResponse)) { if (showOwner == null) { ib.StartPosition = FormStartPosition.CenterScreen; } else { ib.StartPosition = FormStartPosition.CenterParent; } if (ib.ShowDialog(showOwner) == DialogResult.OK) { return(ib.InputResponse); } else { return(string.Empty); } } }
public virtual void Paint(RenderContext context) { Debug.Assert(context != null); Debug.Assert(Root != null); // Validate incoming reference if (context == null) { throw new ArgumentNullException("context"); } // Do nothing if the control is disposed or inside a layout call if (!_control.IsDisposed) { if (_outputDebug) { PI.QueryPerformanceCounter(ref _outputStart); } // Ask the view to paint itself Root.Render(context); if (_outputDebug) { long outputEnd = 0; PI.QueryPerformanceCounter(ref outputEnd); long outputDiff = outputEnd - _outputStart; Console.WriteLine("Id:{0} Paint Type:{1} Elapsed: {2}", Id, _control.GetType().ToString(), outputDiff.ToString()); } } // Maintain internal counters for measuring perf _paintCounter++; }
/// <summary> /// Should a mouse down at the provided point cause an end to popup tracking. /// </summary> /// <param name="m">Original message.</param> /// <param name="pt">Client coordinates point.</param> /// <returns>True to end tracking; otherwise false.</returns> public virtual bool DoesCurrentMouseDownEndAllTracking(Message m, Point pt) { bool endTracking = !ClientRectangle.Contains(pt); // The mouse is not over our client area but the focus is if (endTracking && ContainsFocus) { // Get the window handle of the window under this screen point Point screenPt = PointToScreen(pt); PI.POINT screenPIPt = new PI.POINT { X = screenPt.X, Y = screenPt.Y }; IntPtr hWnd = PI.WindowFromPoint(screenPIPt); // Assuming we got back a valid window handle if (hWnd != IntPtr.Zero) { StringBuilder className = new StringBuilder(256); int length = PI.GetClassName(hWnd, className, className.Capacity); // If we got back a valid name if (length > 0) { // If let the message occur as it is being pressed on a combo box // drop down list and so it will process the message appropriately if (className.ToString() == "ComboLBox") { endTracking = false; } } } } return(endTracking); }
public bool PreFilterMessage(ref Message m) { // If we have suspended operation.... if (_suspended > 0) { // Intercept the non-client mouse move to prevent the custom // chrome of the form from providing hot tracking feedback if (m.Msg == PI.WM_NCMOUSEMOVE) { return(true); } // A mouse move can occur because a context menu is showing with a popup also // already showing. We suppress the mouse move to prevent tracking of the popup if (m.Msg == PI.WM_MOUSEMOVE) { return(ProcessMouseMoveWithCMS(ref m)); } return(false); } if (_current != null) { // If the popup has been become disposed if (_current.IsDisposed) { EndCurrentTracking(); return(false); } else { // Get the active window IntPtr activeWindow = PI.GetActiveWindow(); // Is there a change in active window? if (activeWindow != _activeWindow) { // If the current window has become active, ask popup if that is allowed if ((activeWindow == _current.Handle) && _current.AllowBecomeActiveWhenCurrent) { _activeWindow = _current.Handle; } else { bool focus = _current.ContainsFocus; if (!focus) { VisualPopup[] popups = _stack.ToArray(); // For from last to first for any popup that has the focus for (int i = popups.Length - 1; i >= 0; i--) { if (!popups[i].IsDisposed) { if (popups[i].ContainsFocus) { focus = true; break; } } } } // If the change in active window (focus) is not to the current // or a stacked popup then we need to pull down the entire stack // as focus has been shifted away from the use of any popup. if (!focus) { EndAllTracking(); return(false); } } } } // We only intercept and handle keyboard and mouse messages if (!IsKeyOrMouseMessage(ref m)) { return(false); } switch (m.Msg) { case PI.WM_KEYDOWN: case PI.WM_SYSKEYDOWN: // If the popup is telling us to redirect keyboard to itself if (!_current.KeyboardInert) { // If the focus is not inside the actual current tracking popup // then we need to manually translate the message to ensure that // KeyPress events occur for the current popup. if (!_current.ContainsFocus) { PI.MSG msg = new PI.MSG { hwnd = m.HWnd, message = m.Msg, lParam = m.LParam, wParam = m.WParam }; PI.TranslateMessage(ref msg); } return(ProcessKeyboard(ref m)); } break; case PI.WM_CHAR: case PI.WM_KEYUP: case PI.WM_DEADCHAR: case PI.WM_SYSCHAR: case PI.WM_SYSKEYUP: case PI.WM_SYSDEADCHAR: // If the popup is telling us to redirect keyboard to itself if (!_current.KeyboardInert) { return(ProcessKeyboard(ref m)); } break; case PI.WM_MOUSEMOVE: case PI.WM_NCMOUSEMOVE: return(ProcessMouseMove(ref m)); case PI.WM_LBUTTONDOWN: case PI.WM_RBUTTONDOWN: case PI.WM_MBUTTONDOWN: return(ProcessClientMouseDown(ref m)); case PI.WM_NCLBUTTONDOWN: case PI.WM_NCRBUTTONDOWN: case PI.WM_NCMBUTTONDOWN: return(ProcessNonClientMouseDown(ref m)); } } return(false); }
/// <summary> /// Show the window without taking activation. /// </summary> public void ShowWithoutActivate() { // Show the window without activating it (i.e. do not take focus) PI.ShowWindow(this.Handle, (short)PI.SW_SHOWNOACTIVATE); }
internal static extern bool EndPaint(IntPtr hwnd, ref PI.PAINTSTRUCT ps);
public DialogResult ShowDialog() { return(ShowDialog(Control.FromHandle(PI.GetActiveWindow()))); }
/// <summary> /// Draw text with a glowing background, for use on a composition element. /// </summary> /// <param name="g">Graphics reference.</param> /// <param name="text">Text to be drawn.</param> /// <param name="font">Font to use for text.</param> /// <param name="bounds">Bounding area for the text.</param> /// <param name="state">State of the source element.</param> /// <param name="color">Color of the text.</param> /// <param name="copyBackground">Should existing background be copied into the bitmap.</param> public static void DrawCompositionGlowingText(Graphics g, string text, Font font, Rectangle bounds, PaletteState state, Color color, bool copyBackground) { try { // Get the hDC for the graphics instance and create a memory DC IntPtr gDC = g.GetHdc(); IntPtr mDC = PI.CreateCompatibleDC(gDC); PI.BITMAPINFO bmi = new PI.BITMAPINFO(); bmi.biSize = Marshal.SizeOf(bmi); bmi.biWidth = bounds.Width; bmi.biHeight = -(bounds.Height + GLOW_EXTRA_HEIGHT * 2); bmi.biCompression = 0; bmi.biBitCount = 32; bmi.biPlanes = 1; // Create a device independant bitmp and select into the memory DC IntPtr hDIB = PI.CreateDIBSection(gDC, bmi, 0, 0, IntPtr.Zero, 0); PI.SelectObject(mDC, hDIB); if (copyBackground) { // Copy existing background into the bitmap PI.BitBlt(mDC, 0, 0, bounds.Width, bounds.Height + GLOW_EXTRA_HEIGHT * 2, gDC, bounds.X, bounds.Y - GLOW_EXTRA_HEIGHT, 0x00CC0020); } // Select the font for use when drawing IntPtr hFont = font.ToHfont(); PI.SelectObject(mDC, hFont); // Get renderer for the correct state VisualStyleRenderer renderer = new VisualStyleRenderer(state == PaletteState.Normal ? VisualStyleElement.Window.Caption.Active : VisualStyleElement.Window.Caption.Inactive); // Create structures needed for theme drawing call PI.RECT textBounds = new PI.RECT(); textBounds.left = 0; textBounds.top = 0; textBounds.right = (bounds.Right - bounds.Left); textBounds.bottom = (bounds.Bottom - bounds.Top) + (GLOW_EXTRA_HEIGHT * 2); PI.DTTOPTS dttOpts = new PI.DTTOPTS(); dttOpts.dwSize = Marshal.SizeOf(typeof(PI.DTTOPTS)); dttOpts.dwFlags = PI.DTT_COMPOSITED | PI.DTT_GLOWSIZE | PI.DTT_TEXTCOLOR; dttOpts.crText = ColorTranslator.ToWin32(color); dttOpts.iGlowSize = 11; // Always draw text centered TextFormatFlags textFormat = TextFormatFlags.SingleLine | TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis; // Perform actual drawing PI.DrawThemeTextEx(renderer.Handle, mDC, 0, 0, text, -1, (int)textFormat, ref textBounds, ref dttOpts); // Copy to foreground PI.BitBlt(gDC, bounds.Left, bounds.Top - GLOW_EXTRA_HEIGHT, bounds.Width, bounds.Height + (GLOW_EXTRA_HEIGHT * 2), mDC, 0, 0, 0x00CC0020); // Dispose of allocated objects PI.DeleteObject(hFont); PI.DeleteObject(hDIB); PI.DeleteDC(mDC); // Must remember to release the hDC g.ReleaseHdc(gDC); } catch { } }
public WindowStylesHelper(IntPtr handle) { WinStyle = PI.GetWindowLong(handle, PI.GWL_.STYLE); WinExStyle = PI.GetWindowLong(handle, PI.GWL_.EXSTYLE); }
internal static extern IntPtr WindowFromPoint(PI.POINT pt);
internal static extern bool RedrawWindow(IntPtr hWnd, ref PI.RECT rectUpdate, IntPtr hRgnUpdate, uint uFlags);
void ForwardMessage(IWin32Window control, ref Message m) { PI.SendMessage(control.Handle, m.Msg, m.WParam, m.LParam); }
protected override void OnPaint(PaintEventArgs e) { var outerBounds = new Rectangle(0, 0, Width, Height); using (var target = new Bitmap(outerBounds.Width, outerBounds.Height, PixelFormat.Format32bppArgb)) { using (var targetGraphics = Graphics.FromImage(target)) { // The top and bottom borders extend over the sides of the window. // The left and right borders do no. This means that we need to // update the bounds to make it seem like the left and right // borders do extend outside of the window. if (Border == DropShadowBorder.Left || Border == DropShadowBorder.Right) { outerBounds = new Rectangle( outerBounds.Left, outerBounds.Top - _borderWidth, outerBounds.Width, outerBounds.Height + _borderWidth * 2 ); } if (Border == DropShadowBorder.Left || Border == DropShadowBorder.Top) { DrawImage(targetGraphics, _imageCache.CornerNW, new Point(outerBounds.Left, outerBounds.Top) ); } if (Border == DropShadowBorder.Right || Border == DropShadowBorder.Top) { DrawImage(targetGraphics, _imageCache.CornerNE, new Point(outerBounds.Right - _cornerSize, outerBounds.Top) ); } if (Border == DropShadowBorder.Bottom || Border == DropShadowBorder.Left) { DrawImage(targetGraphics, _imageCache.CornerSW, new Point(outerBounds.Left, outerBounds.Bottom - _cornerSize) ); } if (Border == DropShadowBorder.Bottom || Border == DropShadowBorder.Right) { DrawImage(targetGraphics, _imageCache.CornerSE, new Point(outerBounds.Right - _cornerSize, outerBounds.Bottom - _cornerSize) ); } if (Border == DropShadowBorder.Top) { DrawBorder(targetGraphics, _imageCache.BorderN, new Rectangle( outerBounds.Left + _cornerSize, outerBounds.Top, outerBounds.Width - _cornerSize * 2, _borderWidth ) ); } if (Border == DropShadowBorder.Bottom) { DrawBorder(targetGraphics, _imageCache.BorderS, new Rectangle( outerBounds.Left + _cornerSize, outerBounds.Bottom - _borderWidth, outerBounds.Width - _cornerSize * 2, _borderWidth ) ); } if (Border == DropShadowBorder.Left) { DrawBorder(targetGraphics, _imageCache.BorderW, new Rectangle( outerBounds.Left, outerBounds.Top + _cornerSize, _borderWidth, outerBounds.Height - _cornerSize * 2 ) ); } if (Border == DropShadowBorder.Right) { DrawBorder(targetGraphics, _imageCache.BorderE, new Rectangle( outerBounds.Right - _borderWidth, outerBounds.Top + _cornerSize, _borderWidth, outerBounds.Height - _cornerSize * 2 ) ); } } // Get device contexts var screenDc = PI.GetDC(IntPtr.Zero); var memDc = PI.CreateCompatibleDC(screenDc); var hBitmap = IntPtr.Zero; var hOldBitmap = IntPtr.Zero; try { // Get handle to the new bitmap and select it into the current device context hBitmap = target.GetHbitmap(Color.FromArgb(0)); hOldBitmap = PI.SelectObject(memDc, hBitmap); // Set parameters for layered window update var newSize = new PI.SIZE(target.Size); // Size window to match bitmap var sourceLocation = new PI.POINT(Point.Empty); var newLocation = new PI.POINT(Location); // Same as this window var blend = new PI.BLENDFUNCTION { BlendOp = PI.AC_SRC_OVER, // Only works with a 32bpp bitmap BlendFlags = 0, // Always 0 SourceConstantAlpha = 255, // Set to 255 for per-pixel alpha values AlphaFormat = PI.AC_SRC_ALPHA // Only works when the bitmap contains an alpha channel }; // Update the window PI.UpdateLayeredWindow( Handle, screenDc, ref newLocation, ref newSize, memDc, ref sourceLocation, 0, ref blend, PI.ULW_ALPHA ); } finally { // Release device context PI.ReleaseDC(IntPtr.Zero, screenDc); if (hBitmap != IntPtr.Zero) { PI.SelectObject(memDc, hOldBitmap); PI.DeleteObject(hBitmap); // Remove bitmap resources } PI.DeleteDC(memDc); } } }
/// <summary> /// Draw text without a glowing background, for use on a composition element. /// </summary> /// <param name="g">Graphics reference.</param> /// <param name="text">Text to be drawn.</param> /// <param name="font">Font to use for text.</param> /// <param name="bounds">Bounding area for the text.</param> /// <param name="state">State of the source element.</param> /// <param name="color"><see cref="Color"/> of the text.</param> /// <param name="copyBackground">Should existing background be copied into the bitmap.</param> /// <param name="sf">StringFormat of the memento.</param> public static void DrawCompositionText(Graphics g, string text, Font font, Rectangle bounds, PaletteState state, Color color, bool copyBackground, StringFormat sf) { // Get the hDC for the graphics instance and create a memory DC IntPtr gDC = g.GetHdc(); try { IntPtr mDC = PI.CreateCompatibleDC(gDC); PI.BITMAPINFO bmi = new PI.BITMAPINFO { biWidth = bounds.Width, biHeight = -(bounds.Height), biCompression = 0, biBitCount = 32, biPlanes = 1 }; bmi.biSize = (uint)Marshal.SizeOf(bmi); // Create a device independent bitmap and select into the memory DC IntPtr hDIB = PI.CreateDIBSection(gDC, ref bmi, 0, out _, IntPtr.Zero, 0); PI.SelectObject(mDC, hDIB); if (copyBackground) { // Copy existing background into the bitmap PI.BitBlt(mDC, 0, 0, bounds.Width, bounds.Height, gDC, bounds.X, bounds.Y, 0x00CC0020); } // Select the font for use when drawing IntPtr hFont = font.ToHfont(); PI.SelectObject(mDC, hFont); // Get renderer for the correct state VisualStyleRenderer renderer = new VisualStyleRenderer(state == PaletteState.Normal ? VisualStyleElement.Window.Caption.Active : VisualStyleElement.Window.Caption.Inactive); // Create structures needed for theme drawing call PI.RECT textBounds = new PI.RECT { left = 0, top = 0, right = (bounds.Right - bounds.Left), bottom = (bounds.Bottom - bounds.Top) }; PI.DTTOPTS dttOpts = new PI.DTTOPTS { dwSize = Marshal.SizeOf(typeof(PI.DTTOPTS)), dwFlags = PI.DTT_COMPOSITED | PI.DTT_TEXTCOLOR, crText = ColorTranslator.ToWin32(color) }; // Always draw text centered TextFormatFlags textFormat = TextFormatFlags.SingleLine | TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter; ////Seb | TextFormatFlags.EndEllipsis; // Perform actual drawing //PI.DrawThemeTextEx(renderer.Handle, // mDC, 0, 0, // text, -1, (int)StringFormatToFlags(sf), // ref textBounds, ref dttOpts); PI.DrawThemeTextEx(renderer.Handle, mDC, 0, 0, text, -1, (int)textFormat, ref textBounds, ref dttOpts); // Copy to foreground PI.BitBlt(gDC, bounds.Left, bounds.Top, bounds.Width, bounds.Height, mDC, 0, 0, 0x00CC0020); // Dispose of allocated objects PI.DeleteObject(hFont); PI.DeleteObject(hDIB); PI.DeleteDC(mDC); } catch { // ignored } finally { // Must remember to release the hDC g.ReleaseHdc(gDC); } }
internal static extern IntPtr BeginPaint(IntPtr hwnd, ref PI.PAINTSTRUCT ps);