quarta-feira, outubro 20, 2010

Criando um web site - Sample WebSite Parte 1

A pouco tempo ministrei o curso 2310 - Developing Web Applications Using Microsoft Visual Studio 2008 e resolvi criar uma aplicação para mostrar um pouco mais da implementação na vida real.

Vou abordar essa aplicação em varias partes para não ficar muito extensa e focar mais no exemplo de cada artigo.

Banco de dados - inicialmente o banco vai conter três tabelas:
Usuario
Produto
UsuarioXProduto
A estrutura do projeto consiste em três camadas, Business Layer(Regras de Negocios), DBAccess(Acesso a Dados) e DB Model(Modelo do Banco).

Funcionamento:
DBModel - contém o modelo do banco de dados
Business Layer - contém todas as regras de negócios da aplicação
DBAccess - contém os métodos de acesso a dados

sexta-feira, outubro 01, 2010

TCP Client & Server

Essa semana precisei fazer um server e um client usando TCP. Depois de muita busca achei a melhor solução no livro C# CookBook 2nd Edition da Editora O´Reilly. Mas claro que no livro a solução não estava 100%, faltava declarar uns namespaces e um objeto.

No livro o autor cita que será usado o System.Net mas assim que comecei a ler o codigo percebi que ia precisar de outras namespaces, então declarei as seguintes:

using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;

No meu caso utilizei as listadas a cima mas para seguir o exemplo do livro também é necessário declarar a seguinte namespace para utilizar o Trace:

using System.Diagnostics;

Com isso fiz a seguinte alteração no codigo, troquei o Trace.WriteLine por Console.WriteLine, assim consigo ver todos os resultados no console, quando o Trace aparece apenas no output do debug.

Como a classe é meio grande vou fatiar em pedaços para ficar mais claro mas fica o link para baixar o codigo.

A estrutura inicial da classe é a seguinte:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;

namespace TCP_UDP_Server
{
    public class TCPServer
    {
        private TcpListener listener = null;
        private IPAddress address;
        private int port;
        private bool listening = false;
        private object _syncRoot;

        public TCPServer(IPAddress address, int port)
        {
            this.address = address;
            this.port = port;
            _syncRoot = this;
        }

        public void Listen()
        {
            //CODE HERE
        }

        public void StopListening()
        {
            if (listening)
            {
                lock (_syncRoot)
                {
                    listening = false;
                    listener.Stop();
                }
            }
        }

        private void ProcessClient(object client)
        {
            //CODE HERE
        }

        public IPAddress Address
        {
            get { return address; }
        }

        public int Port
        {
            get { return port; }
        }

        public bool Listening
        {
            get { return listening; }
        }
    }
}

No método Listen() é criado uma escuta para o endereço e a porta configurada. Após isso fica escutando a porta por mensagens do client(o client não vou comentar nesse post, vou criar outro só para explicar sua funcionalidade).

try
{
    lock (_syncRoot)
    {
        listener = new TcpListener(address, port);
        listener.Start();
        listening = true;
    }

    do
    {
        Console.Write("Looking for someone to talk to... ");

        TcpClient newClient = listener.AcceptTcpClient();
        Console.Write("Connected to new client");

        ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessClient), newClient);

    } while (listening);
}
catch (SocketException se)
{
    Console.WriteLine("SocketException: ", se.ToString());
}
finally
{
    StopListening();
}

E no método ProcessClient() é recebido o pacote e transformado em uma string. Ao receber os dados retorna uma mensagem para o client avisando o recebimento.

TcpClient newClient = (TcpClient)client;
try
{
    byte[] bytes = new byte[1024];
    StringBuilder clientData = new StringBuilder();

    using (NetworkStream ns = newClient.GetStream())
    {
        ns.ReadTimeout = 60000;
        int bytesRead = 0;
        do
        {
            try
            {
                bytesRead = ns.Read(bytes, 0, bytes.Length);
                if (bytesRead > 0)
                {
                    clientData.Append(Encoding.ASCII.GetString(bytes, 0, bytesRead));
                    ns.ReadTimeout = 3000;
                }
            }
            catch (IOException ioe)
            {
                Console.WriteLine("Read time out: "+ ioe.Message);
                bytesRead = 0;
            }
        } while (bytesRead > 0);

        Console.WriteLine("Client says: " + clientData.ToString());

        bytes = Encoding.ASCII.GetBytes("Thanks call again!");

        ns.Write(bytes, 0, bytes.Length);
    }
}
finally 
{
    if (newClient != null)
        newClient.Close();
}

