2009-10-08 11 views
3

J'ai un extrait de code pour définir une seule image sur les deux écrans, mais j'ai récemment obtenu un deuxième moniteur pour mon ordinateur portable et je voulais modifier mon code pour définir une image différente à chaque moniteur.Comment définir plusieurs arrière-plans de bureau (double moniteur)

Des idées?

(ce code snipet pour un seul moniteur est:

[DllImport("user32.dll", CharSet = CharSet.Auto)] 
     private static extern Int32 SystemParametersInfo(UInt32 action, UInt32 uParam, String vParam, UInt32 winIni); 
     private static readonly UInt32 SPI_SETDESKWALLPAPER = 0x14; 
     private static readonly UInt32 SPIF_UPDATEINIFILE = 0x01; 
     private static readonly UInt32 SPIF_SENDWININICHANGE = 0x02; 

     private void SetWallpaper(string path) 
     { 
      if (path != null) 
      { 

       string savepath = Settings.Default.SavePath; 

       Image imgInFile = Image.FromFile(path); 
       imgInFile.Save(savepath, ImageFormat.Bmp); 
       SystemParametersInfo(SPI_SETDESKWALLPAPER, 3, savepath, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE); 
      } 
      else 
      { 
       MessageBox.Show("Path Null"); 
      } 
     } 

)

+1

J'utilise UltraMon pour cela et plus: http://www.realtimesoft.com/ultramon/ – tvanfosson

+0

Cest en fait où j'eu l'idée de les mettre comme ça. Cependant, je n'aime pas payer pour des choses parce que je suis juste paresseux pour apprendre à le faire moi-même. – Crash893

Répondre

1

Il n'y a pas de différence en réalité.

Pensez à plusieurs moniteurs pour simplement agrandir l'espace de papier peint.

Donc ce que vous avez à faire est de créer une image de fond d'écran à partir de plusieurs images pour remplir les zones de rectangles pour chaque moniteur.

Cette question ressemble également à un duplicate

+0

comment embarrassant j'ai oublié tout cela. J'ai fait une recherche de fond d'écran double écran et je n'ai même pas vu ça. +1 pour la recherche – Crash893

0
using System; 
using System.Collections.Generic; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Runtime.InteropServices; 

namespace SetWallpapers 
{ 
    internal class Program 
    { 
     [DllImport("user32.dll", CharSet = CharSet.Auto)] 
     private static extern Int32 SystemParametersInfo(UInt32 uiAction, UInt32 uiParam, String pvParam, UInt32 fWinIni); 

     private static UInt32 SPI_SETDESKWALLPAPER = 20; 
     private static UInt32 SPIF_UPDATEINIFILE = 0x1; 

     public void SetImage(string filename) 
     { 
      SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, filename, SPIF_UPDATEINIFILE); 
     } 

     private static void Main(string[] args) 
     { 
      var images = new Dictionary<string, Image> 
      { 
       { @"\\.\DISPLAY1", Image.FromFile(@"C:\Users\Public\Pictures\Sample Pictures\Lighthouse.jpg") }, 
       { @"\\.\DISPLAY2", Image.FromFile(@"C:\Users\Public\Pictures\Sample Pictures\Jellyfish.jpg") }, 
       { @"\\.\DISPLAY3", Image.FromFile(@"C:\Users\Public\Pictures\Sample Pictures\Koala.jpg") } 
      }; 

      CreateBackgroundImage(images); 

     } 

