[RESOLVIDO] Alterar registro do Windows usando C++

Olá!
Pessoal, estou tentando fazer uma DLL que pudesse alterar um valor do registro do Windows, mas não estou conseguindo alterar. Esse é meu código:

#include <windows.h>
#include <winreg.h> 

DLLIMPORT bool SetWallpaper(char* path) {
    bool retorno;
    
    HKEY key;
    RegOpenKeyA(HKEY_CURRENT_USER, "Control Panel\\Desktop", &key);
    RegSetValueA(HKEY_CURRENT_USER, "Control Panel\\Desktop", 2, "WallpaperStyle", REG_SZ);
    RegSaveKeyA(HKEY_CURRENT_USER, "Control Panel\\Desktop", 0);
    RegCloseKey(key);
    
    retorno = SystemParametersInfoA(20, 0, path, 0);
    return retorno;
}

A DLL está alterando o Wallpaper do computador, mas não está alterando o registro. O que tem de errado?

Obrigada

Você está passando os parâmetros errados, usando as APIs erradas, e provavelmente passando um tipo de arquivo errado. O Windows XP só aceita arquivos .bmp, não .png ou .jpeg. Você precisa efetuar as conversões manualmente para .bmp se precisar usar com Windows XP; no Windows Vista ou 7 é possível passar um arquivo .jpg.

O código abaixo funciona corretamente. Não se esqueça de usar as bibliotecas user32.lib e advapi32.lib.

#include <windows.h>
#include <io.h>

bool SetDesktopWallpaper (const char *filename) {
    HKEY hKey;
    BYTE value [2]; 
    strcpy ((char *) value, "2");
    if (::RegOpenKeyEx (HKEY_CURRENT_USER, "Control Panel\\Desktop", 0, NULL, &hKey) == ERROR_SUCCESS) {
        ::RegSetValueEx (hKey, "WallpaperStyle", 0, REG_SZ, value, strlen ((char*)value) + 1);
        ::RegCloseKey (hKey);
    }
    return ::SystemParametersInfo (SPI_SETDESKWALLPAPER, 0, (PVOID) filename, SPIF_SENDCHANGE | 

SPIF_UPDATEINIFILE) != 0;
}

int main (int argc, char *argv[]) {
    if (argc >= 2) {
        SetDesktopWallpaper (argv[1]);
    }
}

Não se esqueça que usar um número mágico (20) não é recomendável em C++.

Em vez disso, você DEVE usar as constantes simbólicas, definidas na documentação (o MSDN é seu amigo de fé e seu irmão camarada :stuck_out_tongue: )

Além disso, em C++ é aconselhável usar sempre o indicador de escopo global ("::") para indicar APIs do Windows.

Obrigada pelas dicas!!
Eu realmente não sabia dessas coisas, porque só sei programar em java e estou tentando fazer uma DLL :shock:
Vou testar aqui e digo depois se funcionou!

Valeu

entanglement, como que eu faço pra converter o JPG pra BMP?

Obrigada

Ok… resolvido aqui… não vou fazer isso usando C++, vou fazer essa conversão usando Java.
Vou usar a minha DLL só pra alterar o registro do Windows.

Antes de mais nada, queria fazer só mais uma pergunta:
Após eu alterar o registro do windows, eu preciso reiniciar o computador para que as configurações sejam validadas?

Obrigada

Costumo fazer o seguinte: uso algum programa que faz a conversão para mim (como o ImageMagick, http://www.imagemagick.org/script/index.php ) e o chamo via Runtime.exec.

Entretanto, parece que a API ImageIO tem um “writer” para o formato BMP. Vou dar um exemplo:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5076878

Aquele parâmetro mágico passado para SystemParametersInfo (SPIF_SENDCHANGE | SPIF_UPDATEINIFILE) tem a função de fazer com que o Windows reconheça a modificação nos parâmetros do wallpaper imediatamente; se você passar 0, como você tinha feito, o Windows não fica sabendo que você modificou a configuração, e você teria de se deslogar desse usuário e logar novamente.

Obrigada, entanglement.
Resolvido meu problema. Esse é o código que eu usei pra redimensionar a imagem

File fileImg = new File("arquivo.JPG"); Dimension dimOriginal = Toolkit.getDefaultToolkit().getScreenSize(); BufferedImage image = ImageIO.read(fileImg); int newWidth = dimOriginal.width, newHeight = dimOriginal.height; BufferedImage newImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g = newImage.createGraphics(); g.drawImage(image, 0, 0, newWidth, newHeight, null); File output = new File(IMAGEM_TEMP); ImageIO.write(newImage, "BMP", output);