/// <summary> /// Helper function to capture a bitmap for a given window handle or incase of WPF app, /// an UIElement. /// </summary> /// <param name="taskbarWindow">The proxy window for which a bitmap needs to be created</param> /// <param name="requestedSize">Size for the requested bitmap image</param> /// <returns>Bitmap captured from the window handle or UIElement. Null if the window is hidden or it's size is zero.</returns> private static IntPtr GrabBitmap(TaskbarWindow taskbarWindow, System.Drawing.Size requestedSize) { IntPtr hBitmap = IntPtr.Zero; if (taskbarWindow.TabbedThumbnail.WindowHandle != IntPtr.Zero) //TabbedThumbnail is linked to WinformsControl { if (taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero) { using (Bitmap bmp = TabbedThumbnailScreenCapture.GrabWindowBitmap( taskbarWindow.TabbedThumbnail.WindowHandle, requestedSize)) { hBitmap = bmp.GetHbitmap(); } } else { using (Image img = Image.FromHbitmap(taskbarWindow.TabbedThumbnail.CurrentHBitmap)) { using (Bitmap bmp = new Bitmap(img, requestedSize)) { hBitmap = bmp != null?bmp.GetHbitmap() : IntPtr.Zero; } } } } else if (taskbarWindow.TabbedThumbnail.WindowsControl != null) //TabbedThumbnail is linked to a WPF UIElement { if (taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero) { Bitmap bmp = TabbedThumbnailScreenCapture.GrabWindowBitmap( taskbarWindow.TabbedThumbnail.WindowsControl, 96, 96, requestedSize.Width, requestedSize.Height); if (bmp != null) { hBitmap = bmp.GetHbitmap(); bmp.Dispose(); } } else { using (Image img = Image.FromHbitmap(taskbarWindow.TabbedThumbnail.CurrentHBitmap)) { using (Bitmap bmp = new Bitmap(img, requestedSize)) { hBitmap = bmp != null?bmp.GetHbitmap() : IntPtr.Zero; } } } } return(hBitmap); }
private static bool DispatchSendIconThumbnailMessage(ref System.Windows.Forms.Message m, TaskbarWindow taskbarWindow) { if (m.Msg == (int)TaskbarNativeMethods.WmDwmSendIconThumbnail) { int width = (int)((long)m.LParam >> 16); int height = (int)(((long)m.LParam) & (0xFFFF)); Size requestedSize = new Size(width, height); // Fire an event to let the user update their bitmap taskbarWindow.TabbedThumbnail.OnTabbedThumbnailBitmapRequested(); IntPtr hBitmap = IntPtr.Zero; // Default size for the thumbnail Size realWindowSize = new Size(200, 200); // Get the size of teh control or UIElement if (taskbarWindow.TabbedThumbnail.WindowHandle != IntPtr.Zero) { TabbedThumbnailNativeMethods.GetClientSize(taskbarWindow.TabbedThumbnail.WindowHandle, out realWindowSize); } else if (taskbarWindow.TabbedThumbnail.WindowsControl != null) { realWindowSize = new 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) { if (taskbarWindow.TabbedThumbnail.CurrentHBitmap == IntPtr.Zero) { hBitmap = GrabBitmap(taskbarWindow, realWindowSize); } else { hBitmap = taskbarWindow.TabbedThumbnail.CurrentHBitmap; } // Clip the bitmap we just got. Bitmap bmp = Bitmap.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) { ShellNativeMethods.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) { ShellNativeMethods.DeleteObject(hBitmap); } hBitmap = temp.GetHbitmap(); TabbedThumbnailNativeMethods.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) { ShellNativeMethods.DeleteObject(hBitmap); } return(true); } return(false); }