O NeoMatrix Tech está de casa nova!

Você deverá ser redirecionado em 6 segundos. Se não, visite:
http://www.leonelfraga.com/neomatrixtech
e atualize seus favoritos.

Aviso IMPORTANTÍSSIMO!

Aviso aos navegantes:

O NeoMatrix Tech mudou de casa!!!

A partir de agora, acessem pelo novo endereço:

http://www.leonelfraga.com/neomatrixtech

Ué... mas é só o domínio mudou de lugar?

R: Na verdade, não é bem assim hehe. Este domínio que você acessa agora aponta para um blog hospedado no Blogger, enquanto no novo, aponta para um blog na plataforma Wordpress, hospedagem própria, muito mais rápida e com um layout mais agradável de ler ;)

Não vou fechar este domínio igual ao que eu fiz com o NM Light (que já está 100% na nova plataforma). Talvez beeeeeeem depois eu faça isso.

Todos os posts daqui se encontram lá, e novos posts serão colocados somente no novo endereço.
A única coisa que não consegui importar foram os comentários. Mas em breve vai ter um post contando sobre a epopéia que foi migrar o NeoMatrix Tech!

Somente vou fechar a área de comentários daqui. Caso queiram comentar, favor ver o post correspondente no "Novo NeoMatrix Tech" e comentem por lá. É bem melhor! (pena que os permalinks "amigáveis para SEO" não funcionam lá, dá erro 404 e não consigo fazer a configuração funcionar. E olha que eu já vi vários artigos falando desse assunto :( ).

Quem assina o feed, já está lendo o conteúdo do novo NeoMatrix Tech!

terça-feira, 27 de outubro de 2009

Experiência com o Windows Seven

Recentemente, no dia 24/10/2009, deixei o Bill Gates um pouco mais rico comprei o novíssimo Windows Seven, que foi lançado oficialmente em todo o mundo no dia 22/10/2009.

241020091763[1]

Sim, vocês leram certo: eu comprei o Windows Seven original, versão Ultimate. Claro que ao falar que compraria (ou até mesmo ler/ouvir que eu comprei), algumas pessoas disseram (vão dizer) “baixa da internet” e coisas do gênero. Resolvi que dessa vez, não vou apelar à pirataria, queria que o sistema operacional fosse legal (em todos os sentidos).

Após um excelente encontro com o pessoal da comunidade “Orientais Adultos +/- 25-35” do Orkut, no Mercado Municipal de São Paulo e antes de ir à uma reunião em minha igreja, dei uma passada na Santa Ifigênia para procurar um lugar onde vendia o Seven. Não achei nenhuma loja, onde eu perguntei, só tinham o Vista e o Seven iria chegar em alguns dias. Incrivelmente, a versão “piratex” é a que se mais achava. Todas as barracas tinha.

Um fato curioso, é que em uma das lojas o capivara vendedor disse que arrumaria sob encomenda, sob a bagatela de R$ 900,00 e queria que desse um sinal. Me desculpe pelo baixo calão a seguir, mas quase que mandei o cara se foder.

Disse para ele:

- Isso está superfaturado! O preço OFICIAL, da Microsoft, é de R$ 669,00 em qualquer lugar!

Ele vem me argumentar que o dono da loja adquiriu 18 licenças, e mais algumas para uns notebooks à uns R$ 700,00, coisa e tal. Como eu sabia muito bem do preço, deixei para lá e fui embora da loja.

Este pequeno fato mostra como é importante estar BEM informado antes de comprar algo, evitar deixar-se levar pela falácia de um vendedor, pois ele está lá para isso mesmo: vender. Além de (dever) estar mal informado, esse cara queria me enrolar

Fui até à Kalunga da Praça Ramos de Azevedo. Lá achei as versões Home Basic e Home Premium, porém, como estava procurando exatamente pela Ultimate, perguntei ao vendedor. Não tinha lá, e após uma consulta ao estoque, verificou-se que haviam duas unidades na loja próxima ao Metrô Carrão. Fui lá e agora sim, me “apossei” do novíssimo Windows Seven Ultimate.

Mas, por que a Ultimate e não a Professional ou a Home Basic / Premium?

Como eu tenho bastante programas legados, além de desenvolver utilizando Delphi 7 e afins, um recurso que utilizarei é o Modo XP (se bem que eu já uso em uma VM…), presente na versão Professional ou acima. Como a diferença de preço da Professional e da Ultimate não é grande (pela ordem de grandeza), resolvi ficar com a versão mais completa possível.

Antes de instalar no meu PC, fiz o backup básico de meus dados no outro PC. Demorou um pouco para copiar pela rede de 100 Mbps, mas foi que foi.

Após o break, vamos entrar na parte técnica da coisa, como foi a instalação, entre outras coisitas mas! Senta que lá vem história!

Primeiramente, vou listar o hardware do meu PC e dizer a você como meu disco rígido está particionado. Vamos lá:

- Placa mãe Gigabyte GA-X48-DQ6
- Processador Core 2 Duo E8400 @ 3,0 GHz (está em stock mesmo)
- 4 GB de RAM DDR 2 800 Kingston (2x 2 GB em Dual Channel)
- HD Western Digital SATA II, de 500 GB
- Placa gráfica Sapphire com chipset gráfico ATI Radeon HD 4870, com 512 MB GDDR5
- Placa de captura Pinnacle PCTV 110i
- Kit de Teclado, Mouse e Webcam Microsoft
- Monitor LCD 22’’ Samsung SyncMaster T220
- Conjunto 5.1 Logitech
- Dongle Bluetooth xing-ling genérico

Dito meu hardware básico, meu disco rígido encontrava-se particionado da segunte forma:

- 80 GB partição primária, instalado o Windows XP (vá com Deus); as outras unidades lógicas mostradas abaixo estão em uma partição extendida.
- 85,5 GB, instalado o Windows Vista (também, vá com Deus) 
- 100,0 GB, dados de usuário (Meus Documentos, pastas de desenvolvimento, downloads)
- 100,0 GB, instalação de aplicativos mais “pesados”
- 100,0 GB, arquivos de multimídia (músicas, vídeos…)

Com o disco particionado, eu poderia instalar outro sistema e não perder os dados. Mas, para prevenir, fiz backup na outra máquina.

241020091764[1] Na caixa do Windows Seven, vieram além dos manuais, dois DVD’s, um com a versão de 32 bits e outro com a 64 bits. Como tenho um processador que suporta as instruções x64 e 4 GB de RAM, a escolha mais adequada é a versão de 64 bits. Foi a que eu instalei.

Resolvi matar a partição que estava instalado o XP. Sem dó nem piedade, cliquei no Formatar quando me foi apresentado as opções de onde instalar o Windows.

Daí por diante, a instalação foi padrão: configurei o idioma, o layout do teclado, algumas outras informações e os arquivos são copiados.

241020091766[1]

Terminada a cópia, mais um boot, e foi onde configurei a data/hora, conta de usuário, inserir o serial…

Durante o boot, notei uma coisa: ele não apresentou o menu de boot com a opção de startar o Vista. Sim, esse Vista é uma versão pirata não oficial mesmo, deveria ter sido crackeada com um lance de ROM BIOS, alguma coisa assim, pois no boot aparecia algo bem rápido na tela. E outra, a ISO que baixei era bem capada, alguns recursos foram retirados e nem instalava o SP2. Bem, agora posso dizer que essa versão não está fazendo falta nenhuma.

Primeiro boot pós-instalação, o desktop me é exibido, e vou logo ver as propriedades de sistema: TODO o meu hardware básico foi reconhecido de primeira: placa mãe, placa de TV, dongle bluetooth, placa de vídeo.

Ativei o sistema, e ele logo foi fazendo um Windows Update, que atualizou mais alguns drivers e instalou o software da webcam, do teclado e do mouse Microsoft.

Baixei do site da Gigabyte o driver da placa de som, na versão Windows Seven de 64 Bits. Fiz isso para poder ter o painel de controle nativo da placa. Quando eu instalei o Windows, a placa de som foi reconhecida.

UAU!!! TODO o meu hardware reconhecido, e NÃO baixei NENHUM outro driver. Até minha placa ATI não precisou baixar driver! E o vídeo funcionou com Aero e tudo!

Os freetards se gabam pela capacidade do Linux reconhecer bem hardware. Claro que não todos os hardwares são reconhecidos pelo Linux (e pelo Windows também), necessitando de algumas gambis… Dessa vez, o Tio Bill acertou a mão hehe.

Fiz o teste do Índice de Experiência do Windows e obtive nota 5,9, que foi definida pelo meu disco rígido. Abaixo você pode ver o resultado completo.

Indice%20de%20Experiencia%20do%20Windows[1]

Agora, hora de instalar o software básico. Vou listar cada programa que instalei, já com as ressalvas:

- Firefox 3.5 –> Fiz backup da versão que eu tinha, 3.0 e restaurei o perfil no 3.5. Algumas extensões deixaram de funcionar, mas não foi por causa do Windows. Funcionou perfeitamente.

- TweetDeck –> Instalou o runtime do Adobe Air. Funcionou perfeitamente.

- Foxit Reader (leitor de PDF)

- Skype

- Windows Live Essentials: Messenger, Writer, Movie Maker e DVD Maker

- Outlook 2003

- Office 2007

- Antivírus Avira (Free Edition)

- Alcohol 120% versão 1.9.8 build 7612: Meu medo ao instalar o Alcohol é na hora de instalar o driver SCSI para a criação das unidades virtuais. Após instalar, ele necessita ser executado como administrador (botão direito, Executar como Administrador) para entrar e pede permissao para execução (olha o UAC entrando em ação!)

- Cyberlink DVD Suite (veio com o gravador de DVD)

- Nero Express 7.9.6.0 (veio com o gravador de DVD)

- Notepad++

- VMWare 6.0 (ele está hospedando VM’s de 32 bits)

- Nokia PC Suite

- Winamp

- K-Lite Mega Codec Pack

- FeedReader (que vem com uma versão do Firebird Embeded)

- PDF Creator

- Picasa 3

- NS Virtual DJ 6.0: Este necessitou ter uma chave do registro alterada. Como ele é um programa de 32 bits, o Windows Seven instalou-o em uma pasta “Arquivos de Programas (x86)”. No registro, a chave HKLM\SOFTWARE\Wow6423Node\VirtualDJ\HomeFolder estava apontando, em formato de nome do DOS, à pasta “Arquivos de Programas” (onde são instalados os programas de 64 bits). Só foi mudar essa chave e meu programa de mixagens, onde produzo os podcasts do NM Light, começou a funcionar de boa! :-D

- Visual Studio 2008 (alguns componentes são x64)

Todos os programas acima são de 32 bits, e até agora não tive nenhum problema.

Jogos: Além de alguns joguinhos antigos, como Duke Nukem, Need for Speed Underground, que rodaram bem, testei o Racedriver GRID, um jogo um pouco mais pesado, para testar a necessidade de baixar o driver da placa de vídeo do site da ATI: não precisei baixar nada, o jogo rodou de boa, em resolução 1650x1080, com 2xAA e detalhes no máximo. Não cheguei a contar a taxa de frames por segundo, mas não tive nenhum engasgo.

desktop-seven[1]

Testei também a multimídia, especialmente a integração com a placa Pinnacle PCTV 110i, que meu deu um trabalhão no Vista: O Windows Media Center funcionou perfeitamente, tanto rádio quanto TV, não presenciei aquele delay que relatei neste post. O chato é que para utilizar a entrada S-Video, ele continua insistindo em uma interface de controle remoto :-(

O Media Player Classic também funcionou de boa, e por ele, posso trocar para a entrada S-Video, ter o áudio através do Line-in da placa de som que tudo fica bem. Sim, não houve aquela tela de erro, como estava no post onde eu relatei a minha epopéia para usar a placa de captura.

Só que o WinampTV não funcionou… aí sim, acho que ele só funciona em SO’s de 32 bits.

Senti um pouco a diferença da barra de tarefas, especialmente na hora de abrir uma janela específica de um grupo e com a localização dos itens no Painel de Controle, pois estava acostumado ao jeitão clássico, mesmo no Vista.

Também demorei um pouquinho para descobrir como se acrescenta novos itens à pasta Programas do novo Menu Iniciar: Em uma pasta qualquer em “Todos os Programas”, cliquei com o botão direito e vi o seguinte caminho: “C:\ProgramData\Microsoft\Windows\Start Menu\Programs\”. Dentro dele, criei uma nova pasta, porém ao arrastar os arquivos com o botão direito para criar o atalho, o Windows mostrou uma mensagem que não pode ser criado.

Pois bem: Criei o atalho na própria pasta do programa e o movi para essa pasta nova no Menu Iniciar. Foi de boa.

E os Meus Documentos? Como meu disco estava particionado, não necessitei de restaurar o backup que tinha feito: os dados estavam todos lá. Aí só foi colocar o meu diretório de uma das partições como um local da biblioteca Documentos. Menu Iniciar, botão direito na pasta Documentos, Propriedades. Depois, clique no botão “Incluir uma Pasta” e aponte o caminho desejado. Veja a tela abaixo:

image

Fiz a mesma coisa para as bibliotecas Músicas e Imagens.

Biblioteca? Sim, agora os “antigos” Meus Documentos, Minhas Músicas e Minhas Imagens podem apontar para mais de um lugar, para o mesmo usuário, como mostrado na imagem acima.

Falhas, telas-azuis e afins? NENHUMA. Sim, o Seven está perfeito na minha máquina. Que me desculpem os freetards, mas dessa vez, o Tio Bill acertou a mão (sim, estou repetindo isso!)! A máquina está rodando muito melhor com o Seven x64. Linux? Eu uso em máquinas virtuais. Embora eu tenha adorado o Seven, não sou nenhum Wintard ou MSTard (talvez um CSharptard… quem sabe) ;-)

Leia o restante deste post...

quarta-feira, 14 de outubro de 2009

Rapidinha: Visualizando propriedades em objetos lazy em um GridView

Se você utiliza como DataSource de um gridview uma coleção do tipo List<> ao invés de um DataTable, pode ter uma hora que teremos que listar propriedades que não são de tipos primitivos (como DateTime, string, int), e sim lazy com outros objetos.

Vamos pegar como exemplo a classe TNivel do artigo anterior. Iremos construir um GridView para listar as propriedades ID, Descrição, Próximo e Anterior, utilizando como DataSource do grid uma coleção do tipo List<TNivel>.

Veja o trecho do XHTML abaixo:

<asp:GridView runat="server" id="gvNiveis">
	<Columns>
		<asp:BoundField HeaderText="Código" DataField="Id" />
		<asp:BoundField HeaderText="Descrição" DataField="Descricao" />
		<asp:BoundField HeaderText="Proximo" DataField="Proximo.Descricao" />
		<asp:BoundField HeaderText="Anterior" DataField="Proximo.Anterior" />
	</Columns>
</asp:GridView>

Compile isso, e você será brindado com uma mensagem de erro.

Como pudemos ver no artigo anterior, as propriedades Proximo e Anterior são objetos do tipo TNivel, e ao listar os campos Descricao das propriedades Proximo e Anterior em um BoundColumn ele não aceita da forma que colocamos.

Como resolvemos isso sem apelar para o evento OnRowDataBound e preencher as células manualmente?

Solução:

Crie, para cada campo, uma TemplateColumn e dentro do ItemTemplate coloque um Label. Na propriedade Text de cada Label, coloque o seguinte comando:

Text='<%# DataBinder.Eval(Container.DataItem, "Nivel.Descricao") %>'

Com a diretiva DataBinder.Eval (parecida com a #Bind, que chegamos a utilizar em artigos anteriores), podemos fazer o Bind de objetos com lazy, que tenham enfim as propriedades com tipos primitivos.

Veja como ficou nosso grid:

<asp:GridView runat="server" id="gvNiveis">
	<Columns>
		<asp:BoundField HeaderText="Código" DataField="Id" />
		<asp:BoundField HeaderText="Descrição" DataField="Descricao" />
		<asp:TemplateColumn HeaderText="Proximo">
			<ItemTemplate>
				<asp:Label runat="server" ID="lbProx" Text='<%# DataBinder.Eval(Container.DataItem, "Proximo.Descricao") %>'></asp:Label>
			</ItemTemplate>
		</asp:TemplateColumn>
		<asp:TemplateColumn HeaderText="Anterior">
			<ItemTemplate>
				<asp:Label runat="server" ID="lbAnt" Text='<%# DataBinder.Eval(Container.DataItem, "Anterior.Descricao") %>'></asp:Label>
			</ItemTemplate>
		</asp:TemplateColumn>
	</Columns>
</asp:GridView>

Enfim, é isso aí!

Um abraço :-)

Leia o restante deste post...

domingo, 4 de outubro de 2009

Momento POG: Armadilha da POO com autorrelacionamentos

Depois de um tempinho sem postagens de programação, finalmente arrumei uma coisnha para poder compartilhar contigo!

Quando você modela uma classe a partir de uma tabela, como você faz com aqueles campos de chave estrangeira, que apontam para uma outra tabela que porventura se torne uma classe também?

Se fomos seguir 100% a POO, devemos fazer um lazy com o objeto em questão, ou seja, criar uma variável privada cujo tipo corresponda a classe daquela tabela, e a sua exposição, se for o caso, em uma propriedade.

Vamos tomar a seguinte tabela como exemplo:

Tabela Niveis

É uma tabela simples, possuindo quatro campos. O detalhe é que os campos ANTES e PROXIMO relacionam-se com o campo ID da mesma tabela, ou seja, um autorrelacionamento (é, com a nova ortografia fica esquisito hehe), ou em jargão menos técnico, uma “tabela que morde o próprio rabo”. E por duas vezes.

Vamos implementar uma classe (em C#, claro, porém, de forma bem simplificada, sem tratamento de erro e tal!) para a tabela em questão:

public class TNivel
{
	#region Variáveis Privadas
	private int _Id;
	private string _Descricao;
	private TNivel _Antes;
	private TNivel _Proximo;
	#endregion
	
	#region Propriedades
	public int Id {get {return _Id;} set {_Id = value;}}
	public string Descricao {get {return _Descricao;} set {_Descricao = value;}}
	public TNivel Antes {get {return _Antes;} set {_Antes = value;}}
	public TNivel Proximo {get {return _Proximo;} set {_Proximo = value;}}
	#endregion
	
	#region Métodos
	public TNiveis(int pNivelId)
	{
		if(pNivelId != null)
		{
			DataReader dr = getReader("select * from NIVEIS where ID = " + pNivelId.ToString());
			if(dr.HasRows)
			{
				_Id = (int)dr["ID"];
				_Descricao = (string)dr["DESCRICAO"];
				_Antes = new TNivel((int)dr["ANTES"]);
				_Proximo = new TNivel((int)dr["PROXIMO"]);
			}
		}
	}
	#endregion
}

Como você pode ver, os campos PROXIMO e ANTES foram implementados como objetos do tipo TNivel, pois eles são como “ponteiros”, apontando para objetos do mesmo tipo.

O construtor desta classe recebe um ID de nível, e atribui os valores às variáveis privadas, e no caso das variáveis _Antes e _Proximo, ele cria uma nova instância da classe TNivel, passando o respectivo ponteiro em seu construtor.

Vamos inserir alguns dados na tabela?

--------------------------------------
ID   DESCRICAO     ANTES    PROXIMO
1    NIVEL 1       NULL     2
2    NIVEL 2       1        3
3    NIVEL 3       2        NULL
--------------------------------------

Montamos os dados nessa tabela de forma que representasse uma lista encadeada, sendo o primeiro nível apontando para o segundo, o segundo apontando para o primeiro e para o terceiro, e o terceiro apontando para o segundo e fechando o encadeamento.

Vamos criar uma instância do nível 1:

TNivel Nivel1 = new TNivel(1);

Quando você executou esse código, notou que o programa ficou parado?

Pois é, o programa fica travado nessa linha! P##ra, o que aconteceu aí, parece que ficou em um looping eterno e não tem nenhum laço!

Vamos fazer agora o bom e velho teste de mesa no método construtor:

  1. Nivel1: O método obtém os dados de um DataReader
  2. Nivel1: Se o DataReader contiver algum registro, continua, senão, cai fora
  3. Nivel1: A propriedade Id é alimentada
  4. Nivel1: A propriedade Descrição é alimentada
  5. Nivel1: Uma nova instância da classe TNivel é inicializada na variável _Antes, e é passado NULL como parâmetro
  6. Nivel1._Antes: O construtor é executado, obtendo os dados de um DataReader
  7. Nivel1._Antes: O Select não retornou registros, então, cai fora
  8. Uma nova instância da classe TNivel é inicializada na variável _Proximo, e é passado “2” como parâmetro.
  9. Nivel1._Proximo: O construtor é executado, obtendo os dados de um DataReader
  10. Nivel1.Proximo: O Select retornou um registro, portanto, vamos alimentar as variáveis
  11. Nivel1.Proximo: A variável Nivel1.Proximo._Id é alimentada
  12. Nivel1.Proximo: A variável Nivel1.Proximo._Descricao é alimentada
  13. Nivel1.Proximo: Uma nova instância da classe TNivel é criada na variável _Antes, e é passado “1” como parâmetro em seu construtor
  14. Nivel1.Proximo.Antes: O construtor é executado, obtendo os dados de um DataReader
  15. Nivel1.Proximo.Antes: O Select retornou um registro (os dados do Nível 1), então, continua.
  16. Nivel1.Proximo.Antes: As variáveis _Id e _Descricao são alimentadas.
  17. Nivel1.Proximo.Antes: Uma nova instância de TNivel é criada na variável _Antes, e é passado NULL como parâmetro
  18. Nivel1.Proximo.Antes.Antes: Obtém os dados de um DataReader, porém o Select não retornou nada.
  19. Nivel1.Proximo.Antes: Uma nova instância de TNivel é criada na variável _Proximo, e é passado “2” como parâmetro em seu construtor
  20. Nivel1.Proximo.Antes.Proximo: Bem, aí vc já sabe, basta retornar ao passo 9 :-)

Notaram que conforme ele carrega os objetos _Antes e _Proximo ele vai criando instâncias de TNivel “aninhadas”? Pois é, neste caso que apresentamos, um nível sempre faz referência com pelo menos um outro nível.

Ficamos em uma sinuca de bico… Manter o paradigma POO neste caso não é viável, pois o programa fica criando estas instâncias aninhadas enquanto haver memória para tal. Como saímos disso, sendo que queremos expor os níveis Próximo e Antes como um objeto TNivel?

Graças à instituição POG temos a solução para este caso!!! Vejam o código modificado de forma que as instâncias de TNivel nas propriedades Proximo e Antes sejam criadas conforme elas são acessadas:

public class TNivel
{
	#region Variáveis Privadas
	private int _Id;
	private string _Descricao;
	private int _Antes;
	private int _Proximo;
	private TNivel _oAntes;
	private TNivel _oProximo;
	#endregion
	
	#region Propriedades
	public int Id {get {return _Id;} set {_Id = value;}}
	public string Descricao {get {return _Descricao;} set {_Descricao = value;}}
	public TNivel Antes {get {return new TNivel(_Antes);} set {_oAntes = value;}}
	public TNivel Proximo {get {return new TNivel(_Proximo);} set {_oProximo = value;}}
	#endregion
	
	#region Métodos
	public TNiveis(int pNivelId)
	{
		if(pNivelId != null)
		{
			DataReader dr = getReader("select * from NIVEIS where ID = " + pNivelId.ToString());
			if(dr.HasRows)
			{
				_Id = (int)dr["ID"];
				_Descricao = (string)dr["DESCRICAO"];
				_Antes = (int)dr["ANTES"];
				_Proximo = (int)dr["PROXIMO"];
			}
		}
	}
	#endregion
}

Note que agora no construtor de TNivel armazenamos os ID dos níveis Proximo e Antes nas variáveis privadas _Antes e _Proximo, e expomos como propriedade um objeto do tipo TNivel, que em seu método get cria uma nova instância de TNivel com o ID armazenado na variável privada correspondente.

Armazenando os ID’s ao invés de criar uma nova instância diretamente, evita com que ele a aplicação crie as instâncias aninhadas do caso anterior, e somente carregue o nível através das propriedades Proximo e Antes conforme elas são chamadas pela aplicação, sempre armazenando o ID ao invés de criar uma nova instância no construtor.

Então, quando você se deparar com uma situação de autorrelacionamento e quiser manter a POO, use este procedimento, que você não terá problemas!

Um abraço!

Leia o restante deste post...

Sobre o NeoMatrix Tech

Meu blog para assuntos profissionais, ligado com tecnologia.
Dicas de programação (grande parte de C# e ASP.NET, mas não limitado a essa plataforma :-) ), dicas de utilitários, análises de equipamentos e serviços, resenhas sobre sites que eu visito, relacionados com tecnologia, opinião sobre mercado de trabalho, metodologias de desenvolvimento, comportamento no mundo tecnológico...

NeoMatrix Light

  © Blogger templates ProBlogger Template by Ourblogtemplates.com 2008 - Editado e configurado por Leonel F.

Voltar ao TOPO