示例#1
0
        // TODO: also return the int given by HandlerNativeMethods.GetWindowThreadProcessId?
        public static int GetWindowThreadProcessId(IntPtr activatedHandle)

        {
            _ = HandlerNativeMethods.GetWindowThreadProcessId(activatedHandle, out int activeProcId);

            return(activeProcId);
        }
示例#2
0
 public static void SetWindowStylesEx(IntPtr hwnd, WindowStylesEx styles)
 {
     if (HandlerNativeMethods.SetWindowLongPtr(hwnd, GetWindowLongEnum.ExStyle, (uint)styles) == 0)
     {
         Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
     }
 }
        /// <summary>
        /// Captures a screenshot of the specified window at the specified
        /// bitmap size. <para/>NOTE: This method will not accurately capture controls
        /// that are hidden or obstructed (partially or completely) by another control (e.g. hidden tabs,
        /// or MDI child windows that are obstructed by other child windows/forms).
        /// </summary>
        /// <param name="windowHandle">The window handle.</param>
        /// <param name="bitmapSize">The requested bitmap size.</param>
        /// <returns>A screen capture of the window.</returns>
        public static Bitmap GrabWindowBitmap(IntPtr windowHandle, System.Drawing.Size bitmapSize)
        {
            if (bitmapSize.Height <= 0 || bitmapSize.Width <= 0)
            {
                return(null);
            }

            IntPtr windowDC = IntPtr.Zero;

            try
            {
                windowDC = HandlerNativeMethods.GetWindowDC(windowHandle);

                _ = HandlerNativeMethods.GetClientSize(windowHandle, out System.Drawing.Size realWindowSize);

                if (realWindowSize == System.Drawing.Size.Empty)
                {
                    realWindowSize = new System.Drawing.Size(200, 200);
                }

                System.Drawing.Size size = (bitmapSize == System.Drawing.Size.Empty) ?
                                           realWindowSize : bitmapSize;

                Bitmap targetBitmap = null;

                try
                {
                    targetBitmap = new Bitmap(size.Width, size.Height);

                    using (var targetGr = Graphics.FromImage(targetBitmap))
                    {
                        IntPtr targetDC  = targetGr.GetHdc();
                        uint   operation = 0x00CC0020 /*SRCCOPY*/;

                        System.Drawing.Size ncArea = Shell.DesktopWindowManager.GetNonClientArea(windowHandle);

                        bool success = GDI.StretchBlt(
                            targetDC, 0, 0, targetBitmap.Width, targetBitmap.Height,
                            windowDC, ncArea.Width, ncArea.Height, realWindowSize.Width,
                            realWindowSize.Height, operation);

                        targetGr.ReleaseHdc(targetDC);

                        return(success ? targetBitmap : null);
                    }
                }
                catch
                {
                    targetBitmap?.Dispose();
                    throw;
                }
            }
            finally
            {
                if (windowDC != IntPtr.Zero)
                {
                    _ = HandlerNativeMethods.ReleaseDC(windowHandle, windowDC);
                }
            }
        }
示例#4
0
        public static void SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, SetWindowPositionOptions windowPositionOptions)

        {
            if (!HandlerNativeMethods.SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, windowPositionOptions))
            {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
            }
        }
示例#5
0
        /// <summary>
        /// Updates the placement of the Control.
        /// </summary>
        protected void UpdatePlacement()
        {
            if (_source != null)
            {
                HandlerNativeMethods.SetParent(_source.Handle, _parentHandle);

                HandlerNativeMethods.SetWindowPos(_source.Handle, new IntPtr((int)SetWindowPositionInsertAfter.Top),
                                                  0, 0, Math.Abs(_bounds.Left - _bounds.Right), Math.Abs(_bounds.Top - _bounds.Bottom), SetWindowPositionOptions.ShowWindow);
            }
        }
