Services/DesktopService.cs
using System;
using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Threading; using Microsoft.Win32; namespace pscommander { public class DesktopService { private Desktop _desktop; private readonly PowerShellService _powerShellService; private readonly DataSourceService _dataSourceService; private readonly List<Window> _windows; private readonly MouseHook _mouseHook = new MouseHook(); public DesktopService(PowerShellService powerShellService, DataSourceService dataSourceService) { _powerShellService = powerShellService; _dataSourceService = dataSourceService; _windows = new List<Window>(); //_mouseHook.Install(); // _mouseHook.LeftButtonUp += (e) => { // foreach(var window in _windows) // { // // Retrieve the coordinate of the mouse position. // Point pt = new Point(e.pt.x - window.Left, e.pt.y - window.Top + 50); // // Perform the hit test against a given portion of the visual object tree. // HitTestResult result = VisualTreeHelper.HitTest(window, pt); // if (result != null) // { // var windowHandle = new WindowInteropHelper(window).Handle; // PostMessage(windowHandle, (int)MK_LBUTTON, IntPtr.Zero, (IntPtr)(((int)pt.Y << 16) | ((int)pt.X & 0xffff))); // } // } // }; } public void SetDesktop(Desktop desktop) { Application.Current.Dispatcher.Invoke((Action)delegate{ ClearDesktop(); _desktop = desktop; foreach(var widget in _desktop.Widgets) { SetDesktopWidget(widget); } }); } private void SetDesktopWidget(DesktopWidget widget) { Window widgetWindow = new Widget(); widgetWindow.Top = widget.Top; widgetWindow.Left = widget.Left; widgetWindow.Height = widget.Height; widgetWindow.Width = widget.Width; if (widget is TextDesktopWidget textDesktopWidget) { widgetWindow.Content = SetDesktopWidgetText(textDesktopWidget); } if (widget is ImageDesktopWidget imageDesktopWidget) { widgetWindow.Content = SetDesktopWidgetImage(imageDesktopWidget); } if (widget is WebpageDesktopWidget webpageDesktopWidget) { widgetWindow.Content = SetDesktopWidgetWebpage(webpageDesktopWidget); } if (widget is CustomDesktopWidget customDesktopWidget) { widgetWindow = SetDesktopWidgetCustom(customDesktopWidget); if (widgetWindow == null) return; widgetWindow.Top = widget.Top; widgetWindow.Left = widget.Left; widgetWindow.Height = widget.Height; widgetWindow.Width = widget.Width; } if (widget is MeasurementDesktopWidget measurementDesktopWidget) { widgetWindow.Content = SetDesktopWidgetMeasurement(measurementDesktopWidget); } if (widget is DataDesktopWidget dataDesktopWidget) { var dataSource = _dataSourceService.DataSources.FirstOrDefault(m => m.Name.Equals(dataDesktopWidget.DataSource, StringComparison.OrdinalIgnoreCase)); if (dataSource == null) return; widgetWindow = SetDesktopWidgetData(dataDesktopWidget, dataSource); if (widgetWindow == null) return; widgetWindow.Top = widget.Top; widgetWindow.Left = widget.Left; widgetWindow.Height = widget.Height; widgetWindow.Width = widget.Width; widgetWindow.DataContext = dataSource; } widgetWindow.AllowsTransparency = widget.Transparent; if (widget.Transparent) { widgetWindow.WindowStyle = WindowStyle.None; } widgetWindow.WindowState = WindowState.Minimized; widgetWindow.Show(); var windowHandle = new WindowInteropHelper(widgetWindow).Handle; SetDesktopWidgetParent(windowHandle); _windows.Add(widgetWindow); } private MeasurementCard SetDesktopWidgetMeasurement(MeasurementDesktopWidget measurementDesktopWidget) { return new MeasurementCard(measurementDesktopWidget, _powerShellService); } private Window SetDesktopWidgetData(DataDesktopWidget dataDesktopWidget, DataSource dataSource) { return _powerShellService.Execute<Window>(dataDesktopWidget.LoadWidget, dataSource).FirstOrDefault(); } private Window SetDesktopWidgetCustom(CustomDesktopWidget customDesktopWidget) { return _powerShellService.Execute<Window>(customDesktopWidget.LoadWidget).FirstOrDefault(); } private System.Windows.Controls.WebBrowser SetDesktopWidgetWebpage(WebpageDesktopWidget webpageDesktopWidget) { var webBrowser = new System.Windows.Controls.WebBrowser(); webBrowser.Source = new Uri(webpageDesktopWidget.Url); return webBrowser; } private Image SetDesktopWidgetImage(ImageDesktopWidget widget) { var image = new Image(); image.Source = new BitmapImage(new Uri(widget.Image)); return image; } private TextBlock SetDesktopWidgetText(TextDesktopWidget widget) { var textBlock = new TextBlock(); textBlock.Text = widget.Text; if (!string.IsNullOrWhiteSpace(widget.Font)) { textBlock.FontFamily = new FontFamily(widget.Font); } textBlock.FontSize = widget.FontSize; if (!string.IsNullOrWhiteSpace(widget.BackgroundColor)) { textBlock.Background = (SolidColorBrush)(new BrushConverter().ConvertFrom(widget.BackgroundColor)); } else { VisualBrush vBrush = new VisualBrush(); vBrush.Opacity = 0; textBlock.Background = vBrush; } if (!string.IsNullOrWhiteSpace(widget.FontColor)) { textBlock.Foreground = (SolidColorBrush)(new BrushConverter().ConvertFrom(widget.FontColor)); } return textBlock; } private void SetDesktopWidgetParent(IntPtr widgetHandle) { IntPtr workerw = IntPtr.Zero; IntPtr result = IntPtr.Zero; IntPtr progman = FindWindow("Progman", null); // Send 0x052C to Progman. This message directs Progman to spawn a // WorkerW behind the desktop icons. If it is already there, nothing // happens. SendMessageTimeout(progman, 0x052C, new IntPtr(0), IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out result); // We enumerate all Windows, until we find one, that has the SHELLDLL_DefView // as a child. // If we found that window, we take its next sibling and assign it to workerw. EnumWindows(new EnumWindowsProc((tophandle, topparamhandle) => { IntPtr p = FindWindowEx(tophandle, IntPtr.Zero, "SHELLDLL_DefView", null); if (p != IntPtr.Zero) { // Gets the WorkerW Window after the current one. workerw = FindWindowEx(IntPtr.Zero, tophandle, "WorkerW", null); } return true; }), IntPtr.Zero); SetParent(widgetHandle, workerw); } public void ClearDesktop() { _desktop = null; IntPtr progman = FindWindow("Progman", null); SendMessage(progman, 0x0034, 4, IntPtr.Zero); foreach(var window in _windows) { window.Close(); } _windows.Clear(); } [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)] static extern IntPtr SendMessageTimeout( IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out IntPtr lpdwResult); [Flags] enum SendMessageTimeoutFlags : uint { SMTO_NORMAL = 0x0, SMTO_BLOCK = 0x1, SMTO_ABORTIFHUNG = 0x2, SMTO_NOTIMEOUTIFNOTHUNG = 0x8, SMTO_ERRORONEXIT = 0x20 } [DllImport("user32.dll", SetLastError = true)] static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("user32.dll", SetLastError=true)] static extern int CloseWindow (IntPtr hWnd); [return: MarshalAs(UnmanagedType.Bool)] [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError=true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool DestroyWindow(IntPtr hwnd); [DllImport("user32.dll")] public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, IntPtr lParam); [DllImport("user32.dll")] static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong); const int WM_MOUSEMOVE = 0x0200; const int MK_LBUTTON = 0x0001; } } //New-CommanderDesktop //New-CommanderDesktopWidget //Clear-CommanderDesktop //Set-CommanderDesktop |