Cambiar fondo de escritorio C#

La invocación de plataforma es un servicio que permite que el código administrado llame a funciones no administradas implementadas en bibliotecas de vínculos dinámicos (DLL), como las que se encuentran en la API Win32. Localiza e invoca una función exportada y calcula las referencias a sus argumentos (enteros, cadenas, matrices, estructuras, etc.) dentro de los límites de la interoperabilidad, según sea necesario.

La invocación de plataforma se basa en los metadatos para localizar funciones exportadas y calcular las referencias a sus argumentos en tiempo de ejecución. En la siguiente ilustración se muestra este proceso.

Cuando la invocación de plataforma llama a una función no administrada, realiza la siguiente secuencia de acciones:
  1. Localiza el archivo DLL que contiene la función.
  2. Carga el archivo DLL en memoria.
  3. Localiza la dirección de la función en la memoria e inserta sus argumentos en la pila y realiza el cálculo de referencias de datos necesario.
  4. Transfiere el control a la función no administrada.
La invocación de plataforma devuelve las excepciones generadas por la función no administrada al llamador administrado.

La identidad de una función de un archivo DLL está formada por los siguientes elementos:
  • Nombre de la función u ordinal
  • Nombre del archivo DLL donde se puede encontrar la implementación
Por ejemplo, si se especifica la función MessageBox en el archivo User32.dll, se identifica la función ( MessageBox) y su ubicación (User32.dll, User32 o user32). La interfaz de programación de aplicaciones de Microsoft Windows (API Win32) puede contener dos versiones de cada función que controla caracteres y cadenas: una versión ANSI de caracteres de 1 byte y una versión Unicode de caracteres de 2 bytes. Si no se especifica, el juego de caracteres, representado por el campo CharSet, toma el valor predeterminado de ANSI. Algunas funciones pueden tener más de dos versiones.

MessageBoxA es el punto de entrada ANSI para la función MessageBox; la versión Unicode es MessageBoxW. Es posible enumerar nombres de función para un archivo DLL específico, como user32.dll, mediante la ejecución de diversas herramientas de la línea de comandos. Se puede utilizar, por ejemplo, dumpbin /exports user32.dll o link /dump /exports user32.dll para obtener nombres de función.

Archivos DLL de la API Win32 que se utilizan con frecuencia

  • GDI32.dll
    • Funciones de la interfaz de dispositivo gráfico (GDI) para la salida de dispositivos, como las funciones de administración de fuentes y dibujos.
  • Kernel32.dll
    • Funciones del sistema operativo de bajo nivel para la administración de memoria y el control de recursos.
  • User32.dll
    • Funciones de administración de Windows para el control de mensajes, los temporizadores, los menús y las comunicaciones.

Cambiar fondo de escritorio desde WPF


De que nos podría servir acceder a una API no administrada, pues muchas de las funciones del sistema solo están disponibles desde el API Win32 y no tenemos acceso directo a ellas desde .Net pero podemos hacer uso de la invocación de plataforma para ejecutar estas funciones.

Por ejemplo si deseáramos cambiar el fondo de escritorio de nuestra pc deberemos llamar a la función SystemParametersInfo la cual sirve para obtener o cambiar las configuraciones del sistema. 

Estos son los pasos a seguir:

Identifique funciones en archivos DLL.

Debe especificar, como mínimo, el nombre de la función y el nombre del archivo DLL que la contiene.

Cree una clase para contener funciones de archivos DLL.

Puede utilizar una clase existente, crear una clase individual para cada función no administrada, o crear una clase que contenga un conjunto de funciones no administradas relacionadas.

Cree prototipos en código administrado.

Utilice DllImportAttribute para identificar el archivo DLL y la función. Marque el método con los modificadores static y extern.

Llame a una función de un archivo DLL.

Llame al método de la clase administrada del mismo modo que lo haría con cualquier otro método administrado. Pasar estructuras e Implementar funciones de devolución de llamada son casos especiales.


private const uint SPI_SETDESKWALLPAPER = 20;
private const uint SPIF_UPDATEINIFILE = 0x01;
private const uint SPIF_SENDWININICHANGE = 0x02;

[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SystemParametersInfo(uint uiAction, uint uiParam, string pvParam, uint fWinIni);

public static void SetDesktopWallpaper(string path)
{
    if (!SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, path, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE))
    {
        throw new Win32Exception();
    }
}


La función SetDesktopWallpaper llama a la función no administrada SystemParametersInfo a la cual hay que pasarle la ruta de la imagen que deseamos establecer como fondo.


Nota: algunos formatos de imágenes no son admitidos “probado con .jpg”, el funcionamiento de la función SystemParametersInfo es mucho más complejo de lo explicado, algunos detalles se han omitido por simplicidad.

Comentarios

Entradas populares de este blog

Conectar SQL Server con Java

Entrenar OpenCV en Detección de Objetos

Detección de figuras geométricas