     private static void CreateBackgroundImage(Dictionary<string, Image> imageFiles) 
     { 
      const string defaultBackgroundFile = @"C:\Users\Public\Pictures\Sample Pictures\DefaultBackground.bmp"; 

      using (var virtualScreenBitmap = new Bitmap((int)System.Windows.SystemParameters.VirtualScreenWidth, (int)System.Windows.SystemParameters.VirtualScreenHeight)) 
      { 
       using (var virtualScreenGraphic = Graphics.FromImage(virtualScreenBitmap)) 
       { 
        foreach (var screen in System.Windows.Forms.Screen.AllScreens) 
        { 
         var image = (imageFiles.ContainsKey(screen.DeviceName)) ? imageFiles[screen.DeviceName] : null; 

         var monitorDimensions = screen.Bounds; 
         var width = monitorDimensions.Width; 
         var monitorBitmap = new Bitmap(width, monitorDimensions.Height); 
         var fromImage = Graphics.FromImage(monitorBitmap); 
         fromImage.FillRectangle(SystemBrushes.Desktop, 0, 0, monitorBitmap.Width, monitorBitmap.Height); 

         if (image != null) 
          DrawImageCentered(fromImage, image, new Rectangle(0, 0, monitorBitmap.Width, monitorBitmap.Height)); 

         Rectangle rectangle; 
         if (monitorDimensions.Top == 0 && monitorDimensions.Left == 0) 
         { 
          rectangle = monitorDimensions; 
         } 
         else 
         { 
          if ((monitorDimensions.Left < 0 && monitorDimensions.Width > -monitorDimensions.Left) || 
           (monitorDimensions.Top < 0 && monitorDimensions.Height > -monitorDimensions.Top)) 
          { 
           var isMain = (monitorDimensions.Top < 0 && monitorDimensions.Bottom > 0); 

           var left = (monitorDimensions.Left < 0) 
               ? (int) System.Windows.SystemParameters.VirtualScreenWidth + monitorDimensions.Left 
               : monitorDimensions.Left; 

           var top = (monitorDimensions.Top < 0) 
               ? (int) System.Windows.SystemParameters.VirtualScreenHeight + monitorDimensions.Top 
               : monitorDimensions.Top; 

           Rectangle srcRect; 
           if (isMain) 
           { 
            rectangle = new Rectangle(left, 0, monitorDimensions.Width, monitorDimensions.Bottom); 
            srcRect = new Rectangle(0, -monitorDimensions.Top, monitorDimensions.Width, monitorDimensions.Height + monitorDimensions.Top); 
           } 
           else 
           { 
            rectangle = new Rectangle(0, top, monitorDimensions.Right, monitorDimensions.Height); 
            srcRect = new Rectangle(-monitorDimensions.Left, 0, monitorDimensions.Width + monitorDimensions.Left, 
                  monitorDimensions.Height); 
           } 

           virtualScreenGraphic.DrawImage(monitorBitmap, rectangle, srcRect, GraphicsUnit.Pixel); 
           rectangle = new Rectangle(left, top, monitorDimensions.Width, monitorDimensions.Height); 
          } 
          else 
          { 
           var left = (monitorDimensions.Left < 0) 
               ? (int) System.Windows.SystemParameters.VirtualScreenWidth + monitorDimensions.Left 
               : monitorDimensions.Left; 
           var top = (monitorDimensions.Top < 0) 
               ? (int) System.Windows.SystemParameters.VirtualScreenHeight + monitorDimensions.Top 
               : monitorDimensions.Top; 
           rectangle = new Rectangle(left, top, monitorDimensions.Width, monitorDimensions.Height); 
          } 
         } 
         virtualScreenGraphic.DrawImage(monitorBitmap, rectangle); 
        } 

        virtualScreenBitmap.Save(defaultBackgroundFile, ImageFormat.Bmp); 
       } 
      } 

      SystemParametersInfo(SPI_SETDESKWALLPAPER, 0u, defaultBackgroundFile, SPIF_UPDATEINIFILE); 
     } 


     private static void DrawImageCentered(Graphics g, Image img, Rectangle monitorRect) 
     { 
      float heightRatio = (float)monitorRect.Height/(float)img.Height; 
      float widthRatio = (float)monitorRect.Width/(float)img.Width; 
      int height = monitorRect.Height; 
      int width = monitorRect.Width; 
      int x = 0; 
      int y = 0; 

      if (heightRatio > 1f && widthRatio > 1f) 
      { 
       height = img.Height; 
       width = img.Width; 
       x = (int)((float)(monitorRect.Width - width)/2f); 
       y = (int)((float)(monitorRect.Height - height)/2f); 
      } 
      else 
      { 
       if (heightRatio < widthRatio) 
       { 
        width = (int)((float)img.Width * heightRatio); 
        height = (int)((float)img.Height * heightRatio); 
        x = (int)((float)(monitorRect.Width - width)/2f); 
       } 
       else 
       { 
        width = (int)((float)img.Width * widthRatio); 
        height = (int)((float)img.Height * widthRatio); 
        y = (int)((float)(monitorRect.Height - height)/2f); 
       } 
      } 

      Rectangle rect = new Rectangle(x, y, width, height); 
      g.DrawImage(img, rect); 
     } 
    } 
} 
1