sexta-feira, maio 21, 2010

PAC MAN!

Pacman completa 30 anos, e o google não podia ficar de fora. Criou uma versão comemorativa do game na tela inicial. Eu como sou viciado em games não pude deixar de dar uma conferida no game. Para quem não conhece ou nunca jogou fica uma imagem da versão original, ou umas dela.

quinta-feira, abril 22, 2010

Bordas usando apenas CSS

Li em algum artigo sobre como fazer bordas sem usar javascript ou imagem. Achei interessante e útil então vou deixar arquivado aqui. Vou ficar devendo o link, mas assim que achar posto aqui.

A técnica é simples, basta criar divs ou outro elemento com margens diferentes na parte superior e inferior do conteúdo. De forma que uma margem fique menor ou maior que a outra gradativamente.

O CSS fica assim:

/*ROUNDED BORDER DIV*/
#Borda h1, #Borda h2, #Borda p {margin:0 10px; letter-spacing:1px; padding:0;}
#Borda h1 {font-size:2.5em; color:#fff;}
#Borda h2 {font-size:2em;color:#06a; border:0;}
#Borda p {padding-bottom:0.5em;}
#Borda h2 {padding-top:0.5em;}
#Borda {background: transparent;}

.xtop, .xbottom {display:block; background:transparent; font-size:1px;}
.xb1, .xb2, .xb3, .xb4 {display:block; overflow:hidden;}
.xb1, .xb2, .xb3 {height:1px;}
.xb2, .xb3, .xb4 {background:#E5E5E5; border-left:1px solid #CCC; border-right:1px solid #CCC;}
.xb1 {margin:0 5px; background:#CCC;}
.xb2 {margin:0 3px; border-width:0 2px;}
.xb3 {margin:0 2px;}
.xb4 {height:2px; margin:0 1px;}

.Conteudo {display:block; background:#E5E5E5; border:0 solid #CCC; border-width:0 1px;}


E no HTML.

<div id="Borda">
    <b class="xtop">
        <b class="xb1"></b>
        <b class="xb2"></b>
        <b class="xb3"></b>
        <b class="xb4"></b>
    </b>
    <div class="Conteudo">
        CONTENT
    </div>
    <b class="xbottom">
        <b class="xb4"></b>
        <b class="xb3"></b>
        <b class="xb2"></b>
        <b class="xb1"></b>
    </b>
</div>

terça-feira, janeiro 26, 2010

ASP.NET e C# definindo a cultura do site

Para definir a cultura, basta colocar o codigo abaixo no web config.
<system.web>
    <globalization requestEncoding="iso-8859-1" responseEncoding="iso-8859-1" culture="pt-br" uiCulture="pt-br"/>
</system.web>
Caso não funcione, tente fazer um override no método abaixo para forçar a cultura. Se funcionar provavelmente a cultura está sendo alterada em outro lugar.
protected override void OnLoadComplete(EventArgs e)
{
    base.OnLoadComplete(e);
    Page.Culture = "pt-br";
}
Neste caso, re-veja o código da MasterPage ou na própria pagina verifique a primeira linha no aspx onde define a herança e os vinculos.
<%@ ... Culture="pt-br" %>

terça-feira, janeiro 19, 2010

Executando um processo C# :: Code Snippet

Utilizar a System.Diagnostics e System.Security.
Process p;
Process[] processos;
processos = Process.GetProcessesByName("calc");

if (processos.Length == 0)
{
    p = new Process();
    ProcessStartInfo info = new ProcessStartInfo();
    //para executar o processo com um usuario e senha
    //info.UserName = "user";
    //info.Password = SecureString("pass");
    //info.UseShellExecute = false;
    info.FileName = "calc";
    p.StartInfo = info;
    p.Start();
}
protected SecureString SecureString(string pass)
{
    SecureString ss = new SecureString();
    foreach (char c in pass)
    {
        ss.AppendChar(c);
    }
    return ss;
}

segunda-feira, dezembro 21, 2009

Alterando o app.config

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
AppSettingsSection configSection = config.AppSettings;

try
{
    if (configSection != null)
    {
        if (configSection.IsReadOnly() == false && configSection.SectionInformation.IsLocked == false)
        {
            configSection.Settings["myKey"].Value = "newValue";
            config.Save();
        }
    }
}
catch (ConfigurationException ex)
{
    MessageBox.Show(ex.Message, "Configuration Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

terça-feira, dezembro 15, 2009

C# Process Show() Hide()

Aqui vai um código bem curto de como manipular o estado(Show/Hide) de um processo. O exemplo foi feito em uma aplicação windows e parte do código foi ocultada para simplificar.

using System.Diagnostics;
using System.Runtime.InteropServices;

namespace MyApp
{
    public partial class frmApp : Form
    {
        private const int SW_HIDE = 0;
        private const int SW_RESTORE = 9;
        private int hWnd; 

        [DllImport("User32")]
        private static extern int ShowWindow(int hwnd, int nCmdShow);

        private void btnShow_Click(object sender, EventArgs e)
        {
            //Seleciona o primeiro processo
            Process p = Process.GetProcesses()[0];
            hWnd = (int)p.MainWindowHandle;
            ShowWindow(hWnd, SW_RESTORE);
        }
    }
}
Parte do exemplo foi retirado do site C# Corner

Abaixo a tabela completa dos estados retirado do site DaniWeb:
0 SW_HIDE
1 SW_SHOWNORMAL
1 SW_NORMAL
2 SW_SHOWMINIMIZED
3 SW_SHOWMAXIMIZED
3 SW_MAXIMIZE
4 SW_SHOWNOACTIVATE
5 SW_SHOW
6 SW_MINIMIZE
7 SW_SHOWMINNOACTIVE
8 SW_SHOWNA
9 SW_RESTORE
10 SW_SHOWDEFAULT
11 SW_FORCEMINIMIZE
11 SW_MAX

quinta-feira, setembro 10, 2009

XNA Tower Defence

Tower Defence é um estilo de jogo muito conhecido na web, com muitas variações e bem aceito quando os gráficos são bons e a jogabilidade é desafiadora. Essa foi a motivação para iniciar o desenvolvimento deste jogo. Ainda sem nome e sem uma versão de testes mas em constante desenvolvimento, o objetivo é disponibilizar a versão até o fim do mês.

Gostaria de participar da produção desse jogo? Entre em contato e descreva a aérea de interesse!

Jogo: Tower Defence
Plataforma: PC e XBOX 360
Comandos: Controle do XBOX360 - Direcional esquerdo e RT
Jogadores: De 1 a 4
Pré-requisitos:
Controle XBOX 360
Ultima versão do DirectX
Microsoft XNA Framework Redistributable 3.1

segunda-feira, agosto 31, 2009

XNA Game Programming

Estou desenvolvendo um game que servirá de exemplo em meu primeiro tutorial. É coisa simples para facilitar o entendimento dos programadores iniciantes, tanto em XNA como em linguagem de programação.

Em todo caso, se alguem tiver interesse em fazer a arte ou o som do game é só entrar em contato.

Plataforma: PC e XBOX 360
Comandos: PC - setas, espaço e R, XBOX - LD, A e Y
Pré-requisitos: Ultima versão do DirectX.

quinta-feira, agosto 27, 2009

Regular Expression Validator


Desenvolvi um programa para testar as expressões regulares e também armazena-las. O aplicativo é bem simples, é feito uma leitura no arquivo XML de todas as expressões e valida os campo abaixo para demonstrar os possíveis casos. Texto em vermelho significa que a o valor não confere com a expressão e textos em azul são os que estão válidos. RegexValidator v1.0

sexta-feira, agosto 14, 2009

Symbol Barcode Reader :: Erro CoreDLL.dll

Ao desenvolver minha aplicação para Windows CE tive um problema com o leitor de código de barras do aparelho Morotola Symbol M1000, ele não lia a codificação I2OF5. Depois de muita pesquisa na web consegui com sucesso juntar várias pistas pra chegar a uma solução.

O que acontece é que por padrão a codificação I2OF5 vem com os valores MaximumLength e MinimumLength alterados para não dar conflito com outra codificação. Dae apara faze-la funcionar seria só mudar os parametros e ok... bem, quase isso. Primeiro tentei o seguinte:
Reader reader = new Reader();
reader = bcLeitor.Reader;
reader.Decoders.I2OF5.MinimumLength = 10;
reader.Decoders.I2OF5.MaximumLength = 16;
reader.Decoders.I2OF5.CheckDigitScheme = I2OF5.CheckDigitSchemes.None;
reader.Decoders.I2OF5.ConvertToEAN13 = false;
reader.Decoders.I2OF5.Redundancy = false;
reader.Decoders.I2OF5.ReportCheckDigit = false;
bcLeitor.Reader = reader;
Mas sem sucesso, o erro "Não é possível carregar a DLL 'CoreDLL.dll'" persistia. Então descobri que não é possível criar um novo Reader, pelo menos não assim. E alterei o código para:

Reader reader = null;
reader = bcLeitor.Reader;

reader.Decoders.I2OF5.MinimumLength = 10;
reader.Decoders.I2OF5.MaximumLength = 16;
reader.Decoders.I2OF5.CheckDigitScheme = I2OF5.CheckDigitSchemes.None;
reader.Decoders.I2OF5.ConvertToEAN13 = false;
reader.Decoders.I2OF5.Redundancy = false;
reader.Decoders.I2OF5.ReportCheckDigit = false;
reader.Changes.Save();
reader.Actions.SetParameters();
E não tive mais problema com a DLL e nem com a leitura do código.

quinta-feira, agosto 06, 2009

Windows CE Application

Farei uma abordagem de um aplicativo para Windows CE utilizando o Visual Studio 2008 e o Framework 2.0 e em breve tutorial de como fazer deploy para um dispositivo movel e algumas dicas do erros mais comuns.

Inicialmente é preciso intalar:
  • ActiveSync para Windows XP ou o Windows Mobile Device Center para Windows Vista.
  • .Net Framework 2.0 ou superior, no PC e no dispositivo o Compact Framework.
Dica: Caso não instale o Compact Framework no dispositivo, ao rodar a aplicação aparecerá um erro de falta de componentes. Isso pode ser uma DLL do projeto faltando ou até o Compact Framework. No meu caso tive esse problema, o único erro que aparecia era esse número 0x89731705 ainda não sei exatamente se ele se refere a falta de componente ou a falta de espaço no disco quando tentava instalar o CF.

Feito isso basta desenvolver o aplicativo e fazer o deploy. Algumas configurações úteis para o deploy.

Em propriedades, devices, verifique:
  • Target Device está selecionado corretamente.
  • Output file folder está selecionado para o local correto onde a aplicação será copiada.
  • Remova o check Deploy the lastest cersion of .net compat.... (no meu caso, ao selecionar essa opção o VS copia o CF.cab - intalador - para dentro da pasta windows e como não tenho espaço livre deixei para instalar o CF direto do dispositivo).
Depois de ajustar as propriedades isso é só fazer o deploy e rodar a aplicação. Não esqueça de instalar o Compact Framework!

Uma dica muito útil é instalar o Remote Display Control, pra poder acessar o dispositivo remotamente, ainda mais quando se trata de um coletor com poucas teclas e sem touch screen.

quarta-feira, agosto 05, 2009

Tudo Aí!

Aproveitando o espaço, vou divulgar meu site de anúncios. É totalmente gratuito e espero conseguir evoluir a idéia conforme explicação no site. Caso tenha interesse ou alguma sugestão entre em contato!



quarta-feira, julho 29, 2009

Silverlight :: Grid :: Adicionando componentes dinamicamente

Como nem tudo é alegria na vida de um programador e as vezes temos que adicionar um componente dinamicamente no codigo ou ler um arquivo de um template e criar uma tela apartir dele. Pelo menos sempre tem uma solução :P a um tempo atras desenvolvi um algoritmo que le uma classe ou um xml e cria a tela em tempo de execução. Como os controles do Silverlight são diferentes não foi so migrar o codigo para o Silverlight e pronto. Abaixo um exemplo basico de como criar as linhas e colunas e adicionar no Grid, comentado no post anterior.

gridCadastro.ColumnDefinitions.Add(new ColumnDefinition());
gridCadastro.RowDefinitions.Add(new RowDefinition());

TextBox txt = new TextBox();
TextBlock lbl = new TextBlock();

//label
lbl.Text = "e-mail";
lbl.SetValue(Grid.RowProperty, 0);
lbl.SetValue(Grid.ColumnProperty, 0);
lbl.HorizontalAlignment = HorizontalAlignment.Left;

//textbox
txt.MaxLength = 30;
txt.Width = 100;
txt.Name = "txtEmail";
txt.SetValue(Grid.RowProperty, 0);
txt.SetValue(Grid.ColumnProperty, 1);
txt.HorizontalAlignment = HorizontalAlignment.Left;

gridCadastro.Children.Add(lbl);
gridCadastro.Children.Add(txt);

Silverlight :: Grid

Uma breve introdução ao controle GRID do silverlight.
Bom inicialmente para utilizar o controle é preciso definir as linhas e colunas do grid, abaixo é possivel ver os ROWS e COLUMN DEFINITION que indica as caracteristicas de cada linha e coluna dentro do grid. Por padrão se as linhas e colunas não tiverem altura e largura definidas, serão ajustadas conforme o controle pai.
No meu exemplo utilizei tipos diferentes para as linhas a fim de demonstrar esse comportamento.
A primeirta linha tem altura fixa, a segunda uma altura máxima e a terceira se ajusta com o tamanho restante conforme o comportamento do controle pai.
Para as duas primeiras colunas utilizei o AUTO que vai definir o tamanho conforme o controle filho, já a terceira coluna vai pegar todo o restante da largura.
Sobre os controles, é necesário posicionar cada um dentro do grid. :(
É, pra quem está acostumado com o velho HTML é algo no mínimo estranho, mas ok.
Então para cada controle definimos as caracteristicas Grid.Row e Grid.Column, se em algum controle não for definido, por padrão será colocado o valor zero, posicionando assim na primeira linha e/ou coluna.
<Grid Name="gridCadastro" Background="YellowGreen" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="25"></RowDefinition>
<RowDefinition MaxHeight="60"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>

<TextBlock Grid.Row="0" Grid.Column="0" Text="e-mail"></TextBlock>
<TextBox Grid.Row="0" Grid.Column="1" Width="100" Height="25"></TextBox>

<TextBlock Grid.Row="1" Grid.Column="0" Text="password" VerticalAlignment="Center"></TextBlock>
<TextBox Grid.Row="1" Grid.Column="1" Width="100" Height="25"></TextBox>

<Button Grid.Row="2" Grid.Column="2" Content="GO!" Height="30" ></Button>
</Grid>


E o resultado...

quarta-feira, julho 15, 2009

Twitter

Eu no twitter http://twitter.com/danielcolnaghi não esperem muita coisa, ainda não vejo finalidade pra ele hehe.

segunda-feira, julho 13, 2009

Usando Reflection

A um tempo atrás desenvolvi um gerador de classes, logo depois incrementei um gerador de interface seguindo um padrão pré estabelecido. Algumas vezes criar geradores pode ser uma solução para criar um projeto do zero com uma certa garantia de qualidade. Digo isso porque normalmente o código gerado não contém erros(pelo menos eu acho que não pode!).
Em todo caso sistemas que estão em constante mudanças, o gerador se torna uma ferramenta superficial e que pode causar dor de cabeça. Isso porque para continuar utilizando o gerador o desenvolvedor usará seu tempo programando o código a ser gerado e não o código final.
Uma outra abordagem para evitar o gerador e não comprometer o tempo que seria ganho com ele, é criar telas genéricas e manipular as classes dinamicamente.
No exemplo abaixo criei um método que carrega os dados do objeto e popula os campos da tela conforme um arquivo XML que contém a definição para cada campo.
protected void CarregarObjeto(string codigo)
{
Assembly a = Assembly.Load("MyClassLib");
var obj = a.CreateInstance("MyNamespace.MyClass");
Type t = obj.GetType();
PropertyInfo[] pInfo = t.GetProperties();
// pInfo[0] = PK
if (t.GetProperties()[0].PropertyType.FullName == "System.String")
{
pInfo[0].SetValue(obj, codigo, null);
}
else
{
pInfo[0].SetValue(obj, Convert.ToInt32(codigo), null);
}

t.GetMethod("Load").Invoke(obj, null);

foreach (PropertyInfo p in t.GetProperties())
{
if (p.GetValue(obj, null) != null && plhCadastro.FindControl(string.Concat("txt", p.Name)) != null)
{
((TextBox)plhCadastro.FindControl(string.Concat("txt", p.Name))).Text = p.GetValue(obj, null).ToString();
}
}
}

quinta-feira, julho 09, 2009

Subsonic 3

Subsonic 3 está disponível para downlaod e agora com o framework 3.5, ainda estou testando para ver quais as novidades e se ele está estável mesmo hehe.

No entanto para rodar os exemplos será preciso baixar o ASP.NET MVC disponível no site www.asp.net ou diretamente no site da microsoft.