2009-10-08 38 views
3

我有一個代碼段來設置跨兩個顯示器的單個圖像,但我最近得到了我的筆記本電腦的第二個顯示器,我想修改我的代碼來說明設置不同的圖像到每個顯示器。如何設置多個桌面背景(雙顯示器)

任何想法?

(對於單顯示器這一小段代碼片段是:

[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

我使用的UltraMon本多:http://www.realtimesoft.com/ultramon/ – tvanfosson 2009-10-08 20:52:30

+0

那其實這裏也有我的想法,他們設置這樣。然而我不喜歡爲事情付錢,因爲我只是懶得學習如何自己做。 – Crash893 2009-10-08 21:48:14

回答

1

有實際上沒有什麼區別。

想想多個顯示器,只是使壁紙空間更大。

所以你要做的是從多個圖像中創建一個壁紙圖像來填充每個顯示器的矩形區域。

這個問題看起來也像是一個duplicate

+0

多麼尷尬,我忘了這一切。我做了一個雙顯示器壁紙的搜索,我什至沒有看到。 +1查找 – Crash893 2009-10-08 21:46:02

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

嗯,採取其他的答案代碼,並修改了一下.... 問題是,前面的代碼假定主監視器是最上和最左邊的新的圖片創造....它沒有爲我工作。 編輯 - >發現Windows 7和10在平鋪圖片的起始位置方面表現不同。 Win 10開始左上角.... Win 7始終與主顯示器一起啓動。

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); 

     } 
    } 
} 
相關問題