Eh bien, le code des prises réponses des autres et modifié un peu .... problème est que le code précédent suppose que le moniteur principal est le plus élevé et la plus à gauche nouvelle image à créer .... ça n'a pas fonctionné pour moi. Édition -> a compris que Windows 7 et 10 se comportent différemment en ce qui concerne la position de départ de l'image en mosaïque. Win 10 start en haut à gauche .... Win 7 démarre toujours avec le moniteur primaire.

using System; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using Microsoft.Win32; 
using System.Windows.Forms; 
using System.IO; 


namespace toolbox.Wallpaper 
{ 
    public class CustomWally 
    { 
     const int SetDeskWallpaper = 20; 
     const int UpdateIniFile = 0x01; 
     const int SendWinIniChange = 0x02; 
     [DllImport("user32.dll", CharSet = CharSet.Auto)] 
     static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni); 




     Point primaryMonitorPoint = new Point(0, 0); 
     const string defaultBackgroundFile = @"C:\Users\Public\Pictures\Sample Pictures\DefaultBackground.jpg"; 
     Dictionary<string, Image> images = new Dictionary<string, Image>(); 

     public CustomWally() 
     { 
      //figure out where the main monitor is in relation to the virtualScreenBitmap 
      foreach (Screen scr in Screen.AllScreens) 
      { 
       images.Add(scr.DeviceName, null); 
       screenos.Add(scr.DeviceName); 
       if (scr.Bounds.Left < primaryMonitorPoint.X) 
        primaryMonitorPoint.X = scr.Bounds.Left; 
       if (scr.Bounds.Top < primaryMonitorPoint.Y) 
        primaryMonitorPoint.Y = scr.Bounds.Top; 
      } 
      primaryMonitorPoint.X *= -1; 
      primaryMonitorPoint.Y *= -1; 

      //Image for multiple screens 
      images.Add("all", null); 

      //set Images in Dictionary in case there are previous Images 
      if (File.Exists(defaultBackgroundFile)) 
      { 
       using (var old = new Bitmap(defaultBackgroundFile)) 
       { 
        foreach (Screen scr in Screen.AllScreens) 
        { 
         Rectangle rectangle = new Rectangle(primaryMonitorPoint.X + scr.Bounds.Left, primaryMonitorPoint.Y + scr.Bounds.Top, scr.Bounds.Width, scr.Bounds.Height); 
         if (old.Width >= (rectangle.X + rectangle.Width) && 
          old.Height >= (rectangle.Y + rectangle.Height)) 
          images[scr.DeviceName] = (Bitmap)old.Clone(rectangle, old.PixelFormat); 
        } 
       } 
      } 
     } 



     List<string> screenos = new List<string>(); 
     int index = 0; 


     public void setAlternatingWalls(string file) 
     { 
      images[screenos[index]] = Image.FromFile(file); 
      index++; 
      if (index == screenos.Count) 
       index = 0; 

      CreateBackgroundImage(Method.multiple); 
      GC.Collect(); 
     } 

     public void setWallforScreen(Screen screen, string file) 
     { 
      images[screen.DeviceName] = Image.FromFile(file); 
      CreateBackgroundImage(Method.multiple); 
      GC.Collect(); 
     } 

     public void setWallforAllScreen(string file) 
     { 
      images["all"] = Image.FromFile(file); 
      CreateBackgroundImage(Method.single); 
      GC.Collect(); 
     } 


