ClipaTec Informática

Receba novidades por e-mail. Digite seu e-mail abaixo e clique no botão "Cadastrar"

Delivered by FeedBurner

2 de fevereiro de 2015

Alterando style da aplicação em tempo de execução no Delphi

delphi
 Olá pessoal, salve. Neste artigo vou ensinar vocês um recurso muito interessante que vocês poderão utilizar em suas aplicações Delphi como mais um diferencial.
Em um artigo publicado há um tempo atrás eu comentei sobre a VCL Style, que é um recurso do Delphi que permite você criar  e usar estilos em suas aplicações, estes estilos na verdade são skins para alterar a aparência da aplicação.
No Delphi já temos alguns estilos que podemos escolher e usar, até aí tudo fácil, basta ir nas configurações da aparência, selecionar o estilo desejado e Ok, automaticamente a aplicação recebe o novo estilo, porém, alguns desejam colocar esses estilos como opção ao cliente, para que ele possa escolher qual aparência usar na aplicação, ou seja, deixar o estilo livre para ser alterado em tempo de execução.
Na internet até então, não temos muitos artigos explicando como fazer isso, por isso resolvi criar este artigo para explicar para vocês como fazer isso, é simples, fácil e prático, então, let's go.
Primeiro, crie um novo projeto no Delphi, adicione 1 TButton, 1 TComboBox e uma TLabel.
Renomeie a propriedade "Name" do formulário para"FrmMain" e o "Caption" para "Change Style". Altere o "Name" do "TButton" para "btnFechar" e o "Caption" para "Fechar". Altere o "Name" do TComboBox" para "cbxStyle" e apague o conteúdo da propriedade "Text" e finalmente, altere o "Caption" da "TLabel" para "Selecione um estilo", no final, sua aplicação deverá estar parecida com a da imagem abaixo:
delphi
Salve o projeto com o nome "Style". Muito bem, o primeiro passo é selecionarmos quais os estilos estarão disponíveis em nossa aplicação para ser alterado posteriormente pelo cliente. Então, clique no menu "Project/Options". Na janela que abrir, ao lado esquerdo selecione clique no item "Appearance" da opção "Application". Feito isso, note que ao lado direito terá uma lista dos estilos que já vem com o Delphi (em Custom styles). Muito bem, então marque todos e em "Default style" (item 2) selecione um estilo que será o padrão da aplicação. Você pode visualizar como é o estilo antes de escolher, para isso, clique em cima do nome do estilo na lista e clique no botão "Preview":
delphi
Legal, agora clique no botão "Ok". Todos os estilos que marcamos agora estão registrados na aplicação e prontos para serem usados. Ao compilar o projeto, esses estilos serão adicionados junto ao executável, e isso dispensa o trabalho de você ter que copiar os estilos junto da aplicação, pois eles já estão, digamos, embutido dentro do executável.
Agora vamos para a implementação. Precisamos adicionar duas "units" ao projeto para trabalharmos com os estilos.
Vá até a "uses" da seção "Interface" e declares as units "Themes" e "Styles":
delphi
Ok, agora no escopo "Private" declare um procedimento "LoadStyles". Este método será responsável por ler os estilos registrados na aplicação e jogar na TComboBox para ficar disponível a ser escolhido:
delphi
Pressione as teclas "Shift + Ctrl + C" para implementarmos a procedure:
delphi
Legal, agora vou explicar parte por parte dessa implementação para você entender corretamente.
Primeiro criamos uma variável do tipo string "sStyles" que obterá o nome dos estilos registrados na aplicação.
Logo abaixo chamamos o método "BeginUpdate" para a propriedade "Items" da "TComboBox". Por que este método?
Quando trabalhamos com lista de strings, sempre que adicionamos uma nova string a esta lista, a aplicação é redesenhada, e se temos muitos itens a serem adicionados na lista, a cada item a aplicação é desenhada novamente, e se esta quantidade for muita, a tela fica "piscando", quando chamamos este método, a aplicação não é redesenhada, e até ganhamos em performance, apesar de hoje grande parte dos computadores serem bem potentes.
Agora, antes de carregar os itens da "TComboBox", estamos limpando os itens. No nosso caso praticamente não seria necessário, mas em determinados casos é necessário para não ficar duplicando os itens. Por boa prática, estamos chamando o "Clear".
Agora vamos fazer uso do loop (laço de repetição) "For...in". Pra quem trabalha com o Java, seria o "For...each". Resumidamente explicando, o For...in" é usado para percorrer uma coleção de objetos.
Antes de prosseguirmos a explicação do mesmo em nosso exemplo, antes preciso falar um pouco sobre a classe "TStyleManager". Esta classe é usada para manipular as operações referente aos estilos. Usamos ela para registrar ou cancelar o registro de uma classe de estilo, definir um estilo ativo, recuperar estilo, alterar estilos, etc.
O método "StyleNames" retorna uma matriz com o nome de todas as classes de estilos registrados.
Agora sim, podemos retomar a explicação, com o "For...In" estamos percorrendo a matriz de objetos, onde, estes objetos são os estilos registrados na aplicação, e estamos retornando o nome de cada um. Estes nomes são atribuídos em nossa variável e abaixo, pegamos este nome e adicionamos na "TComboBox". Isso será feito até que a lista dos estilos registrados chegue ao fim, desta forma, nossa "TComboBox" terá todos os estilos.
O comando "Sorted" que estamos atribuindo "True" é simplesmente para ordenar os itens da "TComboBox" por ordem alfabética.
Na linha de baixo, estamos apontando e selecionando na "TComboBox" o nome do "Style" que está em uso atualmente na aplicação. Na primeira vez, será o estilo que escolhemos como "Default", após o usuário alterar para outro estilo, será o nome do estilo escolhido.
Para sabermos o estilo ativo na aplicação, usamos o comando "TStyleManager.ActiveStyle.Name", onde o comando "ActiveStyle" retorna o estilo atual que está definido para a aplicação, e a propriedade "Name" retorna especificamente o nome do estilo.
Para finalizar, estamos chamando o método "EndUpdate" para indicarmos para aplicação que terminamos o trabalho e agora sim, pode ser repintada ou redesenhada.
Agora que nosso método de carregar os estilos está pronto, vamos chamá-lo no evento "OnShow" do formulário:
delphi
Duplo clique no botão "Fechar" e digite:
delphi
Agora vamos no evento "OnChange" da "TComboBox" e implemente-o desta forma:
delphi
O evento "OnChange" é executado todo vez que alteramos algum item da "TComboBox".
Note que estamos chamando o método "TrySetStyle", este método, define o estilo especificado pelo nome, ativando-o na aplicação. Se for realizado com sucesso, retorna "True", caso contrário, retorna "False". Seria interessante fazer esta validação, no nosso exemplo não foi feito, mas fica a dica.
Este método pede dois parâmetros, onde o primeiro (Name) é o nome do estilo a ser aplicado na aplicação, que no caso estamos lendo do "TComboBox", já o segundo parâmetro (ShowErrorDialog) especifica se uma caixa de diálogo de erro será exibida caso não for possível aplicar o estilo selecionado, não é um parâmetro obrigatório, porém, se não passarmos um valor para ele, por padrão o valor assumido é "True". Se você não deseja que uma mensagem de erro seja exibida, então passe "False" no segundo parâmetro.
E finalmente chegamos ao fim, agora só rodar a aplicação e testar este maravilhoso recurso.
Aqui vai outra dica, seria interessante gravar o estilo escolhido pelo usuário em um arquivo INI, para que na próxima vez que a aplicação for iniciada, o estilo escolhido seja lido do arquivo INI e aplicado na mesma.
delphi
Show de bola, e aqui concluo mais um artigo, abraço a todos que nos acompanham e até o próximo.

