Usando CopySourceAsHtml no Visual Studio 2008

12/10/2007 2:35:00 AM By Felipe Pessoto

Esta ferramente é muito interessante pra quem costuma inserir trechos de códigos no blog ou site.

Infelizmente o instalador dele só está preparado para o VS2005, mas você pode usá-lo no VS2008.

Para isso faça o download desse arquivo zip.

Extraia os 3 arquivos na pasta C:\Documents and Settings\<USUARIO>\Meus documentos\Visual Studio 2008\Addins
Talvez a pasta Addins não exista, então você deve cria-la.

Depois de extraidos ele já está pronto pra usar. Só para confirmar, clique em Tools -> Add-in Manager e verifique se o CopySourceAsHtml está marcado.

Agora é só selecionar o trecho desejado e clicar em Copy As Html...

E o resultado é muito bom:

 

 


   19 NumberFormatInfo NumberInfo = new NumberFormatInfo();


   20 NumberInfo.CurrencySymbol = "@";


   21 NumberInfo.CurrencyDecimalDigits = 4;


   22 DemoBuilder.NumberFormat = NumberInfo;

 

Aqui no blog não vai sair muito bem por causa do pequeno espaço horizontal, mas o html gerado fica com o visual perfeitamente igual Visual Studio.

Criando um assembly em tempo de execução

12/4/2007 1:00:00 PM By Felipe Pessoto

Vou explicar os passos básicos de como criar um pequeno assembly em tempo de execução, usando Reflection. Usando esses recursos seria possível criar um compilador para IL.

Os assemblies são feitos de: Assembly Metadata, Type Metadata, Code (IL) e Resources

  • O Assembly Metadata define propriedades como Nome e Versão do assembly
  • Type Metadata define todas as descrições de um tipo, como métodos, propriedades, nome de classe, etc
  • Code(IL) é o próprio código
  • Resources são imagens, strings, arquivos, etc

Cada assembly deve conter pelo menos um Modulo. Os módulos são uma espécie de caixa que guarda as informações sobre os Tipos.

Então vamos seguir a seguinte ordem, criamos um assembly, um modulo e um tipo, e já teremos o básico.

 

//namespaces necessarios
using System.Reflection;
using System.Reflection.Emit;

//Criamos um AssemblyName
AssemblyName AsyNome = new AssemblyName("MeuAssembly");
//Então definimos um novo assembly no atual AppDomain, não é possível criar um assembly a partir do próprio construtor
AssemblyBuilder AsyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(AsyNome, AssemblyBuilderAccess.RunAndSave);
//AssemblyBuilderAccess.RunAndSave quer dizer que podemos tanto executar esse assembly, quanto salva-lo

//Criamos o modulo a partir do assembly
ModuleBuilder ModBuilder = AsyBuilder.DefineDynamicModule("MeuModulo", "modulo.dll");
//E um tipo a partir do modulo. Este tipo é publico e serializável, você pode atribuir várias propriedades com o operador |
TypeBuilder TipoBuilder = ModBuilder.DefineType("Meutipo", TypeAttributes.Public | TypeAttributes.Serializable);

//Agora podemos definir os membros do tipo, como construtores, métodos, propriedades, etc
//Vamos criar um campo
FieldBuilder CampoBuilder = TipoBuilder.DefineField("Campo", typeof(int), FieldAttributes.Public);

//Podemos tambem salvar o assembly para uso posterior
AsyBuilder.Save("modulo.dll");‚Äč
 

Neste exemplo foi usado somente o FieldBuilder, mas você pode criar qualquer outro membro usando os: ConstructorBuilder para construtor, EnumBuilder para enum, EventBuilder para eventos, etc

Você pode usar esse recurso para criar um software que aceite plug-ins por exemplo.

Usando o LINQ

10/17/2007 2:51:00 PM By Felipe Pessoto

O .Net 3.5 traz uma novidade chamada LINQ(Language Integrated Query), que pretende integrar em uma linguagem de query uma forma de fazer pesquisas em fontes de dados.

Vou mostrar aqui como fica mais simples de gerar XML, e muito mais fácil de ler também:

//Inclua esse namespace
using System.Xml.Linq;

//Dentro do método Main
XDocument DocXml = new XDocument(
                               new XElement("Clientes",
                                      new XElement("Cliente",
                                           new XAttribute ("Nr", 1),
                                           new XElement("Nome", "Maria")
                                           )
                                      )
                                );

