different wallpaper for each screen for multi-moni

2019-02-15 12:07发布

问题:

I'm using:

ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER,
                                           0, "picturefile", 0)

To change the wallpaper.

But I'm wondering if there's any simple way to put different wallpapers on each screen.

This feature isn't standard in windows though, but there are external applications like ultramon that do this. Anyone know how that works?

The way I thought it might work if I join the two images together into one and then make that the wallpaper, but then I still need a way to span one image accross both screens.

Also, how could I grab some info about the monitor setup, the resolution of each screen and their placement? Like what you see in the gui display settings in windows, but in numbers.

回答1:

  1. After joining the images together into a big image, you have to set the wallpaper mode to tiled to make it so the image spans the desktop (otherwise it will restart on each monitor).

    Couple of ways to do this:

    a) Using IActiveDesktop (which does not require Active Desktop to be used, don't worry). This is nicest as on Win7 the new wallpaper will fade in.

    You create an IActiveDesktop / CLSID_ActiveDesktop COM object and then call SetWallpaper, SetWallpaperOptions and finally ApplyChanges. (As I'm not a Python dev, I'm not sure exactly how you access the COM object, sorry.)

    OR:

    b) Via the registry. This isn't as nice, but works well enough.

    Under HKEY_CURRENT_USER\Control Panel\Desktop set:

    • TileWallpaper to (REG_SZ) 1 (i.e. the string "1" not the number 1)
    • WallpaperStyle to (REG_SZ) 0 (i.e. the string "0" not the number 0)
    • Then call SystemParameterInfo(SPI_SETDESKTOPWALLPAPER...) as you do already.

    .

    By the way, the code I'm looking at, which uses IActiveDesktop and falls back on the registry if that fails, passes SPIF_UPDATEINIFILE | SPIF_SENDCHANGE as the last argument to SystemParameterInfo; you're currently passing 0 which could be wrong.

  2. EnumDisplayMonitors is the Win32 API for getting details on the monitors, including their screen sizes and positions relative to each other.

    That API returns its results via a callback function that you have to provide. (It calls it once for each monitor.) I am not a Python developer so I'm not sure how you can call such a function from Python.

    A quick Google for "Python EnumWindows" (EnumWindows being a commonly-used API which returns results in the same way) finds people talking about that, and using a Lambda function for the callback, so it looks like it's possible but I'll leave it to someone who knows more about Python.

    Note: Remember to cope with monitors that aren't right next to each other or aren't aligned with each other. Your compiled image may need to have blank areas to make things line up right on all the monitors. If you move one of the monitors around and do a PrtScn screenshot of the whole desktop you'll see what I mean in the result.