Ir para conteúdo
Fórum Script Brasil
  • 0

Uxtheme - Alguém Já Brincou Com Ele?


Micheus

Pergunta

Recentemente, num post que tratava sobre outro assunto, quando foi mensionado um exemplo que introduzia um novo botão na barra de título da janela, apareceram questionamentos sobre se ele utilizava ou não o tema do Windows.

Ficou a dúvida, a curiosidade. Seria fácil utilizar o recurso de tema do windows para desenhar um novo botão na barra de título? Bom, isto envolveria muito mais que simplesmente desenhar utilizando o tema. É necessário processar mensagens específicas (as Non Client - WM_NC...). Foi discutida também a se o botões padrões na barra de título(Max, Min, Restore, Close) seriam ou não bitmap's. E verificamos que no caso específico do uso de tema, tratam-se de bitmaps (veja figuras neste link)

Depois de trocar algumas MP's com o Thales, achei que poderia ser interessante trocar idéia sobre o assunto. Este questionamento não é urgente, mas acredito que possamos descobrir os detalhes mais rápidos se houver mais pessoas interessadas em investigar.

Aplicação para este conhecimento? Bom, acho que pensaremos em alguma. Na verdade, uma delas é a personalização de componentes, já que você pode construir componentes e desenhar eles utilizando as configurações de temas como você bem entender - desenhar o THeadControl utilizando a "textura" da barra de títulos, p.e..

Referências msdn:

- Tudo sobre as funções/estruturas/... relacionadas a tema -> Visual Style Reference

- Partes e estados, os principais parâmetros que as funções utilizam -> Parts and States(P&S)

A partir da versão 7 do Delphi, foi incluida a unit UxTheme (delphipath\source\rtl\win), se alguém se interessar pelo assunto e não a possuir acredito que baste conseguir/solicitar para resolver esta questão.

Eu comecei meu programa teste com um form e um label, apenas para ter um retorno visual sobre o processo de inicialização do uso de tema:

procedure TForm1.FormCreate(Sender: TObject);
begin
  if InitThemeLibrary then
  begin
    if UseThemes then
      Label1.Caption := 'XP Theme inicializado e tema está em uso'
    else
      Label1.Caption := 'XP Theme inicializado e tema não está em uso';
  end else
    Label1.Caption := 'Não foi possível inicilizar recuros para uso de temas (XP Theme)';
end;
InitThemeLibrary retornará true apenas se conseguir carregar uxtheme.dll e inicializar o ponteiro para as funções nela presentes. Introduzindo um botão e mais um label, tentei obter qual (dos 3) temas está em uso. Encontrei uma forma que foi através da localização das imagens. Utilizando a função GetThemeFilename é possível obter o nome e localização base da figura quando o parâmetro é TMT_IMAGEFILE (veja ref. P&S para especificar a imagem de 1 a 5):
procedure TForm1.Button1Click(Sender: TObject);
var
  HndTheme :HTheme;
  ThemeFileName,
  ThemeClasseList :array[0..255] of WideChar;
  ThemePart,
  ThemeState :LongInt;
begin
  StringToWideChar('WINDOW', ThemeClasseList, SizeOf(ThemeClasseList));
  HndTheme := OpenThemeData(Handle, ThemeClasseList);
  if HndTheme > 0 then
  begin
    ThemePart := WP_CLOSEBUTTON;
    ThemeState := CBS_HOT; // CBS_DISABLED  CBS_HOT  CBS_NORMAL  CBS_PUSHED
    if GetThemeFilename(HndTheme, ThemePart, ThemeState, TMT_IMAGEFILE, ThemeFileName, SizeOf(ThemeFileName)) = S_OK then
    begin
      Label2.Caption := 'GetThemeFilename retornou: '+WideCharToString(ThemeFileName);
    end else
      Label2.Caption := 'Houve erro ao executar GetThemeFilename';
    CloseThemeData(hndTheme);
  end else
    ShowMessage('Não foi possível encontrar a classe '+WideCharToString(ThemeClasseList));
end;
Observar a necessidade de os parâmetros "strings" serem utilizados no formato WideChar. A alteração do tema em meu Desktop seguida da execução do programa resutou no seguinte: 1) Metallic\CloseButton.bmp 2) Blue\CloseButton.bmp 3) HomeStead\CloseButton.bmp Isto já confirma que os botões da barra de título são realmente bitmap's. Desabilitar o uso de tema (Estilo tema clássico do Windows), resultou em: - no Label1 -> XP theme inicializado e não está em uso; - no Label2 -> nada escrito e apresentada mensagem Não foi possível encontrar a classe WINDOW. Desenhando o botão na área de cliente da janela principal (apenas a parte alterada):
  ...
    end else
      Label2.Caption := 'Houve erro ao executar GetThemeFilename';

    DrawThemeBackground(HndTheme, Canvas.Handle, ThemePart, ThemeState, Rect(150, 32, 150 +25, 32 +25), nil);

    CloseThemeData(hndTheme);
  end else
  ...
Observar que a localização é em relação a área de cliente de cujo o HDC é passado. Assim, se introduzirmos um Panel no form, poderemos desenhar a mesma imagem dentro dele, porém, neste caso, como não temos acesso ao canvas do TPanel, teremos que criar um Device Context (DC) para ele (apenas a parte alterada):
procedure TForm1.Button1Click(Sender: TObject);
var
  DC :HDC;
  HndTheme :HTheme;
  ...
    end else
      Label2.Caption := 'Houve erro ao executar GetThemeFilename';

    DrawThemeBackground(HndTheme, Canvas.Handle, ThemePart, ThemeState, Rect(150, 32, 150 +25, 32 +25), nil);

    DC := GetDC(Panel1.Handle);
    DrawThemeBackground(HndTheme, DC, ThemePart, ThemeState, Panel1.ClientRect, nil);
    ReleaseDC(Panel1.Handle, DC);

    CloseThemeData(hndTheme);
  end else
  ...

Acho que ficou meio com cara de tutorial, mas queria já adiantar um pouco do que descobri (quase nada).

Algumas dúvidas:

1) DrawThemeIcon é uma função que parece ser de grande utilidade. Entretanto, tentei adicionar um TImageList e passar seu handle para esta função e não obtive sucesso. Se alguém conseguir fazer uso dela com o componente TImagelist, por favor post aqui.

2) Não consegui, ainda, entender para que serve ou por que utilizar a passagem de mais de uma classe no parâmetro ThemeClasseList em OpenThemaData. Alguma ideia?

3) Será que é possível utilizar/carregar um tema para minha aplicação que não seja o que atualmente está definido no Windows XP?

[]s

p.s. andei dando uma mexida no texto

Link para o comentário
Compartilhar em outros sites

1 resposta a esta questão

Posts Recomendados

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,2k
    • Posts
      651,9k
×
×
  • Criar Novo...