/// <summary> /// Dispatches a window message so that the appropriate events /// can be invoked. /// </summary> /// <param name="m">The window message, typically obtained /// from a Windows Forms or WPF window procedure.</param> public void DispatchMessage(ref Message m) { if (m.Msg == SafeNativeMethods.WM_ACTIVATE && _hwndParent != IntPtr.Zero) { if (((int)m.WParam) == SafeNativeMethods.WA_ACTIVE || ((int)m.WParam) == SafeNativeMethods.WA_CLICKACTIVE) { VistaBridgeInterop.UnsafeNativeMethods.SendMessage( _hwnd, (uint)m.Msg, m.WParam, m.LParam); //TODO: Technically, we should also test if the child //isn't visible. If it is, no need to send the message. } } if (m.Msg == SafeNativeMethods.WM_SYSCOMMAND && _hwndParent != IntPtr.Zero) { if (((int)m.WParam) == SafeNativeMethods.SC_CLOSE) { VistaBridgeInterop.UnsafeNativeMethods.SendMessage( _hwnd, SafeNativeMethods.WM_CLOSE, IntPtr.Zero, IntPtr.Zero); WindowClosed(); } } if (m.Msg == SafeNativeMethods.WM_DWMSENDICONICTHUMBNAIL) { int width = (int)(((long)m.LParam) >> 16); int height = (int)(((long)m.LParam) & (0xFFFF)); BitmapRequestedEventArgs b = new BitmapRequestedEventArgs(width, height, true); ThumbnailRequested(this, b); if (b.UseWindowScreenshot) { //The actual application window might scale pretty badly //with these parameters. Note that the following //scaling is still not as good as what DWM does on //its own, because by default it will take the window //dimensions in consideration. When using custom //preview, DWM gives us default window dimensions //instead of taking the window dimensions in consideration. Size clientSize; UnsafeNativeMethods.GetClientSize(_hwnd, out clientSize); float thumbnailAspect = ((float)width) / height; float windowAspect = ((float)clientSize.Width) / clientSize.Height; if (windowAspect > thumbnailAspect) { //Wider than the thumbnail, make the thumbnail height smaller: height = (int)(height * (thumbnailAspect / windowAspect)); } if (windowAspect < thumbnailAspect) { //The thumbnail is wider, make the width smaller: width = (int)(width * (windowAspect / thumbnailAspect)); } b.Bitmap = ScreenCapture.GrabWindowBitmap(_hwnd, new Size(width, height)); } else if (!b.DoNotMirrorBitmap) { b.Bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); } Windows7Taskbar.SetIconicThumbnail(WindowToTellDwmAbout, b.Bitmap); b.Bitmap.Dispose(); //TODO: Is it our responsibility? } else if (m.Msg == SafeNativeMethods.WM_DWMSENDICONICLIVEPREVIEWBITMAP) { Size clientSize; if (!UnsafeNativeMethods.GetClientSize(_hwnd, out clientSize)) { clientSize = new Size(50,50);//Best guess } BitmapRequestedEventArgs b = new BitmapRequestedEventArgs( clientSize.Width, clientSize.Height, _hwndParent == IntPtr.Zero); PeekRequested(this, b); if (b.UseWindowScreenshot) { b.Bitmap = ScreenCapture.GrabWindowBitmap(_hwnd, clientSize); } else if (!b.DoNotMirrorBitmap) { b.Bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); } if (_hwndParent != IntPtr.Zero) { Point offset = WindowUtilities.GetParentOffsetOfChild(_hwnd, _hwndParent); Windows7Taskbar.SetPeekBitmap(WindowToTellDwmAbout, b.Bitmap, offset, b.DisplayFrameAroundBitmap); } else { Windows7Taskbar.SetPeekBitmap(WindowToTellDwmAbout, b.Bitmap, b.DisplayFrameAroundBitmap); } b.Bitmap.Dispose(); //TODO: Is it our responsibility? } }
/// <summary> /// Dispatches a window message so that the appropriate events /// can be invoked. /// </summary> /// <param name="m">The window message, typically obtained /// from a Windows Forms or WPF window procedure.</param> public void DispatchMessage(ref Message m) { if (m.Msg == SafeNativeMethods.WM_ACTIVATE && _hwndParent != IntPtr.Zero) { if (((int)m.WParam) == SafeNativeMethods.WA_ACTIVE || ((int)m.WParam) == SafeNativeMethods.WA_CLICKACTIVE) { VistaBridgeInterop.UnsafeNativeMethods.SendMessage( _hwnd, (uint)m.Msg, m.WParam, m.LParam); //TODO: Technically, we should also test if the child //isn't visible. If it is, no need to send the message. } } if (m.Msg == SafeNativeMethods.WM_SYSCOMMAND && _hwndParent != IntPtr.Zero) { if (((int)m.WParam) == SafeNativeMethods.SC_CLOSE) { VistaBridgeInterop.UnsafeNativeMethods.SendMessage( _hwnd, SafeNativeMethods.WM_CLOSE, IntPtr.Zero, IntPtr.Zero); WindowClosed(); } } if (m.Msg == SafeNativeMethods.WM_DWMSENDICONICTHUMBNAIL) { int width = (int)(((long)m.LParam) >> 16); int height = (int)(((long)m.LParam) & (0xFFFF)); BitmapRequestedEventArgs b = new BitmapRequestedEventArgs(width, height, true); ThumbnailRequested(this, b); if (b.UseWindowScreenshot) { //The actual application window might scale pretty badly //with these parameters. Note that the following //scaling is still not as good as what DWM does on //its own, because by default it will take the window //dimensions in consideration. When using custom //preview, DWM gives us default window dimensions //instead of taking the window dimensions in consideration. Size clientSize; UnsafeNativeMethods.GetClientSize(_hwnd, out clientSize); float thumbnailAspect = ((float)width) / height; float windowAspect = ((float)clientSize.Width) / clientSize.Height; if (windowAspect > thumbnailAspect) { //Wider than the thumbnail, make the thumbnail height smaller: height = (int)(height * (thumbnailAspect / windowAspect)); } if (windowAspect < thumbnailAspect) { //The thumbnail is wider, make the width smaller: width = (int)(width * (windowAspect / thumbnailAspect)); } b.Bitmap = ScreenCapture.GrabWindowBitmap(_hwnd, new Size(width, height)); } else if (!b.DoNotMirrorBitmap) { b.Bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); } Windows7Taskbar.SetIconicThumbnail(WindowToTellDwmAbout, b.Bitmap); b.Bitmap.Dispose(); //TODO: Is it our responsibility? } else if (m.Msg == SafeNativeMethods.WM_DWMSENDICONICLIVEPREVIEWBITMAP) { Size clientSize; if (!UnsafeNativeMethods.GetClientSize(_hwnd, out clientSize)) { clientSize = new Size(50, 50);//Best guess } BitmapRequestedEventArgs b = new BitmapRequestedEventArgs( clientSize.Width, clientSize.Height, _hwndParent == IntPtr.Zero); PeekRequested(this, b); if (b.UseWindowScreenshot) { b.Bitmap = ScreenCapture.GrabWindowBitmap(_hwnd, clientSize); } else if (!b.DoNotMirrorBitmap) { b.Bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); } if (_hwndParent != IntPtr.Zero) { Point offset = WindowUtilities.GetParentOffsetOfChild(_hwnd, _hwndParent); Windows7Taskbar.SetPeekBitmap(WindowToTellDwmAbout, b.Bitmap, offset, b.DisplayFrameAroundBitmap); } else { Windows7Taskbar.SetPeekBitmap(WindowToTellDwmAbout, b.Bitmap, b.DisplayFrameAroundBitmap); } b.Bitmap.Dispose(); //TODO: Is it our responsibility? } }