示例#6
0
        public static System.Drawing.Size GetNonClientArea(IntPtr hwnd)
        {
            var c = new NativePoint();

            _ = HandlerNativeMethods.ClientToScreen(hwnd, ref c);

            _ = HandlerNativeMethods.GetWindowRect(hwnd, out NativeRect r);

            return(new System.Drawing.Size(c.X - r.Left, c.Y - r.Top));
        }
示例#7
0
        public static WindowStylesEx GetWindowStylesEx(IntPtr hwnd)
        {
            int result = HandlerNativeMethods.GetWindowLongPtr(hwnd, GetWindowLongEnum.ExStyle);

            if (result == 0)
            {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
            }

            return((WindowStylesEx)result);
        }
示例#8
0
        public static System.Drawing.Point GetParentOffsetOfChild(IntPtr hwnd, IntPtr hwndParent)
        {
            var childScreenCoord = new NativePoint();

            _ = HandlerNativeMethods.ClientToScreen(hwnd, ref childScreenCoord);

            var parentScreenCoord = new NativePoint();

            _ = HandlerNativeMethods.ClientToScreen(hwndParent, ref parentScreenCoord);

            var offset = new System.Drawing.Point(
                childScreenCoord.X - parentScreenCoord.X,
                childScreenCoord.Y - parentScreenCoord.Y);

            return(offset);
        }
        internal static void AddTabbedThumbnail(TabbedThumbnail preview)
        {
            // Create a TOP-LEVEL proxy window for the user's source window/control
            TaskbarWindow taskbarWindow = preview.WindowHandle == IntPtr.Zero
                ? GetTaskbarWindow(preview.WindowsControl, TaskbarProxyWindowType.TabbedThumbnail)
                : GetTaskbarWindow(preview.WindowHandle, TaskbarProxyWindowType.TabbedThumbnail);

            // get the TaskbarWindow for UIElement/WindowHandle respectfully.

            //create taskbar, or set its TabbedThumbnail
            if (taskbarWindow == null)
            {
                taskbarWindow = new TaskbarWindow(preview);
                _taskbarWindowList.Add(taskbarWindow);
            }

            else if (taskbarWindow.TabbedThumbnail == null)

                taskbarWindow.TabbedThumbnail = preview;

            // Listen for Title changes
            preview.TitleChanged += new EventHandler(ThumbnailPreview_TitleChanged);
            preview.TooltipChanged += new EventHandler(ThumbnailPreview_TooltipChanged);

            // Get/Set properties for proxy window
            IntPtr windowHandle = taskbarWindow.WindowToTellTaskbarAbout;

            // Register this new tab and set it as being active.
            TaskbarList.Instance.RegisterTab(windowHandle, preview.ParentWindowHandle);
            TaskbarList.Instance.SetTabOrder(windowHandle, IntPtr.Zero);
            TaskbarList.Instance.SetTabActive(windowHandle, preview.ParentWindowHandle, 0);

            // We need to make sure we can set these properties even when running with admin 

            var changeFilterResult = new ChangeFilterStruct
            {
                cbSize = (uint)Marshal.SizeOf
#if CS7
                <
#else
                (typeof(
#endif
                ChangeFilterStruct
#if CS7
                >(
#else
                )
#endif
                )
            };

            _ = HandlerNativeMethods.ChangeWindowMessageFilterEx(
                windowHandle,
                WindowMessage.DWMSendIconicThumbnail,
                MessageFilterAction.Allow,
                ref changeFilterResult);

            changeFilterResult = new ChangeFilterStruct
            {
                cbSize = (uint)Marshal.SizeOf
#if CS7
                <
#else
                (typeof(
#endif
                ChangeFilterStruct
#if CS7
                >(
#else
                )
#endif
                )
            };

            _ = HandlerNativeMethods.ChangeWindowMessageFilterEx(
                windowHandle,
                WindowMessage.DWMSendIconicLivePreviewBitmap,
                MessageFilterAction.Allow,
                ref changeFilterResult);

            // BUG: There should be somewhere to disable CustomWindowPreview. I didn't find it.
            DesktopWindowManager.EnableCustomWindowPreview(windowHandle, true);

            // Make sure we use the initial title set by the user
            // Trigger a "fake" title changed event, so the title is set on the taskbar thumbnail.
            // Empty/null title will be ignored.
            ThumbnailPreview_TitleChanged(preview, EventArgs.Empty);
            ThumbnailPreview_TooltipChanged(preview, EventArgs.Empty);

            // Indicate to the preview that we've added it on the taskbar
            preview.AddedToTaskbar = true;
        }
        private static bool DispatchLivePreviewBitmapMessage(ref System.Windows.Forms.Message m, TaskbarWindow taskbarWindow)
        {
            if (m.Msg == (int)WindowMessage.DWMSendIconicLivePreviewBitmap)
            {
                // Try to get the width/height
                int width = (int)(((long)m.LParam) >> 16);
                int height = (int)(((long)m.LParam) & (0xFFFF));

                // Default size for the thumbnail
                var realWindowSize = new System.Drawing.Size(200, 200);

                if (taskbarWindow.TabbedThumbnail.WindowHandle != IntPtr.Zero)

                    _ = HandlerNativeMethods.GetClientSize(taskbarWindow.TabbedThumbnail.WindowHandle, out realWindowSize);

                else if (taskbarWindow.TabbedThumbnail.WindowsControl != null)

                    realWindowSize = new System.Drawing.Size(
                        Convert.ToInt32(taskbarWindow.TabbedThumbnail.WindowsControl.RenderSize.Width),
                        Convert.ToInt32(taskbarWindow.TabbedThumbnail.WindowsControl.RenderSize.Height));

                // If we don't have a valid height/width, use the original window's size
                if (width <= 0)

                    width = realWindowSize.Width;

                if (height <= 0)

                    height = realWindowSize.Height;

                // Fire an event to let the user update their bitmap
                // Raise the event
                taskbarWindow.TabbedThumbnail.OnTabbedThumbnailBitmapRequested();

                // capture the bitmap for the given control
                // If the user has already specified us a bitmap to use, use that.
                IntPtr hBitmap = taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero ? GrabBitmap(taskbarWindow, realWindowSize) : taskbarWindow.TabbedThumbnail.CurrentHBitmap;

                // If we have a valid parent window handle,
                // calculate the offset so we can place the "peek" bitmap
                // correctly on the app window
                if (taskbarWindow.TabbedThumbnail.ParentWindowHandle != IntPtr.Zero && taskbarWindow.TabbedThumbnail.WindowHandle != IntPtr.Zero)
                {
                    // if we don't have a offset specified already by the user...
                    Point offset = !taskbarWindow.TabbedThumbnail.PeekOffset.HasValue
                        ? Shell.DesktopWindowManager.GetParentOffsetOfChild(taskbarWindow.TabbedThumbnail.WindowHandle, taskbarWindow.TabbedThumbnail.ParentWindowHandle)
                        : new Point(Convert.ToInt32(taskbarWindow.TabbedThumbnail.PeekOffset.Value.X),
                            Convert.ToInt32(taskbarWindow.TabbedThumbnail.PeekOffset.Value.Y));

                    // Only set the peek bitmap if it's not null. 
                    // If it's null (either we didn't get the bitmap or size was 0),
                    // let DWM handle it
                    if (hBitmap != IntPtr.Zero && offset.X >= 0 && offset.Y >= 0)

                        DesktopWindowManager.SetPeekBitmap(
                            taskbarWindow.WindowToTellTaskbarAbout,
                            hBitmap, offset,
                            taskbarWindow.TabbedThumbnail.DisplayFrameAroundBitmap);

                    // If the bitmap we have is not coming from the user (i.e. we created it here),
                    // then make sure we delete it as we don't need it now.
                    if (taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero)

                        _ = GDI.DeleteObject(hBitmap);

                    return true;
                }

                // Else, we don't have a valid window handle from the user. This is mostly likely because
                // we have a WPF UIElement control. If that's the case, use a different screen capture method
                // and also couple of ways to try to calculate the control's offset w.r.t it's parent.
                else if (taskbarWindow.TabbedThumbnail.ParentWindowHandle != IntPtr.Zero &&
                    taskbarWindow.TabbedThumbnail.WindowsControl != null)
                {
                    System.Windows.Point offset;

                    if (!taskbarWindow.TabbedThumbnail.PeekOffset.HasValue)
                    {
                        // Calculate the offset for a WPF UIElement control
                        // For hidden controls, we can't seem to perform the transform.
                        GeneralTransform objGeneralTransform = taskbarWindow.TabbedThumbnail.WindowsControl.TransformToVisual(taskbarWindow.TabbedThumbnail.WindowsControlParentWindow);
                        offset = objGeneralTransform.Transform(new System.Windows.Point(0, 0));
                    }

                    else

                        offset = new System.Windows.Point(taskbarWindow.TabbedThumbnail.PeekOffset.Value.X, taskbarWindow.TabbedThumbnail.PeekOffset.Value.Y);

                    // Only set the peek bitmap if it's not null. 
                    // If it's null (either we didn't get the bitmap or size was 0),
                    // let DWM handle it
                    if (hBitmap != IntPtr.Zero)

                        if (offset.X >= 0 && offset.Y >= 0)

                            DesktopWindowManager.SetPeekBitmap(
                                taskbarWindow.WindowToTellTaskbarAbout,
                                hBitmap, new Point((int)offset.X, (int)offset.Y),
                                taskbarWindow.TabbedThumbnail.DisplayFrameAroundBitmap);

                        else

                            DesktopWindowManager.SetPeekBitmap(
                                taskbarWindow.WindowToTellTaskbarAbout,
                                hBitmap,
                                taskbarWindow.TabbedThumbnail.DisplayFrameAroundBitmap);

                    // If the bitmap we have is not coming from the user (i.e. we created it here),
                    // then make sure we delete it as we don't need it now.
                    if (taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero)

                        _ = GDI.DeleteObject(hBitmap);

                    return true;
                }

                else
                {
                    // Else (no parent specified), just set the bitmap. It would take over the entire 
                    // application window (would work only if you are a MDI app)

                    // Only set the peek bitmap if it's not null. 
                    // If it's null (either we didn't get the bitmap or size was 0),
                    // let DWM handle it
                    if (hBitmap != null)

                        DesktopWindowManager.SetPeekBitmap(taskbarWindow.WindowToTellTaskbarAbout, hBitmap, taskbarWindow.TabbedThumbnail.DisplayFrameAroundBitmap);

                    // If the bitmap we have is not coming from the user (i.e. we created it here),
                    // then make sure we delete it as we don't need it now.
                    if (taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero)

                        _ = GDI.DeleteObject(hBitmap);

                    return true;
                }
            }

            return false;
        }
        private static bool DispatchSendIconThumbnailMessage(ref System.Windows.Forms.Message m, TaskbarWindow taskbarWindow)
        {
            if (m.Msg == (int)WindowMessage.DWMSendIconicThumbnail)
            {
                int width = (int)((long)m.LParam >> 16);
                int height = (int)(((long)m.LParam) & (0xFFFF));
                var requestedSize = new System.Drawing.Size(width, height);

                // Fire an event to let the user update their bitmap
                taskbarWindow.TabbedThumbnail.OnTabbedThumbnailBitmapRequested();

                IntPtr hBitmap;

                // Default size for the thumbnail
                var realWindowSize = new System.Drawing.Size(200, 200);

                // Get the size of teh control or UIElement
                if (taskbarWindow.TabbedThumbnail.WindowHandle != IntPtr.Zero)

                    _ = HandlerNativeMethods.GetClientSize(taskbarWindow.TabbedThumbnail.WindowHandle, out realWindowSize);

                else if (taskbarWindow.TabbedThumbnail.WindowsControl != null)

                    realWindowSize = new System.Drawing.Size(
                        Convert.ToInt32(taskbarWindow.TabbedThumbnail.WindowsControl.RenderSize.Width),
                        Convert.ToInt32(taskbarWindow.TabbedThumbnail.WindowsControl.RenderSize.Height));

                if (realWindowSize.Height == -1 && realWindowSize.Width == -1)

                    realWindowSize.Width = realWindowSize.Height = 199;

                // capture the bitmap for the given control
                // If the user has already specified us a bitmap to use, use that.
                if (taskbarWindow.TabbedThumbnail.ClippingRectangle != null &&
                    taskbarWindow.TabbedThumbnail.ClippingRectangle.Value != Rectangle.Empty)
                {
                    hBitmap = taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero
                        ? GrabBitmap(taskbarWindow, realWindowSize)
                        : taskbarWindow.TabbedThumbnail.CurrentHBitmap;

                    // Clip the bitmap we just got.
                    Bitmap bmp = Image.FromHbitmap(hBitmap);

                    Rectangle clippingRectangle = taskbarWindow.TabbedThumbnail.ClippingRectangle.Value;

                    // If our clipping rect is out of bounds, update it
                    if (clippingRectangle.Height > requestedSize.Height)

                        clippingRectangle.Height = requestedSize.Height;

                    if (clippingRectangle.Width > requestedSize.Width)

                        clippingRectangle.Width = requestedSize.Width;

                    // NOTE: Is this a memory leak?
                    bmp = bmp.Clone(clippingRectangle, bmp.PixelFormat);

                    // Make sure we dispose the bitmap before assigning, otherwise we'll have a memory leak
                    if (hBitmap != IntPtr.Zero && taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero)

                        _ = GDI.DeleteObject(hBitmap);

                    hBitmap = bmp.GetHbitmap();
                    bmp.Dispose();
                }

                else
                {
                    // Else, user didn't want any clipping, if they haven't provided us a bitmap,
                    // use the screencapture utility and capture it.

                    hBitmap = taskbarWindow.TabbedThumbnail.CurrentHBitmap;

                    // If no bitmap, capture one using the utility
                    if (hBitmap == IntPtr.Zero)

                        hBitmap = GrabBitmap(taskbarWindow, realWindowSize);
                }

                // Only set the thumbnail if it's not null. 
                // If it's null (either we didn't get the bitmap or size was 0),
                // let DWM handle it
                if (hBitmap != IntPtr.Zero)
                {
                    Bitmap temp = TabbedThumbnailScreenCapture.ResizeImageWithAspect(
                        hBitmap, requestedSize.Width, requestedSize.Height, true);

                    if (taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero)

                        _ = GDI.DeleteObject(hBitmap);

                    hBitmap = temp.GetHbitmap();
                    DesktopWindowManager.SetIconicThumbnail(taskbarWindow.WindowToTellTaskbarAbout, hBitmap);
                    temp.Dispose();
                }

                // If the bitmap we have is not coming from the user (i.e. we created it here),
                // then make sure we delete it as we don't need it now.
                if (taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero)

                    _ = GDI.DeleteObject(hBitmap);

                return true;
            }
            return false;
        }
 /// <inheritdoc />
 protected override void SetParentHandle(IntPtr handle)
 {
     HandlerNativeMethods.SetParent(Control.Handle, handle);
 }
 void IPreviewHandler.QueryFocus(out IntPtr phwnd)
 {
     phwnd = HandlerNativeMethods.GetFocus();
 }
示例#14
0
 // TODO: should HandlerNativeMethods.GetForegroundWindow() be used directly?
 public static IntPtr GetForegroundWindow() => HandlerNativeMethods.GetForegroundWindow();
示例#15
0
        public static bool IsOnForeground(IntPtr hWnd)
        {
            IntPtr activatedHandle = HandlerNativeMethods.GetForegroundWindow();

            return(activatedHandle != null && activatedHandle != IntPtr.Zero && activatedHandle == hWnd);
        }