我可以在Java / Groovy中以编程方式更改我的Windows桌面墙纸吗?

时间:2011-01-20 17:22:19

标签: java groovy

有没有办法在Windows XP中使用Java(或Groovy)来更改我的桌面墙纸?我有一个程序,每天(或每当)创建一个新的图像,我想要一种自动更新我的桌面的方法。

我在这个网站上似乎有一些关于C ++或.NET的问题,但我没有看到任何特定于Java的内容。

5 个答案:

答案 0 :(得分:25)

对不起,我有点落后@ ataylor的回答,因为我正在准备一个代码片段。是的,JNA是一种正确的方法。你走了:

import java.util.HashMap;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.UINT_PTR;
import com.sun.jna.win32.*;

public class WallpaperChanger {
   public static void main(String[] args) {
      //supply your own path instead of using this one
      String path = "C:\\Users\\Public\\Pictures\\Sample Pictures\\Chrysanthemum.jpg";

      SPI.INSTANCE.SystemParametersInfo(
          new UINT_PTR(SPI.SPI_SETDESKWALLPAPER), 
          new UINT_PTR(0), 
          path, 
          new UINT_PTR(SPI.SPIF_UPDATEINIFILE | SPI.SPIF_SENDWININICHANGE));
   }

   public interface SPI extends StdCallLibrary {

      //from MSDN article
      long SPI_SETDESKWALLPAPER = 20;
      long SPIF_UPDATEINIFILE = 0x01;
      long SPIF_SENDWININICHANGE = 0x02;

      SPI INSTANCE = (SPI) Native.loadLibrary("user32", SPI.class, new HashMap<Object, Object>() {
         {
            put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
            put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
         }
      });

      boolean SystemParametersInfo(
          UINT_PTR uiAction,
          UINT_PTR uiParam,
          String pvParam,
          UINT_PTR fWinIni
        );
  }
}

您需要在类路径上安装JNA库才能使其正常工作。这是在Windows 7中测试的,XP中可能存在一些细微差别,但我认为它应该可行。该API可能是稳定的。

参考

编辑(2010/01/20):

我之前省略了SPIF_UPDATEINIFILESPIF_SENDWININICHANGE选项。现在正在按照Coding4Fun MSDN文章中的建议使用它们。

答案 1 :(得分:5)

你可以更轻松地做到:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.PVOID;
import com.sun.jna.win32.W32APIOptions;
public class Wallpaper {    
 public static interface User32 extends Library {
     User32 INSTANCE = (User32) Native.loadLibrary("user32",User32.class,W32APIOptions.DEFAULT_OPTIONS);        
     boolean SystemParametersInfo (int one, int two, String s ,int three);         
 }
public static void main(String[] args) {   
   User32.INSTANCE.SystemParametersInfo(0x0014, 0, "C:\\Users\\Public\\Pictures\\Sample Pictures\\Chrysanthemum.jpg" , 1);
   }
 }

答案 2 :(得分:3)

您可以编写batch file to change the wall-paper,然后使用

执行该批处理文件

Runtime.getRuntime.exec()

答案 3 :(得分:2)

JNA java库允许您轻松调用Win32 API调用。特别是,要更改桌面背景,您需要调用SystemParametersInfo 函数。

看看这篇文章,了解JNA:http://today.java.net/article/2009/11/11/simplify-native-code-access-jna

答案 4 :(得分:0)

这里是使用JDK16 Project Panama抢先体验版

的版本
// Tested with JDK16-panama+3-385 on Windows 10
public static void main(String[] args) throws Throwable {
    LibraryLookup user32 = LibraryLookup.ofLibrary("user32");
    MethodHandle spi = CLinker.getInstance().downcallHandle(user32.lookup("SystemParametersInfoA").get()
        // BOOL SystemParametersInfoA         (UINT uiAction,  UINT uiParam,   PVOID pvParam,       UINT fWinIni);
        , MethodType.methodType(int.class,     int.class,      int.class,      MemoryAddress.class, int.class)
        , FunctionDescriptor.of(CLinker.C_LONG,CLinker.C_LONG, CLinker.C_LONG, CLinker.C_POINTER,   CLinker.C_LONG));

    final int SPI_SETDESKWALLPAPER  = 0x0014;
    final int SPIF_UPDATEINIFILE    = 0x01;
    final int SPIF_SENDCHANGE       = 0x02;

    Path path = Path.of(args[0]).toAbsolutePath();

    try (NativeScope scope = NativeScope.unboundedScope()) {
        MemorySegment img = CLinker.toCString(path.toString(), scope);
        int status = (int)spi.invokeExact(SPI_SETDESKWALLPAPER, 0, img.address(), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
        System.out.println("Changed wallpaper to "+path+" rc="+status);
    }
}