Trabalhando com Interfaces

Mudando o Papel de Parede instantaneamente

Salve amigos do ClubeDelphi. É sempre um prazer enorme poder colaborar com a comunidade. Depois de alguns meses fora do ar e do fórum estou voltando a tona e com força total.

E para começar vou passar uma dica especial. Como trabalhar com Interfaces. Nesta dica vamos aprender a mudar o papel de parede do Windows instantaneamente.

Tenho visto que muitos, assim como eu, procuram uma solução prática e funcional para se trocar em runtime o papel de parede do Windows. A tarefa não é difícil, basta fazer algumas alterações no registro do Windows e usar a API SystemParametersInfo que informa ao Sistema Operacional que houve uma alteração. Veja:

 

procedure TForm1.Button1Click(Sender: TObject);

   procedure ChangeWallpaper(bitmap: string);

   var

      pBitmap : pchar;

   begin

      bitmap := bitmap+#0; {bitmap contém um arquivo *.bmp}

      pBitmap := @bitmap[1];

      SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, pBitmap,SPIF_UPDATEINIFILE);

   end;

begin

   if OpenDialog1.Execute then

      ChangeWallpaper(OpenDialog1.FileName);

end;

 

Isso já funcionaria. Funcionaria, se não fosse o Windows 2000, pois a função acima precisa de um reinicio ou logoff na máquina para que as alterações tenham efeito. Pesquisando nas bibliotecas do Delphi descobri uma interface que faz exatamente isso: IActiveDesktop. A tarefa não é muito fácil de entender, mas funciona perfeitamente.

A Interface mencionada acima tem como objetivo trabalhar toda a área de desktop do Windows. Para exemplificar o uso abra um novo projeto e declare as units ShlObj e ComObj. A primeira possui a interface e a segunda será usada para criar um objeto do tipo IActiveDesktop para podermos manipular o mesmo. Inicie desenhando uma tela semelhante a figura a seguir:

 

 

No botão Localizar digite um algoritimo capaz de selecionar um JPG e atualizar o TImage com a imagem selecionada e o Edit1 com o caminho da imagem. Agora no botão atualizar escreva o algoritimo abaixo:

 

procedure TForm1.AtualizarClick(Sender: TObject);

const

  CLSID_ActiveDesktop: TGUID = (D1: $75048700; D2: $EF1F; D3: $11D0;D4: ($98, $88, $00, $60, $97, $DE, $AC, $F9));

var

  twpoComponentOpt : TComponentsOpt;

  ActiveDesktop : IActiveDesktop;

  Buffer : Array [0..1000]of WideChar;

  Addr : String;

  Endereco : PWideChar;

  WallpaperOptions : TWallpaperOpt;

begin

  ActiveDesktop := CreateComObject(CLSID_ActiveDesktop) as IActiveDesktop;

  {Ativa o ActiveDesktop - Equivale a: Propriedades de Vídeo >> Web >> Exibir conteúdo da   web no Active Desktop}

  with twpoComponentOpt do

    begin

      ZeroMemory(@twpoComponentOpt, SizeOf(TComponentsOpt));

      dwSize := SizeOf(twpoComponentOpt);

      fEnableComponents := True;

      fActiveDesktop := True;

    end;

  ActiveDesktop.SetDesktopItemOptions(twpoComponentOpt, 0);

  ActiveDesktop.ApplyChanges(AD_APPLY_ALL);

  {FIM}

  {Verifica como será colocado o papel de parede}

  Case ComboBox1.ItemIndex of

    0: WallpaperOptions.dwStyle := WPSTYLE_CENTER; {Centralizado}

    1: WallpaperOptions.dwStyle := WPSTYLE_TILE; {Lado a Lado}

    2: WallpaperOptions.dwStyle := WPSTYLE_STRETCH; {Estendido ou Esticado}

  end;

  WallpaperOptions.dwSize := SizeOf(WallpaperOptions);

  ActiveDesktop.SetWallpaperOptions(WallpaperOptions, 0);

  {FIM}

  {Aplica o Papel de Parede}

  Addr := Edit1.Text;

  Endereco := StringToWideChar(Addr,Buffer,Length(Addr) + 1);

  ActiveDesktop.SetWallpaper(Endereco,0);

  ActiveDesktop.ApplyChanges(AD_APPLY_ALL or AD_APPLY_FORCE);

  {FIM}

end;

 

Note a variável:

   ActiveDesktop: IActiveDesktop;

 

Ela é instanciada usando o método de criação de objetos.

   ActiveDesktop := CreateComObject(CLSID_ActiveDesktop) as IActiveDesktop;

 

Ela faz toda a diferença, pois é reponsável pelas atualizações do papel de parede.

Mas para que nosso exemplo funcione é necessário que em propriedades de vídeo, na guia WEB, esteja ativada a opção de exibição de conteúdo web no Desktop. Para isso fiz uma chamada direto ao procedimento que o ativa, veja:

 

  {Ativa o ActiveDesktop - Equivale a: Propriedades de Vídeo >> Web >> Exibir conteúdo da   web no Active Desktop}

  with twpoComponentOpt do

    begin

      ZeroMemory(@twpoComponentOpt, SizeOf(TComponentsOpt));

      dwSize := SizeOf(twpoComponentOpt);

      fEnableComponents := True;

      fActiveDesktop := True;

    end;

  ActiveDesktop.SetDesktopItemOptions(twpoComponentOpt, 0);

  ActiveDesktop.ApplyChanges(AD_APPLY_ALL);

  {FIM}

 

Desta forma, mesmo que a opção esteja desativada ela será automaticamente ativada. Bom, pra finalizar basta colocar um botão no form e fazer a chamada a nossa função.