Console.WriteLine(DocXml);
Console.Read();



É bem mais intuitivo criar o elemento Pai e no construtor criar os filhos, do que fazer como no .Net2.0 em que você tinha que criar o elemento Filho, então criar o Pai, e adicionar o Filho no elemento Pai.

Uma diferença interessante entre o novo C#3.0 e o Visual Basic 9.0 é que o VB aceita literais XML, exemplo:

Dim ElementoXml As XElement =
     <clientes>
        <cliente nr="1">
            <nome>Maria</nome>
        </cliente>
     <clientes>


Sendo um literal, será interpretado em tempo de compilação e não uma string que vai ser convertida em runtime, assim evita-se erros inesperados. Por enquanto o C# não tem essa implementação e talvez seja assim na versão final também.

Você também pode criar elementos XML da seguinte maneira, usando uma Query Expression:

  List<int> MegaSena = new List<int>();

  MegaSena.Add(13);
  MegaSena.Add(21);
  MegaSena.Add(27);
  MegaSena.Add(33);
  MegaSena.Add(39);
  MegaSena.Add(43);

  XElement elementoNumeros =
     new XElement("Numeros",
        from Numero in MegaSena
        select new XElement("Numero", Numero)
     );

Criando uma aplicação de instância única

10/16/2007 8:51:00 PM By Felipe Pessoto

Para evitar que o usuário abra duas ou mais instâncias do seu programa, você pode usar a seguinte técnica

//Referencie o namespace System.Threading
using System.Threading;

//Classe Mutex, ela que identificará se seu programa já está aberto
Mutex m = null;
//String que usaremos para identificar o programa
const string NomeMutex =  "MEUPROGRAMA";

try
{
   //Tenta abrir o Mutex
    m = Mutex.OpenExisting(NomeMutex);
}
catch(WaitHandleCannotBeOpenedException)
{
   //Nao existe
}
if(m == null)
{
  //Caso nao exista, ele cria um novo
    m = new Mutex(true,NomeMutex);
}
else
{
  //Se existir é porque seu programa já está aberto
   m.Close();
   Application.Exit();

}

Você só precisa ter cuidado ao escolher a string de identificação, pois se houver outro programa com a mesma identificação, você não vai conseguir abrir seu programa.

Diminuindo fotos automaticamente

10/13/2007 8:54:00 PM By Felipe Pessoto

Criei esse programa pra diminuir algumas fotos de forma automatica. As vezes deixamos a câmera digital no modo com mais alta resolução e isso vai consumindo o HD. No exemplo iremos diminuir a foto pra largura ou altura(o que for maior) de 640px.

Vamos precisar de um Button, um CheckBox e uma ProgressBar:



Vamos criar o método que irá gerar a foto menor:

private void GravarThumb (FileInfo Arquivo)
{
   Bitmap bm;
   Bitmap thumb;
   int altura;
   int largura;

   bm = (Bitmap)Bitmap.FromFile(Arquivo.FullName);

   if(bm.Width > 640 || bm.Height > 640)
   {
      altura = (int)(640f/ bm.Width * bm.Height);
      if(altura > 640)
      {
         largura = (int)(640f/ bm.Height * bm.Width);
         thumb = new Bitmap(bm, new Size(largura, 640));
      }
      else
      {
         thumb = new Bitmap(bm, new Size(640, altura));
      }
   }
   else
   {
      thumb = new Bitmap(bm);
   } 
   thumb.Save(Arquivo.DirectoryName + "/tn_" + Arquivo.Name, System.Drawing.Imaging.ImageFormat.Jpeg);
}

E dentro do evento Click do Button:

if
   (folderBrowser.ShowDialog() == DialogResult.OK)
   {
   DirectoryInfo d = new DirectoryInfo(folderBrowser.SelectedPath);
   FileInfo[] Arquivos;

   if(chkIncluirSubPastas.Checked)
       Arquivos = d.GetFiles("*.jpg",SearchOption.AllDirectories);
   else
       Arquivos = d.GetFiles("*.jpg",SearchOption.TopDirectoryOnly);

   progressBar1.Maximum = Arquivos.Length;

   foreach(FileInfo Arquivo in Arquivos)
   {
      GravarThumb(Arquivo);
      progressBar1.Value++;
      Application.DoEvents();
   }
   progressBar1.Value = 0;
}