     private enum Method 
     { 
      multiple, 
      single 
     } 
     private void CreateBackgroundImage(Method method) 
     { 

      using (var virtualScreenBitmap = new Bitmap((int)System.Windows.Forms.SystemInformation.VirtualScreen.Width, (int)System.Windows.Forms.SystemInformation.VirtualScreen.Height)) 
      { 
       using (var virtualScreenGraphic = Graphics.FromImage(virtualScreenBitmap)) 
       { 

        switch (method) 
        { 
         // alternated Screen Images 
         case Method.multiple: 
          foreach (var screen in System.Windows.Forms.Screen.AllScreens) 
          { 
           // gets the image which we want to place in virtualScreenGraphic 
           var image = (images.ContainsKey(screen.DeviceName)) ? images[screen.DeviceName] : null; 

           //sets the position and size where the images will go 
           Rectangle rectangle = new Rectangle(primaryMonitorPoint.X + screen.Bounds.Left, primaryMonitorPoint.Y + screen.Bounds.Top, screen.Bounds.Width, screen.Bounds.Height); 

           // produce a image for the screen and fill it with the desired image... centered 
           var monitorBitmap = new Bitmap(rectangle.Width, rectangle.Height); 
           if (image != null) 
            DrawImageCentered(Graphics.FromImage(monitorBitmap), image, rectangle); 

           //draws the picture at the right place in virtualScreenGraphic 
           virtualScreenGraphic.DrawImage(monitorBitmap, rectangle); 
          } 
          break; 

         //Single screen Image 
         case Method.single: 
          // gets the image which we want to place in virtualScreenGraphic 
          var image2 = images["all"]; 

          //sets the position and size where the images will go 
          Rectangle rectangle2 = new Rectangle(0, 0, virtualScreenBitmap.Width, virtualScreenBitmap.Height); 

          // fill with the desired image... centered        
          if (image2 != null) 
           DrawImageCentered(virtualScreenGraphic, image2, rectangle2); 

          //draws the picture at the right place in virtualScreenGraphic 
          virtualScreenGraphic.DrawImage(virtualScreenBitmap, rectangle2); 
          break; 
        } 

        virtualScreenBitmap.Save(defaultBackgroundFile, ImageFormat.Jpeg); 
       } 
      } 

      RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true); 
      key.SetValue(@"WallpaperStyle", 0.ToString()); 
      key.SetValue(@"TileWallpaper", 1.ToString()); 
      SystemParametersInfo(SetDeskWallpaper, 0, defaultBackgroundFile, UpdateIniFile | SendWinIniChange); 
     } 


     private void DrawImageCentered(Graphics g, Image img, Rectangle monitorRect) 
     { 
      double ratiodev = (1.0 * monitorRect.Width/monitorRect.Height) - (1.0 * img.Width/img.Height); 
      if (((1.0 * monitorRect.Width/monitorRect.Height > 1) && ratiodev > -0.25 && ratiodev < 0.25)) 
      { 
       img = getsnappedIMG(img, monitorRect); 
      } 


      float heightRatio = (float)monitorRect.Height/(float)img.Height; 
      float widthRatio = (float)monitorRect.Width/(float)img.Width; 
      int height = monitorRect.Height; 
      int width = monitorRect.Width; 
      int x = 0; 
      int y = 0; 

      if (heightRatio < widthRatio) 
      { 
       width = (int)((float)img.Width * heightRatio); 
       height = (int)((float)img.Height * heightRatio); 
       x = (int)((float)(monitorRect.Width - width)/2f); 
      } 
      else 
      { 
       width = (int)((float)img.Width * widthRatio); 
       height = (int)((float)img.Height * widthRatio); 
       y = (int)((float)(monitorRect.Height - height)/2f); 
      } 
      Rectangle rect = new Rectangle(x, y, width, height); 
      g.DrawImage(img, rect); 
     } 

     private Image getsnappedIMG(Image img, Rectangle monitorRect) 
     { 
      double ratiodev = (1.0 * monitorRect.Width/monitorRect.Height) - (1.0 * img.Width/img.Height); 
      int height = img.Height; 
      int width = img.Width; 

      Rectangle rect; 
      if (ratiodev < 0) 
      { 
       rect = new Rectangle(0, 0, (int)((1.0 * monitorRect.Width/monitorRect.Height) * height), height);     
       rect.X = (width - rect.Width)/2;     
      } 
      else 
      { 
       rect = new Rectangle(0, 0, width, (int)(1.0 * width/(1.0 * monitorRect.Width/monitorRect.Height))); 
       rect.Y = (height - rect.Height)/2; 
      } 


      var img2 = (Bitmap)img; 
      return (Bitmap)img2.Clone(rect, img.PixelFormat); 

     } 
    } 
}