将 DWM 缩略图添加为 WPF 控件子项
Posted
技术标签:
【中文标题】将 DWM 缩略图添加为 WPF 控件子项【英文标题】:adding DWM Thumbnails as WPF control child 【发布时间】:2017-09-13 07:49:17 【问题描述】:我使用 DWM 缩略图创建窗口选择器,但我想将此缩略图添加为 WPF StackPanl 的子项,我该怎么做? 因此,在这段代码中,我有一个名为“b”的网格,我想为其添加 App Thumbnail 作为子项。
这是代码:
#region dwmapi.dll imports
[DllImport("dwmapi.dll", PreserveSig = false)]
private static extern bool DwmIsCompositionEnabled();
[DllImport("dwmapi.dll")]
private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMargins);
[StructLayout(LayoutKind.Sequential)]
struct MARGINS
public int Left;
public int Right;
public int Top;
public int Bottom;
public void ExtendToWholeClientArea()
this.Left = -1;
this.Right = -1;
this.Top = -1;
this.Bottom = -1;
[DllImport("dwmapi.dll")]
private static extern int DwmRegisterThumbnail(IntPtr dest, IntPtr src, out IntPtr thumb);
[DllImport("dwmapi.dll")]
private static extern int DwmUnregisterThumbnail(IntPtr thumb);
[DllImport("dwmapi.dll")]
private static extern int DwmQueryThumbnailSourceSize(IntPtr thumb, out PSIZE size);
[StructLayout(LayoutKind.Sequential)]
private struct PSIZE
public int x;
public int y;
[DllImport("dwmapi.dll")]
private static extern int DwmUpdateThumbnailProperties(IntPtr hThumb, ref DWM_THUMBNAIL_PROPERTIES props);
[StructLayout(LayoutKind.Sequential)]
private struct DWM_THUMBNAIL_PROPERTIES
public int dwFlags;
public RECT rcDestination;
public RECT rcSource;
public byte opacity;
public bool fVisible;
public bool fSourceClientAreaOnly;
[StructLayout(LayoutKind.Sequential)]
private struct RECT
public RECT(int left, int top, int right, int bottom)
Left = left;
Top = top;
Right = right;
Bottom = bottom;
public int Left;
public int Top;
public int Right;
public int Bottom;
private static readonly int DWM_TNP_VISIBLE = 0x8;
private static readonly int DWM_TNP_RECTDESTINATION = 0x1;
private static readonly int DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010;
#endregion
private void DrawThumbnail(WindowInfo win, int thumbnailIndex) IntPtr thumbnail = win.Thumbnail;
if (thumbnail != IntPtr.Zero)
DwmUnregisterThumbnail(thumbnail);
int hResult = DwmRegisterThumbnail(mainWindowHandle, win.HWnd, out thumbnail);
if (hResult == 0)
PSIZE size;
DwmQueryThumbnailSourceSize(thumbnail, out size);
DWM_THUMBNAIL_PROPERTIES props = new DWM_THUMBNAIL_PROPERTIES();
props.dwFlags = DWM_TNP_VISIBLE | DWM_TNP_RECTDESTINATION | DWM_TNP_SOURCECLIENTAREAONLY;
props.fVisible = true;
props.fSourceClientAreaOnly = true;
Grid b = new Grid() Height = ThumbnailSize+20, Width = ThumbnailSize+(WindowLeftOffset), Background = (SolidColorBrush)(new BrushConverter().ConvertFrom("#55D3E6EE")), Tag = UnSelectedTag ,VerticalAlignment=VerticalAlignment.Stretch,HorizontalAlignment=HorizontalAlignment.Stretch;
b.MouseLeftButtonDown += B_MouseLeftButtonDown;
//Set the region where the live preview will be drawn ======> I want to add this region as a child for "b" grid
int left = (thumbnailIndex % MaxThumbnails) * (ThumbnailSize + ThumbnailSpacing)+ WindowLeftOffset;
int top = (int)(thumbnailIndex / MaxThumbnails) * (ThumbnailSize + ThumbnailSpacing) + WindowTopOffset;
int right = left + ThumbnailSize;
int bottom = top + ThumbnailSize;
props.rcDestination = new RECT(left, top, right, bottom);
Border bor = new Border() BorderThickness = new Thickness(1), BorderBrush = (SolidColorBrush)(new BrushConverter().ConvertFrom("#550863A2")), CornerRadius= new CornerRadius(2) ;
bor.Child = b;
bor.SetValue(Canvas.LeftProperty, (double)(((drowingIndex % MaxThumbnails) * (ThumbnailSize + ThumbnailSpacing))+WindowLeftOffset - (WindowLeftOffset/2)-1));
bor.SetValue(Canvas.TopProperty, Math.Floor((double)(drowingIndex / MaxThumbnails)) * (ThumbnailSize + ThumbnailSpacing));
canvas.Children.Add(bor);
drowingIndex++;
previweStackPanels.Add(b);
//Center the live preview
if (size.x < size.y)
double ScaleFactor = ThumbnailSize / (double)size.y;
int scaledX = (int)(size.x * ScaleFactor);
int xOffset = (ThumbnailSize - scaledX) / 2;
props.rcDestination.Left += xOffset;
props.rcDestination.Right -= xOffset;
if (size.y < size.x)
double ScaleFactor = ThumbnailSize / (double)size.x;
int scaledY = (int)(size.y * ScaleFactor);
int yOffset = (ThumbnailSize - scaledY) / 2;
props.rcDestination.Top += yOffset;
props.rcDestination.Bottom -= yOffset;
DwmUpdateThumbnailProperties(thumbnail, ref props);
【问题讨论】:
【参考方案1】:Panel
(例如Grid
和StackPanel
)有一个Children
集合,您可以将UIElement
s 添加到其中:
previweStackPanels.Children.Add(b);
请注意,除了UIElement
对象之外,您不能将任何其他对象添加到Panel
。
这意味着您不能将RECT
添加到Grid
,因为RECT
不是UIElement
。不过,您可以添加 System.Windows.Shapes.Rectangle
:
【讨论】:
不,我想将这个 Rectangleprops.rcDestination = new RECT(left, top, right, bottom);
添加为一个孩子 .. previweStackPanels 只是所有 StackPanels 的列表
作为什么的孩子?
of b
Grid .. 所以我有运行窗口的缩略图,我想将此窗口的缩略图添加为子窗口或 Grid b
的内容@
我想你应该再读一遍我的答案。您可以仅将 UIElements 添加到 Grid 的 Children 集合中,并且由于 RECT 不是 UI 元素,因此您不能将此元素添加到 Grid。不过,您可以添加 System.Windows.Shapes.Rectangle。以上是关于将 DWM 缩略图添加为 WPF 控件子项的主要内容,如果未能解决你的问题,请参考以下文章
php 使用类菜单 - 拇指将特色图像缩略图添加到菜单项的子项
WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表