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.