/// <summary> /// Creates a Display instance. /// </summary> /// <param name="settings">ScreenSettings object</param> /// <param name="startupWindow"></param> public Display(ScreenSettings settings, bool startupWindow) { ScreenSettings = settings; _startupWindow = startupWindow; InitializeComponent(); Paint += new PaintEventHandler(Display_Paint); }
/// <summary> /// Gets a Screen instance from the provided screen ScreenSettings. /// </summary> /// <param name="screenSettings">screen settings</param> /// <returns>Screen instance</returns> public static Screen GetScreen(ScreenSettings screenSettings) { var screens = from screen in Screen.AllScreens where screen.DeviceName == screenSettings.ScreenID select screen; return screens.Count() == 1 ? screens.First() : null; }
/// <summary> /// Draw image for a single screen using the provided ScreenSettings. /// </summary> /// <param name="screenSettings">screen settings</param> /// <returns>background image</returns> public static Image DesktopImage(ScreenSettings screenSettings) { Screen screen = GetScreen(screenSettings); Image image = new Bitmap(screen.Bounds.Width, screen.Bounds.Height); Graphics graphics = Graphics.FromImage(image); if (!string.IsNullOrEmpty(screenSettings.WallpaperPath)) { // give a better error for missing files if (!File.Exists(screenSettings.WallpaperPath)) throw new FileNotFoundException(string.Format("The file '{0}' could not be found.", screenSettings.WallpaperPath), screenSettings.WallpaperPath); Image wallpaper = Image.FromFile(screenSettings.WallpaperPath); float ratio; Rectangle newImageBounds = Rectangle.Empty; // test to see if the image is the same size as the screen // this should happen often enough that I thought I'd make it more efficient if there was an exact match // all that math isn't necessary if the screen and image are the same size bool imageIsSameAsScreenSize = wallpaper.Width != screen.Bounds.Width || wallpaper.Height != screen.Bounds.Height; if (!imageIsSameAsScreenSize) { // get image resize ratio ratio = Math.Min((float)screen.Bounds.Height / (float)wallpaper.Height, (float)screen.Bounds.Width / (float)wallpaper.Width); // get the image bounds based on the new ratio newImageBounds = new Rectangle(screen.Bounds.Width / 2 - (int)((float)(wallpaper.Width / 2) * ratio), screen.Bounds.Height / 2 - (int)((float) (wallpaper.Height / 2) * ratio), (int)((float)wallpaper.Width * ratio), (int)((float)wallpaper.Height * ratio)); } switch (screenSettings.Style) { case WallPaperStyle.FitToScreen: if (!imageIsSameAsScreenSize) { // fill background color graphics.FillRectangle(new SolidBrush(screenSettings.BackgroundColor), 0, 0, screen.Bounds.Width, screen.Bounds.Height); graphics.DrawImage(wallpaper, newImageBounds); } else graphics.DrawImage(wallpaper, new Rectangle(0, 0, screen.Bounds.Width, screen.Bounds.Height)); break; case WallPaperStyle.FillScreen: if (!imageIsSameAsScreenSize) { // fill background color graphics.FillRectangle(new SolidBrush(screenSettings.BackgroundColor), 0, 0, screen.Bounds.Width, screen.Bounds.Height); graphics.DrawImage(wallpaper, newImageBounds); } else graphics.DrawImage(wallpaper, new Rectangle(0, 0, screen.Bounds.Width, screen.Bounds.Height)); break; case WallPaperStyle.StretchToFillScreen: graphics.DrawImage(wallpaper, new Rectangle(0, 0, screen.Bounds.Width, screen.Bounds.Height)); break; case WallPaperStyle.Center: // only fill if image is smaller than background if (screen.Bounds.Width > wallpaper.Width && screen.Bounds.Height > wallpaper.Height) graphics.FillRegion(new SolidBrush(screenSettings.BackgroundColor), new Region(screen.Bounds)); graphics.DrawImage(wallpaper, screen.Bounds.Width / 2 - wallpaper.Width / 2, screen.Bounds.Height / 2 - wallpaper.Height / 2, wallpaper.Width, wallpaper.Height); break; case WallPaperStyle.Tile: // create new texture brush TextureBrush texture = new TextureBrush(wallpaper, WrapMode.Tile); // if image is not same as screen size, translate texture to start from the center if (!imageIsSameAsScreenSize) texture.TranslateTransform(screen.Bounds.Width / 2 - wallpaper.Width / 2, screen.Bounds.Height / 2 - wallpaper.Height / 2); graphics.FillRegion(texture, new Region(new Rectangle(0, 0, screen.Bounds.Width, screen.Bounds.Height))); break; } } else // no image, just color fill graphics.FillRegion(new SolidBrush(screenSettings.BackgroundColor), new Region(screen.Bounds)); return image; }