Samual
Samual

Reputation: 552

How can I set windows 10 desktop background with smooth transition?

I am changing my windows desktop background with the following code

ctypes.windll.user32.SystemParametersInfoW(20, 0, "C:/image/jkk7LGN03aY.jpg" , 0)

my image directory has so many images and I am setting those one by one as follows

for path in image_list:
    ctypes.windll.user32.SystemParametersInfoW(20, 0, path , 0)
    time.sleep(5)

Desktop background image is changing abruptly but I want a smooth transition. How can I do this?

Upvotes: 3

Views: 1170

Answers (1)

abdusco
abdusco

Reputation: 11081

Here's a pure Python snippet that I use regularly:

It uses pywin32 to enable active desktop and set the wallpaper using a smooth transition (make sure you've not disabled window effects or you won't see any fade effect)

import ctypes
from typing import List

import pythoncom
import pywintypes
import win32gui
from win32com.shell import shell, shellcon

user32 = ctypes.windll.user32


def _make_filter(class_name: str, title: str):
    """https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumwindows"""

    def enum_windows(handle: int, h_list: list):
        if not (class_name or title):
            h_list.append(handle)
        if class_name and class_name not in win32gui.GetClassName(handle):
            return True  # continue enumeration
        if title and title not in win32gui.GetWindowText(handle):
            return True  # continue enumeration
        h_list.append(handle)

    return enum_windows


def find_window_handles(parent: int = None, window_class: str = None, title: str = None) -> List[int]:
    cb = _make_filter(window_class, title)
    try:
        handle_list = []
        if parent:
            win32gui.EnumChildWindows(parent, cb, handle_list)
        else:
            win32gui.EnumWindows(cb, handle_list)
        return handle_list
    except pywintypes.error:
        return []


def force_refresh():
    user32.UpdatePerUserSystemParameters(1)


def enable_activedesktop():
    """https://stackoverflow.com/a/16351170"""
    try:
        progman = find_window_handles(window_class='Progman')[0]
        cryptic_params = (0x52c, 0, 0, 0, 500, None)
        user32.SendMessageTimeoutW(progman, *cryptic_params)
    except IndexError as e:
        raise WindowsError('Cannot enable Active Desktop') from e


def set_wallpaper(image_path: str, use_activedesktop: bool = True):
    if use_activedesktop:
        enable_activedesktop()
    pythoncom.CoInitialize()
    iad = pythoncom.CoCreateInstance(shell.CLSID_ActiveDesktop,
                                     None,
                                     pythoncom.CLSCTX_INPROC_SERVER,
                                     shell.IID_IActiveDesktop)
    iad.SetWallpaper(str(image_path), 0)
    iad.ApplyChanges(shellcon.AD_APPLY_ALL)
    force_refresh()


if __name__ == '__main__':
    set_wallpaper(r'D:\Wallpapers\Cool\enchanted_mountain_4k.jpg')

Upvotes: 4

Related Questions