(Por Welinton J. Dias)

31 comments:

  1. Boa tarde amigo. Gostaria de parabenizá-lo pelo ótimo trabalho, me ajudou muito. Gostaria de saber também se você pode me informar se posso utilizar isso para mudar os estilos de outros programas que desenvolvi.

    ResponderExcluir
    Respostas
    1. Boa tarde Gabriel.
      Primeiramente agradecemos por seu comentário.
      Respondendo sua pergunta, desde que você consiga abrir seus projetos em alguma versão do Delphi a partir da 2009, que tem o suporte a VCL Style, basta fazer as implementações como segue o tutorial que vai funcionar. Qualquer dúvida sobre como proceder, só comentar que ajudaremos. Grande abraço.

      Excluir
  2. boa tarde, estou usando e funciona ok em algumas maquinas, mas algumas ele não pega o tema, sabe me dizer pq isso acontece? sera q tenho q manda algo junto ao exe?

    ResponderExcluir
    Respostas
    1. Ola amigo,
      Você escolhe um estilo no combobox e o mesmo não é aplicado, isso?
      Aparece algum erro? Qual o sistema operacional da máquina que não funcionou? Aguardamos suas respostas para compreendermos melhor o cenário. Abraço.

      Excluir
    2. Respondendo sua pergunta, conforme o autor explica no tutorial, quando você executa o passo 2 da segunda imagem, os estilos são compilados no executável, desta forma, não se faz necessário distribuir os arquivos juntos. Forte abraço.

      Excluir
  3. Excelente artigo e muito esclarecedor!!! Parabéns Welinton J. Dias, estou migrando uma aplicação desenvolvida originalmente em Delphi 6 para o XE 7, e com certeza vou usar essa opção para dispor aos usuários. Muito obrigado!

    ResponderExcluir
  4. Boa noite o código funciona perfeitamente, mas sempre que troco o Skin o form fecha. Gostaria de saber se tem algum propriedade ou o que posso fazer para continuar no form de alteração de Skin. Assim eu poderia criar um botão e só depois que clicar nele é que gravaria o Skin no banco ou em um INI.

    Desde já obrigado pela atenção.

    ResponderExcluir
    Respostas
    1. Olá meu caro,
      Isso, você pode gravar o nome do Style no arquivo INI e na hora de abrir o programa, você lê e aplica as configurações. Se tiver dúvida de como fazer, comenta aqui que vamos montar uma vídeo-aula pra te ajudar melhor. Forte abraço.

      Excluir
  5. Olá poderia me dar um exemplo de como ler os estilos no arquivo ini consegui gravar mais não consigo ler.

    ResponderExcluir
    Respostas
    1. Olá amigo, para isso, basta ler o nome do Style gravado no INI anteriormente e jogar em uma variável por ex:
      "sNomeStyle := oIni.ReadString('Style', 'Name', 'Windows');"
      E depois setar o style na aplicação:
      "TStyleManager.TrySetStyle(sNomeStyle);"
      Caso tenha dificuldades em trabalhar com arquivo INI, segue nosso video, parte1, no canal tema parte 2 tbm:
      https://www.youtube.com/watch?v=GEH7AUcsSL8
      Abraço

      Excluir
  6. Bom dia amigos. Gostei muito desse post, ajudou muito.
    Estou com uma duvida que eu não sei se é possível resolver sem grandes alterações nos componentes de skin.
    Eu gostaria de saber se é possível alterar apenas um item da skin em tempo de execução, vou utilizar meu caso como exemplo, eu deseja aplicar uma skin branca, onde o PageControl quando está na vertical permanece com a cor da skin branca, e quando estiver na horizontal a skin deve ser alterada para azul, isso sem carregar duas skins diferentes.
    Obrigado pela atenção.

    Att.

    ResponderExcluir
    Respostas
    1. Não conhecemos se existe essa possibilidade em tempo de execução, o indicado seria vc fazer uma cópia do arquivo do style e modificar de acordo com sua preferência usando a ferramenta dentro da própria IDE que se chama: "Bitmap Style Designer"

      Excluir
  7. Muito bom esse post, me ajudou e está bem atualizado.

    Senhores estou com uma necessidade que não sei se é possível resolver apenas com uma unica skin, atualmente eu preciso alterar a aparência de um único item da skin em tempo de execução, vou exemplificar com o meu caso, estou utilizando uma skin branca na minha aplicação, a aba na vertical é branca conforme skin nativa, porém na horizontal deve se tornar azul, possuindo um estilo customizado. Eu alterei a skin e criei mais um estilo para o TabHeader, onde eu o chamei de TabHeaderVer, é possível alterar esse item da skin em tempo de execução?

    Muito obrigado pela atenção.

    ResponderExcluir
    Respostas
    1. Olá amigo, ainda não fizemos este tipo de teste, de antemão, cremos que neste caso teria que criar o seu próprio style customizado a seu gosto. Caso a gente encontre alguma novidade sobre isso, postaremos uma resposta aqui. Um grande abraço.

      Excluir
  8. amigo gostaria de uma ajuda criei uma rotina pra mudar o skin so que toda vez que saio ele volta pra original oque devo fazer o código que to usando e o seguntie
    procedure TFrmINI.LoadStyle;
    var
    sstyles : string;

    begin
    cbxStyle.Items.BeginUpdate;
    try
    cbxStyle.Items.Clear;
    for sstyles in TStyleManager.StyleNames do
    cbxStyle.Items.Add(sstyles);
    cbxStyle.Sorted :=True;
    cbxStyle.ItemIndex := cbxStyle.Items.IndexOf(TStyleManager.ActiveStyle.Name);

    finally
    cbxStyle.Items.EndUpdate;

    end;

    end;
    conforme mudo a combo ele muda, criei um ini pra salvar o nome que alterei so que quando fecho ele volta no primeiro

    ResponderExcluir
    Respostas
    1. Olá, tudo bem?
      Você está lendo o arquivo INI quando a aplicação é aberta?

      Excluir
  9. sim amigo hora que vai abrir o programa ele le em show, mas um erro

    ResponderExcluir
  10. na verdade não consigo mudar o skin default do projeto essa e a realidade se conseguir já resolve meus problemas, por exemplo se eu ir manualmente lá em projeto aparência e mudar o sistema sempre abre com aquela cara, queria fazer isso por código, mas só consegui alterar enquanto estou com o sistema aberto quando fecho ele volta pro padrão default que esta lá no projeto

    ResponderExcluir
    Respostas
    1. Talvez você não está gravando a alteração no arquivo INI ao fechar a aplicação ou na hora que o style é alterado. Para um suporte mais aprimorado, entre em nossa página de contato e envie seu email para que possamos resolver este problema, ou nos adicione no skype: clipatecinfo. Estamos aguardando o seu retorno, um grande abraço.

      Excluir
  11. Parabéns! Ótimo post. Já estou utilizando em meus projetos.
    Mas queria perguntar algo...
    como fazer para ele mostrar um exemplo apenas na tela que esta aberta? como se fosse um PREVIEW?
    Valeu!

    ResponderExcluir
    Respostas
    1. Você diz uma janela de preview do tema igual a do Delphi quando vc pre-visualiza o efeito do style? Entendemos correto sua dúvida?

      Excluir
  12. Olá, será que teria como aplicar o skin em apenas determinado formulário da aplicação?

    ResponderExcluir
    Respostas
    1. Até onde sabemos não, pois a skin é aplicada no objeto da aplicação como um todo.

      Excluir
  13. Fiz em um segundo form somente para mudança do Stylo.
    Mas após mudar da erro de violação. :(

    ResponderExcluir
    Respostas
    1. Já debugou para saber em qual linha está levantando o AV? Se sim, poste pra gente tentar ajudar. Abraço.

      Excluir
  14. Muito bom, pena que não te a explicação de como gravar no arquivo ini

    ResponderExcluir
    Respostas
    1. Olá, temos um artigo que pode ajudar na criação de arquivos INI:
      https://www.clipatecinformatica.com.br/2012/07/arquivo-ini-de-configuracao-no-delphi.html

      Temos tbm uma vídeo-aula bem explicativa:
      https://www.youtube.com/watch?v=GEH7AUcsSL8&t=13s

      Caso tenha dúvidas ainda, dê um feedback. Abraços

      Excluir
  15. Muito obrigado amigo! Excelente tutorial, forte abraço.

    ResponderExcluir

Visite nossa página de Política de comentarios antes de comentar para ter certeza de que seu comentário não será excluído! Lembre-se, assim que aprovarmos o teu comentário ele será publicado, por isso, não deixe de sempre visitar nosso blog e conferir nossa resposta ao seu comentário, abraço!