<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>FD Web</title>
	
	<link>http://fdweb.com.br</link>
	<description />
	<pubDate>Mon, 23 Jun 2008 18:55:17 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.2</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/fdweb" type="application/rss+xml" /><item>
		<title>Implementando controle de transações com TransactionScope</title>
		<link>http://feeds.feedburner.com/~r/fdweb/~3/318298322/</link>
		<comments>http://fdweb.com.br/implementando-controle-de-transacoes-com-transactionscope/#comments</comments>
		<pubDate>Mon, 23 Jun 2008 18:55:17 +0000</pubDate>
		<dc:creator>Fabio Centenaro</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Programação]]></category>

		<guid isPermaLink="false">http://fdweb.com.br/?p=27</guid>
		<description><![CDATA[Controle de transa&#231;&#245;es &#233; algo que passa batido em sistemas pequenos ou em sistemas onde a preocupa&#231;&#227;o com a consist&#234;ncia dos dados n&#227;o &#233; relevante (n&#227;o vou entrar na quest&#227;o que se um sistema possui dados inconsistentes ent&#227;o &#233; melhor n&#227;o ter sistema algum). Mas o n&#250;mero de programadores que n&#227;o utilizam algum sistema de [...]]]></description>
			<content:encoded><![CDATA[<p>Controle de transa&ccedil;&otilde;es &eacute; algo que passa batido em sistemas pequenos ou em sistemas onde a preocupa&ccedil;&atilde;o com a consist&ecirc;ncia dos dados n&atilde;o &eacute; relevante (n&atilde;o vou entrar na quest&atilde;o que se um sistema possui dados inconsistentes ent&atilde;o &eacute; melhor n&atilde;o ter sistema algum). Mas o n&uacute;mero de programadores que n&atilde;o utilizam algum sistema de controle de transa&ccedil;&atilde;o &eacute; bastante grande e a preocupa&ccedil;&atilde;o com os dados e a sua consist&ecirc;ncia acaba ficando em segundo plano. Deixou de ser exce&ccedil;&atilde;o o sistema que deve estar pronto em um curt&iacute;ssimo espa&ccedil;o de tempo e com isso outros aspectos que deveriam ser exce&ccedil;&atilde;o se tornaram regras. E controle de transa&ccedil;&atilde;o &eacute; um deles. Neste artigo veremos como implementar um sistema de transa&ccedil;&otilde;es utilizando o .NET Framework.</p>
<h2>Introdu&ccedil;&atilde;o</h2>
<p>O controle de transa&ccedil;&atilde;o serve para garantir a integridade dos dados. Isso significa que atrav&eacute;s dele podemos ter a certeza de que todos os dados ser&atilde;o gravados no banco de dados. Em caso de eventual falha em algum momento da grava&ccedil;&atilde;o todo o processo volta ao estado inicial, sem inser&ccedil;&otilde;es parciais. Ao encontrar um erro durante o processo (leia-se um ou mais <em>inserts</em> em seq&uuml;encia) simplesmente &eacute; dado um <em>rollback</em> e nada &eacute; gravado no banco. Ao completar o processo com sucesso, a transa&ccedil;&atilde;o d&aacute; um <em>commit</em> e grava os dados no banco.</p>
<h2>Exemplificando</h2>
<p>Peguemos um sistema de vendas como exemplo. Para efetuar um pedido, devemos gravar as informa&ccedil;&otilde;es do cliente na tabela <strong>cliente</strong>, os itens do pedido na tabela <strong>itens</strong>, atualizar o estoque na tabela <strong>produtos</strong> e por fim gravar os dados da venda na tabela <strong>vendas</strong>. Agora imaginemos que no meio deste processo &eacute; gerado algum erro. Digamos que j&aacute; tenhamos inserido os dados na tabela de clientes, os itens do pedido e atualizado o estoque. Falta apenas gravar os dados da venda. E neste momento ocorre algum erro. O que fazer com os dados que j&aacute; foram gravados? Como fica o estoque que j&aacute; foi atualizado? Em um sistema que n&atilde;o possui nenhum tipo de controle, isso seria o caos: o estoque fica comprometido, o banco de dados ganha inconsist&ecirc;ncias e nunca o sistema ser&aacute; confi&aacute;vel.</p>
<h2>Pondo a teoria em pr&aacute;tica</h2>
<p>Ent&atilde;o vamos implementar o nosso controle de transa&ccedil;&otilde;es utilizando o TransactionScope, fornecido pela biblioteca <em>System.Transactions.dll</em>. Em primeiro lugar devemos adicionar a referencia da biblioteca em nosso projeto. Com isso, basta ir no menu <strong>Project </strong>e depois em <strong>Add Reference</strong>.</p>
<p><img src="http://img77.imageshack.us/img77/4401/addreferencewm3.jpg" alt="Add Reference" width="374" height="396" /></p>
<p>Depois selecionamos o assembly System.Transactions.</p>
<p><img src="http://img369.imageshack.us/img369/8949/addtransactionup4.jpg" alt="Adding System.Transactions" /></p>
<p>Depois disso &eacute; s&oacute; p&ocirc;r a m&atilde;o na massa. Primeiramente adicionamos a refer&ecirc;ncia &agrave; nossa classe.</p>
<p>Em C#</p>
<blockquote><p>using System.Transactions;</p></blockquote>
<p>Em VB</p>
<blockquote><p>Imports System.Transactions</p></blockquote>
<p>Feito isso, agora implementar o controle de transa&ccedil;&otilde;es:</p>
<p>Em C#</p>
<blockquote><p>TransactionOptions options = new TransactionOptions();<br />
options.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;</p>
<p>using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, options))<br />
{<br />
//Insira os comandos de insert aqui</p>
<p>scope.Complete();</p>
<p>}</p></blockquote>
<p>Em VB.NET</p>
<blockquote><p>Using scope As New TransactionScope(TransactionScopeOption.Required, IsolationLevel.ReadCommitted)<br />
&#8216;* Insira os comandos de insert aqui<br />
scope.Complete()<br />
End Using</p></blockquote>
<h2>Par&acirc;metros Necess&aacute;rios</h2>
<p>Para criar uma nova inst&acirc;ncia de um TransactionScope, devemos passar alguns par&acirc;metros.</p>
<h3><strong>TransactionScopeOption</strong></h3>
<p>Em TransactionScopeOption temos as seguintes op&ccedil;&otilde;es:</p>
<p><strong>Required </strong>- Re-utiliza uma transa&ccedil;&atilde;o ativa ou cria uma nova caso n&atilde;o haja nenhuma ativa.</p>
<p><strong>RequiresNew</strong> - Cria sempre uma nova transa&ccedil;&atilde;o sem re-aproveitar outra transa&ccedil;&atilde;o.</p>
<p><strong>Suppress</strong> - Simplesmente n&atilde;o utiliza nenhuma transa&ccedil;&atilde;o.</p>
<h3><strong>IsolationLevel </strong></h3>
<p><strong>Serializable - </strong>Os dados, durante a transa&ccedil;&atilde;o, podem ser lidos mas nenhum dado pode ser adicionado ou modificado.</p>
<p><strong>RepetableRead - </strong>Os dados podem ser lidos e adicionados mas n&atilde;o podem ser modificados.</p>
<p><strong>ReadCommited - </strong>Dados n&atilde;o podem ser lidos, mas podem ser modificados.</p>
<p><strong>ReadUncommited - </strong>Dados podem ser lidos e modificados durante a transa&ccedil;&atilde;o.</p>
<p><strong>Snapshot - </strong>Os dados podem ser lidos e modificados, por&eacute;m, antes de modificar alguma informa&ccedil;&atilde;o, a transa&ccedil;&atilde;o verifica se o conjunto de dados permanecem os mesmos. Se tiverem sido alterados, uma exce&ccedil;&atilde;o &eacute; gerada.</p>
<p><strong>Chaos</strong> - As altera&ccedil;&otilde;es pendentes de transa&ccedil;&otilde;es em n&iacute;veis superiores n&atilde;o podem ser sobrepostas.</p>
<p><strong>Unspecified</strong> - Um IsolationLevel diferente do atual est&aacute; sendo usado, mas n&atilde;o &eacute; poss&iacute;vel determinar o seu tipo. Neste caso &eacute; gerada uma exce&ccedil;&atilde;o.</p>
<h2>Finalizando</h2>
<p>Implementar um controle de transa&ccedil;&otilde;es &eacute; algo muito simples e poupa muita dor de cabe&ccedil;a. O ideal seria que todos os sistemas, por mais simples que sejam, utilizassem um controle como este. Desta forma seria poss&iacute;vel entregar sistemas mais seguros e confi&aacute;veis, melhorando a qualidade do produto e a imagem do desenvolvedor junto aos clientes.</p><p>Confira ofertas de: <a href="http://centenaro.org/submarino/?pal=DVD" rel="external" target="_Blank">DVD</a>, <a href="http://centenaro.org/submarino/?pal=filmes" rel="external" target="_Blank">filmes</a>, <a href="http://centenaro.org/submarino/?pal=celular" rel="external" target="_Blank">celular</a>, <a href="http://centenaro.org/submarino/?pal=notebook" rel="external" target="_Blank">notebook</a>, <a href="http://centenaro.org/submarino/?pal=livros" rel="external" target="_Blank">livros</a>, <a href="http://centenaro.org/submarino/?pal=jogos" rel="external" target="_Blank">jogos</a>, <a href="http://centenaro.org/submarino/?pal=Wii" rel="external" target="_Blank">Wii</a>, <a href="http://centenaro.org/submarino/?pal=PS3" rel="external" target="_Blank">PS3</a>, <a href="http://centenaro.org/submarino/?pal=MP4" rel="external" target="_Blank">MP4</a></p><p>a</p>
<p><a href="http://fdweb.com.br/implementando-controle-de-transacoes-com-transactionscope/">Implementando controle de transa&ccedil;&otilde;es com TransactionScope</a></p>
]]></content:encoded>
			<wfw:commentRss>http://fdweb.com.br/implementando-controle-de-transacoes-com-transactionscope/feed/</wfw:commentRss>
		<feedburner:origLink>http://fdweb.com.br/implementando-controle-de-transacoes-com-transactionscope/</feedburner:origLink></item>
		<item>
		<title>Buscando o preview de um arquivo EPS em C# com ASP.NET</title>
		<link>http://feeds.feedburner.com/~r/fdweb/~3/313931576/</link>
		<comments>http://fdweb.com.br/buscando-o-preview-de-um-arquivo-eps-em-csharp-com-aspnet/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 16:26:56 +0000</pubDate>
		<dc:creator>Daniel Nogueira</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://fdweb.com.br/?p=26</guid>
		<description><![CDATA[Dentro de um arquivo EPS (Encapsulated Postscript) podemos encontrar um preview da imagem  em TIFF. O TIFF encontrado no EPS &#233; bastante &#250;til para n&#227;o necessitamos de programas como o PhotoShop, CorelDraw, Illustrator ou outros para serem visualizados, como por exemplo gerar um thumbnail da imagem.
Neste artigo vou mostrar como buscar este TIFF para [...]]]></description>
			<content:encoded><![CDATA[<p>Dentro de um arquivo EPS (Encapsulated Postscript) podemos encontrar um preview da imagem  em TIFF. O TIFF encontrado no EPS &eacute; bastante &uacute;til para n&atilde;o necessitamos de programas como o PhotoShop, CorelDraw, Illustrator ou outros para serem visualizados, como por exemplo gerar um thumbnail da imagem.</p>
<p>Neste artigo vou mostrar como buscar este TIFF para podermos trabalhar com ele.</p>
<h2>Exemplo</h2>
<p>Este exemplo consiste em efetuar o upload de um arquivo EPS, e mostrar o preview do arquivo EPS na p&aacute;gina.</p>
<p>1 - Crie o arquivo Default.aspx que vai conter a interface do exemplo;</p>
<p>2 - Insira no arquivo um component FileUpload e o renomeie para FileUploadEps;</p>
<p>3 - E insira um componente Button e o renomeie para ButtonUploadEps;</p>
<p>Arquivo Default.aspx</p>
<blockquote><p>&lt;%@ Page Language=&#8221;C#&#8221; AutoEventWireup=&#8221;true&#8221;  CodeFile=&#8221;Default.aspx.cs&#8221; Inherits=&#8221;_Default&#8221; %&gt;</p>
<p>&lt;!DOCTYPE html PUBLIC &#8220;-//W3C//DTD XHTML 1.0 Transitional//EN&#8221; &#8220;<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&#8221;</a>&gt;</p>
<p>&lt;html xmlns=&#8221;<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml&#8221;</a> &gt;<br />
&lt;head runat=&#8221;server&#8221;&gt;<br />
&lt;title&gt;Preview de Arquivos EPS&lt;/title&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;form id=&#8221;form1&#8243; runat=&#8221;server&#8221;&gt;<br />
&lt;div&gt;<br />
&lt;asp:FileUpload ID=&#8221;FileUploadEps&#8221; runat=&#8221;server&#8221; Style=&#8221;position: relative&#8221; /&gt;<br />
&lt;asp:Button ID=&#8221;ButtonUploadEps&#8221; runat=&#8221;server&#8221; OnClick=&#8221;ButtonUploadEps_Click&#8221; Style=&#8221;position:relative&#8221; Text=&#8221;Upload EPS&#8221; /&gt;<br />
&lt;/div&gt;<br />
&lt;/form&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</p></blockquote>
<p>4 - Crie o arquivo Default.aspx.cs que vai conter o c&oacute;digo em C#;</p>
<p>5 - Use os seguintes namespace:</p>
<blockquote><p>using System;<br />
using System.Data;<br />
using System.Configuration;<br />
using System.Web;<br />
using System.Web.Security;<br />
using System.Web.UI;<br />
using System.Web.UI.WebControls;<br />
using System.Web.UI.WebControls.WebParts;</p>
<p>using System.Web.UI.HtmlControls;</p>
<p>using System.IO;<br />
using System.Drawing;<br />
using System.Drawing.Imaging;</p></blockquote>
<p>6 - Crie o evento de click do bot&atilde;o &#8220;ButtonUploadEps&#8221; e insira nele o seguinte c&oacute;digo:</p>
<blockquote><p>FileStream fileStreamEps = null;<br />
string strCaminhoEpsUpload = &#8220;&#8221;;</p>
<p>//* Verifica se o usu&aacute;rio selecionou algum arquivo<br />
if (FileUploadEps.PostedFile.FileName != &#8220;&#8221;)<br />
{</p>
<p>//* Monta o caminho da onde o arquivo vai ser salvo<br />
strCaminhoEpsUpload = MapPath(&#8221;.&#8221;) + &#8220;\\&#8221; + Path.GetFileName(FileUploadEps.PostedFile.FileName);</p>
<p>//* Executa o upload do arquivo<br />
FileUploadEps.PostedFile.SaveAs(strCaminhoEpsUpload);</p>
<p>//* Abre o arquivo e l&ecirc; o header<br />
fileStreamEps = File.Open(strCaminhoEpsUpload, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);</p>
<p>byte[] buf = new byte[32];</p>
<p>//* Passa para o buffer o header do arquivo<br />
fileStreamEps.Read(buf, 0, 32);</p>
<p>//* Converte para uint<br />
uint idArquivo = obtemU(buf, 0);</p>
<p>//* Verifica se o arquivo de entrada &eacute; um EPS<br />
if (idArquivo != 0xc6d3d0c5)<br />
{</p>
<p>return;</p>
<p>}</p>
<p>//* obtem o uint<br />
uint TIFOff = obtemU(buf, 20);</p>
<p>//* Verifica se foi encontrado no EPS a identifica&ccedil;&atilde;o de preview<br />
if (TIFOff == 0)<br />
{</p>
<p>return;</p>
<p>}</p>
<p>//* N&atilde;o posicionou no TifOffset<br />
if (fileStreamEps.Seek(TIFOff, SeekOrigin.Begin) != TIFOff)<br />
{<br />
return;<br />
}</p>
<p>//* obtem o uint<br />
uint TIFSize = obtemU(buf, 24);</p>
<p>//* Redimensiona o buffer<br />
byte[] msBuf = new Byte[TIFSize];</p>
<p>//* Passa o arquivo para a mem&oacute;ria<br />
MemoryStream memoryStreamEps = new MemoryStream(msBuf);<br />
fileStreamEps.Read(msBuf, 0, (int)TIFSize);</p>
<p>//* Cria um novo bitmap apartir do conteudo da memoria<br />
Bitmap bitMapEps = new Bitmap(memoryStreamEps);</p>
<p>//* Mostra a imagem na tela<br />
bitMapEps.Save(Response.OutputStream, ImageFormat.Jpeg);<br />
bitMapEps.Dispose();<br />
}</p></blockquote>
<p>7 - Crie uma fun&ccedil;&atilde;o para obter o uint:</p>
<blockquote><p>private static uint obtemU(byte[] buf, int pos)<br />
{<br />
return (uint)(buf[pos] + 0&#215;100 * buf[pos + 1] + 0&#215;10000 * buf[pos + 2] + 0&#215;1000000 * buf[pos + 3]);<br />
}</p></blockquote>
<p>Vale lembrar que n&atilde;o s&atilde;o todos os EPS que contem um arquivo de preview. Na hora de salvar a imagem em EPS o usu&aacute;rio tem a escolha, se deseja salvar o preview, e em qual qualidade ser&aacute; gerado o preview.</p>
<h2>Download do Exemplo</h2>
<p>Clique <a href="http://fdweb.com.br/downloads/EpsPreviewCSharpAspNet.rar">aqui</a> para efetuar o download  do projeto de exemplo. O projeto foi criado no Visual Studio 2005.</p><p>Confira ofertas de: <a href="http://centenaro.org/submarino/?pal=DVD" rel="external" target="_Blank">DVD</a>, <a href="http://centenaro.org/submarino/?pal=filmes" rel="external" target="_Blank">filmes</a>, <a href="http://centenaro.org/submarino/?pal=celular" rel="external" target="_Blank">celular</a>, <a href="http://centenaro.org/submarino/?pal=notebook" rel="external" target="_Blank">notebook</a>, <a href="http://centenaro.org/submarino/?pal=livros" rel="external" target="_Blank">livros</a>, <a href="http://centenaro.org/submarino/?pal=jogos" rel="external" target="_Blank">jogos</a>, <a href="http://centenaro.org/submarino/?pal=Wii" rel="external" target="_Blank">Wii</a>, <a href="http://centenaro.org/submarino/?pal=PS3" rel="external" target="_Blank">PS3</a>, <a href="http://centenaro.org/submarino/?pal=MP4" rel="external" target="_Blank">MP4</a></p><p>a</p>
<p><a href="http://fdweb.com.br/buscando-o-preview-de-um-arquivo-eps-em-csharp-com-aspnet/">Buscando o preview de um arquivo EPS em C# com ASP.NET</a></p>
]]></content:encoded>
			<wfw:commentRss>http://fdweb.com.br/buscando-o-preview-de-um-arquivo-eps-em-csharp-com-aspnet/feed/</wfw:commentRss>
		<feedburner:origLink>http://fdweb.com.br/buscando-o-preview-de-um-arquivo-eps-em-csharp-com-aspnet/</feedburner:origLink></item>
		<item>
		<title>Gerando arquivos PDF com PHP</title>
		<link>http://feeds.feedburner.com/~r/fdweb/~3/227401304/</link>
		<comments>http://fdweb.com.br/gerando-arquivos-pdf-com-php/#comments</comments>
		<pubDate>Fri, 01 Feb 2008 19:03:27 +0000</pubDate>
		<dc:creator>Fabio Centenaro</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Programação]]></category>

		<guid isPermaLink="false">http://fdweb.com.br/gerando-arquivos-pdf-com-php/</guid>
		<description><![CDATA[Introdu&#231;&#227;o
Os arquivos PDF se transformaram ao longo do tempo em um padr&#227;o para troca de documentos. Desde relat&#243;rios at&#233; contratos, este formato tem sido usado em larga escala devido a sua portabilidade - &#233; poss&#237;vel abrir arquivos deste tipo em qualquer sistema operacional - al&#233;m de, geralmente, ser um arquivo pequeno. Isso sem falar que [...]]]></description>
			<content:encoded><![CDATA[<h2>Introdu&ccedil;&atilde;o</h2>
<p>Os arquivos PDF se transformaram ao longo do tempo em um padr&atilde;o para troca de documentos. Desde relat&oacute;rios at&eacute; contratos, este formato tem sido usado em larga escala devido a sua portabilidade - &eacute; poss&iacute;vel abrir arquivos deste tipo em qualquer sistema operacional - al&eacute;m de, geralmente, ser um arquivo pequeno. Isso sem falar que um arquivo PDF n&atilde;o pode ser modificado, garantindo, desta forma, que o arquivo ir&aacute; sempre manter o mesmo conte&uacute;do. Eu arriscaria dizer, ainda, que passa uma apar&ecirc;ncia mais profissional enviar um arquivo em formato PDF, ao inv&eacute;s de outros formatos, como DOC, por exemplo.</p>
<p>Neste artigo iremos conhecer os fundamentos da cria&ccedil;&atilde;o de um arquivo PDF utilizando a linguagem PHP. Para tal, ser&aacute; usada a biblioteca <a href="http://www.phpclasses.org/browse/package/421.html" title="FPDF - PHP Classes" target="_blank">FPDF</a>, respons&aacute;vel pela cria&ccedil;&atilde;o do arquivo. O download pode ser feito <a href="http://www.fpdf.org/en/download.php" title="FPDF" target="_blank">aqui</a>.</p>
<h2>Conhecendo as principais fun&ccedil;&otilde;es</h2>
<p>Abaixo est&atilde;o relacionadas as principais fun&ccedil;&otilde;es que ser&atilde;o utilizadas para a cria&ccedil;&atilde;o do arquivo, com a respectiva descri&ccedil;&atilde;o.</p>
<p><strong>SetFont </strong>- Define a fonte que ser&aacute; usada para imprimir o texto. &Eacute; obrigat&oacute;rio setar ao menos uma vez a fonte que ser&aacute; utilizada no documento.</p>
<p><strong>SetTitle </strong>- Define o t&iacute;tulo do documento.</p>
<p><strong>SetSubject </strong>- Define o assunto do documento.</p>
<p><strong>SetX </strong>-  Define a abscissa da posi&ccedil;&atilde;o corrente. A grosso modo podemos dizer que informa a posi&ccedil;&atilde;o a partir da margem esquerda do documento.</p>
<p><strong>SetY </strong>- Explicando de uma forma simples, indica a linha (posi&ccedil;&atilde;o vertical).</p>
<p><strong>Cell </strong>- Imprime uma c&eacute;lula (&aacute;rea retangular) com bordas opcionais, cor de fundo e texto. O canto superior-esquerdo da c&eacute;lula corresponde &agrave; posi&ccedil;&atilde;o atual. O texto pode ser alinhado ou centralizado. Depois de chamada, a posi&ccedil;&atilde;o atual se move para a direita ou para a linha seguinte. &Eacute; poss&iacute;vel p&ocirc;r um link no texto. Se a quebra de p&aacute;gina autom&aacute;tica est&aacute; habilitada e a pilha for al&eacute;m do limite, uma quebra de p&aacute;gina &eacute; feita antes da impress&atilde;o.</p>
<p><strong>Ln </strong>- Faz uma quebra de linha. A abscissa corrente volta para a margem esquerda e a ordenada &eacute; somada ao valor passado como par&acirc;metro.</p>
<p><strong>MultiCell </strong>- Este m&eacute;todo permite imprimir um texto com quebras de linha. Podem ser autom&aacute;tica (assim que o texto alcan&ccedil;a a margem direita da c&eacute;lula) ou expl&iacute;cita (atrav&eacute;s do caracter n). Ser&atilde;o geradas tantas c&eacute;lulas quantas forem necess&aacute;rias, uma abaixo da outra.</p>
<p><strong>Image </strong>- Permite inserir uma imagem no documento. Os tipos permitidos s&atilde;o JPG e PNG.</p>
<p><strong>AddPage </strong>- Acrescenta uma p&aacute;gina ao documento.</p>
<p><strong>PageNo </strong>- Informa a p&aacute;gina atual.</p>
<p><strong>AliasNbPages </strong>- Define um apelido para a impress&atilde;o do n&uacute;mero total de p&aacute;ginas.</p>
<p><strong>Header </strong>e <strong>Footer </strong>- Estes m&eacute;todos inserem automaticamente o cabe&ccedil;alho e rodap&eacute; das p&aacute;ginas do documento. Por&eacute;m, para utiliz&aacute;-las, &eacute; necess&aacute;rio criar uma subclasse para sobrepor os m&eacute;todos originais.</p>
<p><strong>Output</strong> -   Envia o documento para o destino informado. Pode-se abrir o arquivo no navegador, fazer o download ou mesmo salvar o arquivo no disco.</p>
<h3>OBSERVA&Ccedil;&Atilde;O:</h3>
<p>Sempre que for necess&aacute;rio setar a posi&ccedil;&atilde;o X e Y, sete primeiro o Y e depois o X.</p>
<h2>Criando nosso primeiro documento</h2>
<p>Agora vamos ver como criar um arquivo simples, contendo algum texto e uma imagem.</p>
<blockquote><p> &lt;?</p>
<p>require_once(&#8221;fpdf/fpdf.php&#8221;);</p>
<p>$texto = &#8220;Os arquivos PDF se transformaram ao longo do tempo em um padr&atilde;o para troca de documentos. Desde relat&oacute;rios at&eacute; contratos, este formato<br />
tem sido usado em larga escala devido a sua portabilidade  - &eacute; poss&iacute;vel abrir arquivos deste tipo em qualquer sistema operacional - al&eacute;m de, geralmente, ser um arquivo pequeno.<br />
Isso sem falar que um arquivo PDF n&atilde;o pode ser modificado,  garantindo, desta forma, que o arquivo ir&aacute; sempre manter o  mesmo conte&uacute;do. Eu arriscaria dizer, ainda, que passa uma<br />
apar&ecirc;ncia mais profissional enviar um arquivo em formato PDF,  ao inv&eacute;s de outros formatos, como DOC, por exemplo.&#8221;;</p>
<p>//defininfo a fonte !<br />
define(&#8217;FPDF_FONTPATH&#8217;,'fpdf/font/&#8217;);</p>
<p>//instancia a classe<br />
//uso: FPDF(orientacao - retrato ou paisagem), unidade de medida, tamanho do papel)<br />
$pdf = new FPDF(&#8221;P&#8221;,&#8221;mm&#8221;,&#8221;A4&#8243;);</p>
<p>//define a fonte a ser usada<br />
//uso: SetFont(nome da fonte, estilo (branco = normal, b = negrito, i = italico, u = sublinhado), tamanho da fonte)<br />
$pdf-&gt;SetFont(&#8217;arial&#8217;,&#8221;,10);</p>
<p>//define o titulo<br />
$pdf-&gt;SetTitle(&#8221;Criando nosso primeiro arquivo PDF !&#8221;);</p>
<p>// seta a posicao vertical e horizontal<br />
$pdf-&gt;SetY(&#8221;-1&#8243;);</p>
<p>//assunto<br />
$pdf-&gt;SetSubject(&#8221;Cria&ccedil;&atilde;o de arquivos PDF com PHP!&#8221;);</p>
<p>//escreve o texto<br />
//uso: Cell(largura, altura, conteudo, borda, quebra de linha, alinhamento (L = esquerdo, R = direito, C = centralizado)<br />
$pdf-&gt;Cell(0,5,&#8221;Criando arquivos PDF com PHP&#8221;,0,0,&#8217;L');<br />
$pdf-&gt;Cell(0,5,&#8217;http://fdweb.com.br&#8217;,0,1,&#8217;R');<br />
$pdf-&gt;Cell(0,0,&#8221;,1,1,&#8217;L');<br />
$pdf-&gt;Ln(8);</p>
<p>//Seta a fonte do texto do documento<br />
$pdf-&gt;SetFont(&#8217;arial&#8217;,&#8221;,8);</p>
<p>// insere a imagem<br />
//uso: Image(caminho, posicao X,posicao Y,altura, largura)<br />
//$pdf-&gt;Image(&#8221;http://fdweb.com.br/downloads/logo.jpg&#8221;, $pdf-&gt;GetX(), $pdf-&gt;GetY(), 20, 20);<br />
$pdf-&gt;Image(&#8221;logo.jpg&#8221;,10,30);</p>
<p>//posiciona horizontalmente<br />
$pdf-&gt;SetY(&#8221;30&#8243;);<br />
$pdf-&gt;SetX(&#8221;50&#8243;);</p>
<p>//Insere o texto do documento<br />
//uso: MultiCell(largura, altura, conteudo, borda, quebra de linha, alinhamento (L = esquerdo, R = direito, C = centralizado, J = justificado)<br />
$pdf-&gt;MultiCell(0,5,$texto,0,&#8221;L&#8221;,0);</p>
<p>$pdf-&gt;Output(&#8221;arquivo pdf&#8221;,&#8221;I&#8221;);</p>
<p>?&gt;</p></blockquote>
<p>Este exemplo mostra como criar um arquivo simples, com texto e uma imagem.</p>
<h2>Implementando cabe&ccedil;alho e rodap&eacute;</h2>
<p>Para que todas as p&aacute;ginas possuam cabe&ccedil;alho e rodap&eacute; padr&atilde;o, temos que estender a classe FPDF e sobrepor os m&eacute;todos Header e Footer. Note que a partir desse momento, ao inv&eacute;s de chamarmos a classe FPDF para gerarmos os documentos iremos passar a chamar a nossa classe estendida. Observe:</p>
<blockquote><p>&lt;?</p>
<p>require_once(&#8221;fpdf/fpdf.php&#8221;);</p>
<p>class PDF extends FPDF<br />
{</p>
<p>// sobrep&otilde;e o m&eacute;todo header<br />
function Header()<br />
{<br />
//escreve o texto<br />
//uso: Cell(largura, altura, conteudo, borda, quebra de linha, alinhamento (L = esquerdo, R = direito, C = centralizado)<br />
//$this-&gt;SetY(-1);<br />
$this-&gt;SetFont(&#8217;arial&#8217;,&#8221;,8);<br />
$this-&gt;Cell(0,5,&#8221;Criando arquivos PDF com PHP&#8221;,0,0,&#8217;L');<br />
$this-&gt;Cell(0,5,&#8217;http://fdweb.com.br&#8217;,0,1,&#8217;R');<br />
$this-&gt;Cell(0,0,&#8221;,1,1,&#8217;L');<br />
$this-&gt;Ln(8);</p>
<p>}<br />
// sobrep&otilde;e o m&eacute;todo footer<br />
function Footer()<br />
{<br />
//Vai para 1.5 cm da parte inferior</p>
<p>$this-&gt;SetY(-15);</p>
<p>//Seleciona a fonte Arial it&aacute;lico 8</p>
<p>$this-&gt;SetFont(&#8217;Arial&#8217;,'I&#8217;,8);</p>
<p>//Imprime o n&uacute;mero da p&aacute;gina corrente e o total de p&aacute;ginas</p>
<p>$this-&gt;Cell(0,10,&#8217;P&aacute;gina &#8216;.$this-&gt;PageNo().&#8217; de {total}&#8217;,0,0,&#8217;C');<br />
}<br />
}</p>
<p>$texto = &#8220;Os arquivos PDF se transformaram ao longo do tempo em um padr&atilde;o para troca de documentos. Desde relat&oacute;rios at&eacute; contratos, este formato<br />
tem sido usado em larga escala devido a sua portabilidade  - &eacute; poss&iacute;vel abrir arquivos deste tipo em qualquer sistema operacional - al&eacute;m de, geralmente, ser um arquivo pequeno.<br />
Isso sem falar que um arquivo PDF n&atilde;o pode ser modificado,  garantindo, desta forma, que o arquivo ir&aacute; sempre manter o  mesmo conte&uacute;do. Eu arriscaria dizer, ainda, que passa uma<br />
apar&ecirc;ncia mais profissional enviar um arquivo em formato PDF,  ao inv&eacute;s de outros formatos, como DOC, por exemplo.&#8221;;</p>
<p>//defininfo a fonte !<br />
define(&#8217;FPDF_FONTPATH&#8217;,'fpdf/font/&#8217;);</p>
<p>//instancia a classe<br />
//uso: PDF(orientacao - retrato ou paisagem), unidade de medida, tamanho do papel)<br />
$pdf = new PDF(&#8221;P&#8221;,&#8221;mm&#8221;,&#8221;A4&#8243;);</p>
<p>$pdf-&gt;AliasNbPages( &#8216;{total}&#8217; );</p>
<p>$pdf-&gt;AddPage();</p>
<p>//define a fonte a ser usada<br />
//uso: SetFont(nome da fonte, estilo (branco = normal, b = negrito, i = italico, u = sublinhado), tamanho da fonte)<br />
$pdf-&gt;SetFont(&#8217;arial&#8217;,&#8221;,10);</p>
<p>//define o titulo<br />
$pdf-&gt;SetTitle(&#8221;Criando nosso primeiro arquivo PDF !&#8221;);</p>
<p>//assunto<br />
$pdf-&gt;SetSubject(&#8221;Cria&ccedil;&atilde;o de arquivos PDF com PHP!&#8221;);</p>
<p>//Seta a fonte do texto do documento<br />
$pdf-&gt;SetFont(&#8217;arial&#8217;,&#8221;,8);</p>
<p>// insere a imagem<br />
//uso: Image(caminho, posicao X,posicao Y,altura, largura)<br />
//$pdf-&gt;Image(&#8221;http://fdweb.com.br/downloads/logo.jpg&#8221;,$pdf-&gt;GetX(),$pdf-&gt;GetY(),20,20);<br />
$pdf-&gt;Image(&#8221;logo.jpg&#8221;,10,30);</p>
<p>//posiciona horizontalmente<br />
$pdf-&gt;SetY(&#8221;30&#8243;);<br />
$pdf-&gt;SetX(&#8221;50&#8243;);</p>
<p>//Insere o texto do documento<br />
//uso: MultiCell(largura, altura, conteudo, borda, quebra de linha, alinhamento (L = esquerdo, R = direito, C = centralizado, J = justificado)<br />
$pdf-&gt;MultiCell(0,5,$texto,0,&#8221;L&#8221;,0);</p>
<p>$pdf-&gt;Output();</p>
<p>?&gt;</p></blockquote>
<p>Podemos notar que o c&oacute;digo sofreu tr&ecirc;s altera&ccedil;&otilde;es:</p>
<p>Declaramos  $pdf = new PDF() ao inv&eacute;s de $pdf = new FPDF().</p>
<p>Acrescentamos as linhas : $pdf-&gt;AliasNbPages( &#8216;{total}&#8217; ); e $pdf-&gt;AddPage();</p>
<p>O c&oacute;digo que montava o cabe&ccedil;alho foi para dentro da fun&ccedil;&atilde;o Header, saindo do corpo do documento.</p>
<h2>Considera&ccedil;&otilde;es Finais</h2>
<p>Antes de finalizar &eacute; bom ressaltar alguns itens:</p>
<p>- N&atilde;o esquecer de informar a fonte antes de imprimir qualquer texto. Caso contr&aacute;rio a p&aacute;gina ou o texto anterior ao primeiro SetFont n&atilde;o aparecer&aacute; no documento;</p>
<p>- Setar sempre a posi&ccedil;&atilde;o Y primeiro. Primeiro Y depois X, e n&atilde;o o contr&aacute;rio.</p>
<p>- Se for necess&aacute;rio colocar algum texto no final de cada p&aacute;gina, como por exemplo a soma total de um campo, basta usar a fun&ccedil;&atilde;o GetY &eacute; para determinar a posi&ccedil;&atilde;o da impress&atilde;o dentro do documento. Isso pode ser verificado dentro de um loop <em>for </em>ou <em>while</em>. Por exemplo, o c&oacute;digo abaixo imprime o n&uacute;mero de linha de 1 a 150. Ao chegar no final da p&aacute;gina (ou seja, a 27cm) ele escreve a palavra <strong>total</strong> e continua a impress&atilde;o da linha seguinte na pr&oacute;xima p&aacute;gina:</p>
<blockquote><p> for($i=1;$i&lt;=150;$i++)<br />
{</p>
<p>if ($pdf-&gt;GetY() &gt;= 270)<br />
{<br />
$pdf-&gt;Cell(0,5,&#8221;total: &#8220;,0,0);<br />
$pdf-&gt;AddPage();<br />
$pdf-&gt;Cell(0,5,&#8221;Line $i - &#8221; . $pdf-&gt;GetY() ,0,1);<br />
}<br />
else<br />
{<br />
$pdf-&gt;Cell(0,5,&#8221;Line $i - &#8221; . $pdf-&gt;GetY() ,0,1);<br />
}</p>
<p>}</p></blockquote>
<h2>Concluindo</h2>
<p>Vimos que criar arquivos PDF pode ser uma tarefa bem simples. Claro que documentos ou relat&oacute;rios mais bem elaborados e/ou complexos podem dar um pouco mais de trabalho, mas o resultado final fica com aspecto mais profissional e elegante.</p><p>Confira ofertas de: <a href="http://centenaro.org/submarino/?pal=DVD" rel="external" target="_Blank">DVD</a>, <a href="http://centenaro.org/submarino/?pal=filmes" rel="external" target="_Blank">filmes</a>, <a href="http://centenaro.org/submarino/?pal=celular" rel="external" target="_Blank">celular</a>, <a href="http://centenaro.org/submarino/?pal=notebook" rel="external" target="_Blank">notebook</a>, <a href="http://centenaro.org/submarino/?pal=livros" rel="external" target="_Blank">livros</a>, <a href="http://centenaro.org/submarino/?pal=jogos" rel="external" target="_Blank">jogos</a>, <a href="http://centenaro.org/submarino/?pal=Wii" rel="external" target="_Blank">Wii</a>, <a href="http://centenaro.org/submarino/?pal=PS3" rel="external" target="_Blank">PS3</a>, <a href="http://centenaro.org/submarino/?pal=MP4" rel="external" target="_Blank">MP4</a></p><p>a</p>
<p><a href="http://fdweb.com.br/gerando-arquivos-pdf-com-php/">Gerando arquivos PDF com PHP</a></p>
]]></content:encoded>
			<wfw:commentRss>http://fdweb.com.br/gerando-arquivos-pdf-com-php/feed/</wfw:commentRss>
		<feedburner:origLink>http://fdweb.com.br/gerando-arquivos-pdf-com-php/</feedburner:origLink></item>
		<item>
		<title>Trabalhando com a taskbar do windows no Visual Basic</title>
		<link>http://feeds.feedburner.com/~r/fdweb/~3/198604237/</link>
		<comments>http://fdweb.com.br/trabalhando-com-a-taskbar-do-windows-no-visual-basic/#comments</comments>
		<pubDate>Tue, 11 Dec 2007 13:14:28 +0000</pubDate>
		<dc:creator>Daniel Nogueira</dc:creator>
		
		<category><![CDATA[Programação]]></category>

		<category><![CDATA[Visual Basic]]></category>

		<category><![CDATA[Bandeija de tarefas]]></category>

		<category><![CDATA[Taskbar]]></category>

		<guid isPermaLink="false">http://fdweb.com.br/trabalhando-com-a-taskbar-do-windows-no-visual-basic/</guid>
		<description><![CDATA[Trabalhar com os objetos da taskbar ( bandeja do sistema ) do windows que se encontra ao lado do rel&#243;gio &#233; bem &#250;til para nossas aplica&#231;&#245;es. Permitimos ao usu&#225;rio deixar a nossa aplica&#231;&#227;o rodando em &#8220;segundo plano&#8221; n&#227;o mantendo-a no desktop, deixando a &#225;rea de trabalho limpa. Assim quando a aplica&#231;&#227;o estiver rodando um processo [...]]]></description>
			<content:encoded><![CDATA[<p>Trabalhar com os objetos da taskbar ( bandeja do sistema ) do windows que se encontra ao lado do rel&oacute;gio &eacute; bem &uacute;til para nossas aplica&ccedil;&otilde;es. Permitimos ao usu&aacute;rio deixar a nossa aplica&ccedil;&atilde;o rodando em &#8220;segundo plano&#8221; n&atilde;o mantendo-a no desktop, deixando a &aacute;rea de trabalho limpa. Assim quando a aplica&ccedil;&atilde;o estiver rodando um processo demorado, damos a liberdade para o usu&aacute;rio executar outras tarefas, sem manter o desktop cheio.</p>
<p>Para inserir, modificar, e remover objetos da taskbar, usaremos uma API do windows que se encontra em shell32 e o m&eacute;todo a ser chamado &eacute; o &#8220;Shell_NotifyIconA&#8221; .</p>
<h2>Exemplo</h2>
<p>Neste artigo, vamos criar um simples exemplo, mostrando como trabalhar com est&aacute; API em nossas aplica&ccedil;&otilde;es criadas em Visual Basic em sua vers&atilde;o 6.</p>
<p>Primeiro vamos criar a interface do exemplo:</p>
<p>1. Crie um novo projeto Standard EXE.</p>
<p>2. Crie a seguinte estrutura de menus, no formul&aacute;rio:</p>
<p>mnuIconeTaskbar</p>
<p>- mnuIconeTaskbarAlterar &#8220;Alterar &Iacute;cone&#8221;</p>
<p>- mnuIconeTaskbarMostrarFormulario &#8220;Mostrar Formul&aacute;rio&#8221;</p>
<p>- mnuIconeTaskbarSair &#8220;Sair&#8221;</p>
<p>3. Vamos precisar usar o componente CommonDialog, para adicionar este componente ao seu projeto entre no menu Project-&gt;Components.. e marque na lista o item &#8220;Microsoft Common Dialog Control 6.0&#8243;, se n&atilde;o constar na lista este item, voc&ecirc; tem que instalar o Service Pack 6 do Visual Basic que pode ser encontrado para download aqui . Insira este componente no formul&aacute;rio e renomeie para &#8220;cmmdlgArquivo&#8221;.</p>
<h2>Code</h2>
<p>Agora com a nossa interface pronta, vamos a parte de c&oacute;digo. Ap&oacute;s o Option Explicit declare o tipo typeIconeTaskbar, que ser&aacute; usado para guardarmos os dados que precisamos para criar o &iacute;cone na taskbar:</p>
<blockquote><p> Private Type typeIconeTaskbar<br />
cbSize As Long<br />
hWnd As Long<br />
uId As Long<br />
uFlags As Long<br />
uCallBackMessage As Long<br />
hIcon As Long<br />
szTip As String * 64<br />
End Type</p></blockquote>
<p>Declare as constantes que usaremos no decorrer do nosso exemplo:</p>
<blockquote><p> Private Const cntIconeTaskbarInsere = &amp;H0<br />
Private Const cntIconeTaskbarAltera = &amp;H1<br />
Private Const cntIconeTaskbarRemove = &amp;H2<br />
Private Const cntIconeTaskbarMensagem = &amp;H1<br />
Private Const cntIconeTaskbarIcone = &amp;H2<br />
Private Const cntIconeTaskbarTipo = &amp;H4</p>
<p>Private Const cntMouseMove = &amp;H200<br />
Private Const cntMouseEsquerdoDuploClick = &amp;H203<br />
Private Const cntMouseEsquerdoDown = &amp;H201<br />
Private Const cntMouseEsquerdoUp = &amp;H202<br />
Private Const cntMouseDireitoDuploClick = &amp;H206<br />
Private Const cntMouseDireitoDown = &amp;H204<br />
Private Const cntMouseDireitoUP = &amp;H205</p></blockquote>
<p>As constantes que come&ccedil;am com cntIconeTaskbar, s&atilde;o relativas a o objeto na taskbar. E as que come&ccedil;am com cntMouse, s&atilde;o relativas aos eventos do mouse.</p>
<p>Declare a API para podermos interagir com a taskbar:</p>
<blockquote><p> Private Declare Function apiIconeTaskbar Lib &#8220;shell32&#8243; _<br />
Alias &#8220;Shell_NotifyIconA&#8221; (ByVal dwMessage As Long, objIconeTaskbar As typeIconeTaskbar) As Boolean</p></blockquote>
<p>Ainda na parte publica do formul&aacute;rio, declare a seguinte vari&aacute;vel:</p>
<blockquote><p> Dim objTaskbar As typeIconeTaskbar</p></blockquote>
<p>Agora vamos criar duas subs, uma para esconder o formul&aacute;rio e a outra para mostra-lo:</p>
<blockquote><p> Sub subEscondeFormulario()</p>
<p>Me.Hide</p>
<p>objTaskbar.cbSize = Len(objTaskbar)<br />
objTaskbar.hWnd = Me.hWnd<br />
objTaskbar.uId = vbNull<br />
objTaskbar.uFlags = cntIconeTaskbarIcone Or cntIconeTaskbarTipo Or cntIconeTaskbarMensagem<br />
objTaskbar.uCallBackMessage = cntMouseMove<br />
objTaskbar.hIcon = Me.Icon<br />
objTaskbar.szTip = Me.Caption &amp; vbNullChar</p>
<p>apiIconeTaskbar cntIconeTaskbarInsere, objTaskbar</p>
<p>End Sub</p></blockquote>
<p>Na sub subEscondeFormulario ao ser chamada , executamos um hide no nosso formul&aacute;rio e definimos as propriedades do nosso objeto, para inseri-lo no taskbar. No objeto, definimos o comprimento na propriedade cbSize. Na propriedade hWnd definimos o identificador do nosso formul&aacute;rio. Definimos como nulo o uId. Definimos quais ser&atilde;o os flags na propriedade uFlags. Definimos qual o evento que ser&aacute; gerado por este objeto na propriedade uCallBackMessage. Na propriedade hIcon definimos o &iacute;cone que ser&aacute; apresentado na taskbar, que no caso ser&aacute; o &iacute;cone que estiver definido no formul&aacute;rio e por ultimo a propriedade szTip, onde fica armazenado o caption do objeto na taskbar.</p>
<p>Ap&oacute;s definirmos as propriedades do objeto, executamos a API para inserir o objeto na taskbar. O par&acirc;metro para a API saber que est&aacute; inserindo um objeto, est&aacute; apontado por cntIconeTaskbarInsere.</p>
<p>Agora crie a subMostraFormul&aacute;rio, que altera o WindowState do formul&aacute;rio para vbNormal, mostra o formul&aacute;rio, seta o focus nele e atualiza o formul&aacute;rio. Ap&oacute;s, executa a API para remover o objeto da taskbar:</p>
<blockquote><p> Sub subMostraFormulario()</p>
<p>Me.WindowState = vbNormal</p>
<p>Me.Show</p>
<p>Me.SetFocus</p>
<p>Me.Refresh</p>
<p>apiIconeTaskbar cntIconeTaskbarRemove, objTaskbar</p>
<p>End Sub</p></blockquote>
<p>No evento Load do formul&aacute;rio, executa a subEscondeFormulario:</p>
<blockquote><p> Private Sub Form_Load()</p>
<p>subEscondeFormulario</p>
<p>End Sub</p></blockquote>
<p>No evento Resize do formul&aacute;rio, verifica se o formul&aacute;rio foi minimizado, se sim, executa a subEscondeFormulario:</p>
<blockquote><p> Private Sub Form_Resize()</p>
<p>If Me.WindowState = vbMinimized Then _<br />
subEscondeFormulario</p>
<p>End Sub</p></blockquote>
<p>Agora vamos criar o evento MouseMove do formul&aacute;rio. Nele verificamos qual o evento foi executado no nosso objeto que se encontra na taskbar. Caso for um duplo clique com o bot&atilde;o esquerdo, mostramos o formul&aacute;rio. Caso clicarmos com o bot&atilde;o direito do mouse no objeto, abrir&aacute; um menu para selecionarmos uma das op&ccedil;&otilde;es:</p>
<blockquote><p> Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)</p>
<p>Dim lngEvento As Long<br />
Dim sFilter As String</p>
<p>lngEvento = X / Screen.TwipsPerPixelX</p>
<p>Select Case lngEvento</p>
<p>Case cntMouseEsquerdoDown</p>
<p>Case cntMouseEsquerdoUp</p>
<p>Case cntMouseEsquerdoDuploClick</p>
<p>subMostraFormulario</p>
<p>Case cntMouseDireitoDown</p>
<p>PopupMenu mnuIconeTaskbar</p>
<p>Case cntMouseDireitoUP</p>
<p>Case cntMouseDireitoDuploClick</p>
<p>End Select</p>
<p>End Sub</p></blockquote>
<p>Agora vamos criar os eventos do nosso menu. No mnuIconeTaskbarAlterar vamos vai abrir uma caixa de dialogo onde podemos selecionar o novo &iacute;cone do nosso formul&aacute;rio. Alterando tamb&eacute;m o &iacute;cone que se encontra na taskbar:</p>
<blockquote><p> Private Sub mnuIconeTaskbarAlterar_Click()</p>
<p>cmmdlgArquivo.DialogTitle = &#8220;Selecione um &iacute;cone&#8221;</p>
<p>cmmdlgArquivo.Filter = &#8220;Icone (*.ico)|*.ico|Todos os arquivos (*.*)|*.*&#8221;<br />
cmmdlgArquivo.ShowOpen</p>
<p>If cmmdlgArquivo.FileName &lt;&gt; &#8220;&#8221; Then</p>
<p>Me.Icon = LoadPicture(cmmdlgArquivo.FileName)<br />
objTaskbar.hIcon = Me.Icon<br />
apiIconeTaskbar cntIconeTaskbarAltera, objTaskbar</p>
<p>End If</p>
<p>End Sub</p></blockquote>
<p>No mnuIconeTaskbarMostrarFormulario, vamos apenas chamar a subMostraFormulario:</p>
<blockquote><p> Private Sub mnuIconeTaskbarMostrarFormulario_Click()</p>
<p>subMostraFormulario</p>
<p>End Sub</p></blockquote>
<p>E finalizando o nosso exemplo, vamos criar o evento do mnuIconeTaskbarSair:</p>
<blockquote><p> Private Sub mnuIconeTaskbarSair_Click()</p>
<p>subMostraFormulario</p>
<p>Unload Me</p>
<p>End Sub</p></blockquote>
<h2>Debug</h2>
<p>Pronto! Agora &eacute; s&oacute; testar, execute o projeto.<br />
Ao iniciar o formul&aacute;rio, o mesmo ser&aacute; escondido, e um &iacute;cone ser&aacute; criado na sua taskbar. Ao dar um duplo click no &iacute;cone com o bot&atilde;o esquerdo o formul&aacute;rio ser&aacute; mostrado, e o &iacute;cone removido da bandeja. Ao minimizar a aplica&ccedil;&atilde;o, o formul&aacute;rio &eacute; escondido novamente, e inserido o &iacute;cone na taskbar. Ao clicar no &iacute;cone com o bot&atilde;o direito do mouse, teremos tr&ecirc;s op&ccedil;&otilde;es: Sair, para fecharmos a aplica&ccedil;&atilde;o e remover o &iacute;cone da bandeja. Mostrar Formul&aacute;rio, para chamar o formul&aacute;rio novamente e remover o &iacute;cone da bandeja. E a ultima op&ccedil;&atilde;o que &eacute; Alterar &Iacute;cone, para alterarmos o &iacute;cone do formul&aacute;rio e do objeto da taskbar.</p>
<h2>Download do Exemplo</h2>
<p>O link para download do exemplo:<br />
<a href="http://www.fdweb.com.br/downloads/TaskbarVB.zip"> http://www.fdweb.com.br/downloads/TaskbarVB.zip</a></p><p>Confira ofertas de: <a href="http://centenaro.org/submarino/?pal=DVD" rel="external" target="_Blank">DVD</a>, <a href="http://centenaro.org/submarino/?pal=filmes" rel="external" target="_Blank">filmes</a>, <a href="http://centenaro.org/submarino/?pal=celular" rel="external" target="_Blank">celular</a>, <a href="http://centenaro.org/submarino/?pal=notebook" rel="external" target="_Blank">notebook</a>, <a href="http://centenaro.org/submarino/?pal=livros" rel="external" target="_Blank">livros</a>, <a href="http://centenaro.org/submarino/?pal=jogos" rel="external" target="_Blank">jogos</a>, <a href="http://centenaro.org/submarino/?pal=Wii" rel="external" target="_Blank">Wii</a>, <a href="http://centenaro.org/submarino/?pal=PS3" rel="external" target="_Blank">PS3</a>, <a href="http://centenaro.org/submarino/?pal=MP4" rel="external" target="_Blank">MP4</a></p><p>a</p>
<p><a href="http://fdweb.com.br/trabalhando-com-a-taskbar-do-windows-no-visual-basic/">Trabalhando com a taskbar do windows no Visual Basic</a></p>
]]></content:encoded>
			<wfw:commentRss>http://fdweb.com.br/trabalhando-com-a-taskbar-do-windows-no-visual-basic/feed/</wfw:commentRss>
		<feedburner:origLink>http://fdweb.com.br/trabalhando-com-a-taskbar-do-windows-no-visual-basic/</feedburner:origLink></item>
		<item>
		<title>Arquivo Torrent: O que é e como funciona</title>
		<link>http://feeds.feedburner.com/~r/fdweb/~3/190404638/</link>
		<comments>http://fdweb.com.br/arquivo-torrent-o-que-e-como-funciona/#comments</comments>
		<pubDate>Sun, 25 Nov 2007 22:16:42 +0000</pubDate>
		<dc:creator>Fabio Centenaro</dc:creator>
		
		<category><![CDATA[Geral]]></category>

		<guid isPermaLink="false">http://fdweb.com.br/arquivo-torrent-o-que-e-como-funciona/</guid>
		<description><![CDATA[O Torrent &#233; uma tecnologia que permite o compartilhamento de qualquer tipo de arquivo pela internet, sendo muito usado para a distribui&#231;&#227;o de v&#237;deos, m&#250;sicas e programas. Sua forma de trabalho &#233; muito eficaz e evita, por exemplo, que determinados usu&#225;rios s&#243; fa&#231;am download, mas n&#227;o compartilhem arquivos (pelos menos teoricamente). Isso porque a taxa [...]]]></description>
			<content:encoded><![CDATA[<p>O Torrent &#233; uma tecnologia que permite o compartilhamento de qualquer tipo de arquivo pela internet, sendo muito usado para a distribui&#231;&#227;o de v&#237;deos, m&#250;sicas e programas. Sua forma de trabalho &#233; muito eficaz e evita, por exemplo, que determinados usu&#225;rios s&#243; fa&#231;am download, mas n&#227;o compartilhem arquivos (pelos menos teoricamente). Isso porque a taxa de download &#233; equivalente &#224; taxa de upload, ou seja, somente compartilhando &#233; que voc&#234; consegue baixar arquivos. Por esta raz&#227;o, quando voc&#234; est&#225; iniciando um determinado download, a velocidade utilizada &#233; lenta e vai aumentando de acordo com o que j&#225; foi baixado do arquivo. Quanto mais voc&#234; tiver de um arquivo, mais usu&#225;rios se conectar&#227;o ao seu computador e pela regra, a taxa de velocidade do seu download aumenta.</p>
<h2>Como o BitTorrent funciona</h2>
<p>Para que voc&#234; possa fazer download (e upload) pelo BitTorrent, &#233; necess&#225;rio que cada item compartilhado esteja associado a um arquivo denominado <b>torrent</b>, cuja extens&#227;o &#233; .torrent (por exemplo, infowester.torrent). Trata-se de um arquivo pequeno, mas que cont&#233;m as informa&#231;&#245;es necess&#225;rias para o compartilhamento, como o local onde o arquivo est&#225; e a seq&#252;&#234;ncia que verifica a integridade deste. Esse arquivo pode estar dispon&#237;vel em um site e, quando acessado, inicia o download do arquivo compartilhado (desde que o BitTorrent esteja instalado). Isso significa que voc&#234; precisa achar um torrent do arquivo que voc&#234; deseja baixar. Para encontrar torrents voc&#234; pode usar sites voltados a este fim. H&#225; v&#225;rios na internet, basta digitar a palavra &quot;torrent&quot; em mecanismos de busca para localiz&#225;-los. </p>
<p>Para entender o compartilhamento de arquivos do Torrent, &#233; necess&#225;rio conhecer alguns termos:</p>
<p><b>Seed (ou seeding):</b> &#233; a denomina&#231;&#227;o dada ao computador que possui um arquivo completo compartilhado, como o computador que primeiramente disponibilizou o arquivo e os outros que o baixaram por inteiro;</p>
<p><b>Peer:</b> nome dado a cada computador que compartilha arquivos. Quando voc&#234; est&#225; baixando algo pelo Torrent, seu computador &#233; um peer, ou seja, um ponto ou um n&#243; da rede;</p>
<p><b>Leech (ou leeching):</b> &#233; a denomina&#231;&#227;o dada ao momento em que um computador faz download;</p>
<p><b>Tracker:</b> denomina&#231;&#227;o dada ao servidor que &#233; respons&#225;vel por organizar os arquivos dispon&#237;veis e direcionar os downloads;</p>
<p><b>Swarm:</b> nome dado ao conjunto de computadores que est&#227;o compartilhando o mesmo arquivo. Se, por exemplo, o arquivo infowester.pdf est&#225; sendo compartilhado por 2 seeds e por 8 peers, o swarm do arquivo cont&#233;m 10 computadores (2 seeds + 8 peers).</p>
<p>O tracker &#233; um dos principais respons&#225;veis pelo funcionamento da rede do Torrent, pois ele praticamente gerencia a distribui&#231;&#227;o de arquivos porque possui informa&#231;&#245;es sobre onde est&#227;o os computadores com os arquivos compartilhados num determinado momento.</p>
<p>Quando voc&#234; inicia um download, o tracker &#233; consultado para que a lista de computadores que possui o arquivo em quest&#227;o seja informada. Enquanto o download vai sendo feito, seu computador se comunica periodicamente com o tracker para informar o quanto de download j&#225; foi feito e para saber o quanto falta. &#201; importante ao tracker saber o quanto j&#225; foi baixado ao seu computador porque assim ele pode indicar sua m&#225;quina &#224; outra que esteja precisando do &quot;peda&#231;o&quot; do arquivo que voc&#234; j&#225; tem. Assim, quanto mais computadores estiverem compartilhando aquele arquivo, mais r&#225;pido ser&#225; o download, pois h&#225; mais op&#231;&#245;es de fontes.</p>
<p>Um fato interessante, &#233; que se por alguma raz&#227;o o tracker parar de funcionar (quando isso ocorre, geralmente &#233; tempor&#225;rio) o swarm continua compartilhando o arquivo que lhe cabe, afinal, cada computador sabe de onde fazer o download. No entanto, nenhuma outra m&#225;quina poder&#225; fazer parte do swarm, pois n&#227;o h&#225; tracker que possa direcion&#225;-la.</p>
<h2>Clientes Torrent</h2>
<p>Para poder baixar um arquivo .torrent &#233; necess&#225;rio utilizar um programa que entenda o arquivo .torrent e fa&#231;a o download dos arquivos contidos dentro dele. Este programa chamamos de cliente torrent (ou torrent client). Existem diversos programas espalhados pela internet. Um dos melhores e mais usados &#233; o uTorrent, que pode ser baixado <a title="uTorrent" href="http://www.utorrent.com/download.php" target="_blank">aqui</a>.</p>
<p>O programa &#233; bem f&#225;cil de usar, possuindo uma interface bastante intuitiva. Fora o fato de ter suporte &#224; l&#237;ngua tupiniquim.</p>
<h2>Conclus&#227;o</h2>
<p>Agora que j&#225; temos uma boa id&#233;ia do que &#233; e de como funcionam os arquivos Torrent, &#233; s&#243; sair por a&#237; baixando seus filmes e m&#250;sicas favoritas! O c&#233;u &#233; o limite ( e a banda da internet tamb&#233;m!).</p><p>Confira ofertas de: <a href="http://centenaro.org/submarino/?pal=DVD" rel="external" target="_Blank">DVD</a>, <a href="http://centenaro.org/submarino/?pal=filmes" rel="external" target="_Blank">filmes</a>, <a href="http://centenaro.org/submarino/?pal=celular" rel="external" target="_Blank">celular</a>, <a href="http://centenaro.org/submarino/?pal=notebook" rel="external" target="_Blank">notebook</a>, <a href="http://centenaro.org/submarino/?pal=livros" rel="external" target="_Blank">livros</a>, <a href="http://centenaro.org/submarino/?pal=jogos" rel="external" target="_Blank">jogos</a>, <a href="http://centenaro.org/submarino/?pal=Wii" rel="external" target="_Blank">Wii</a>, <a href="http://centenaro.org/submarino/?pal=PS3" rel="external" target="_Blank">PS3</a>, <a href="http://centenaro.org/submarino/?pal=MP4" rel="external" target="_Blank">MP4</a></p><p>a</p>
<p><a href="http://fdweb.com.br/arquivo-torrent-o-que-e-como-funciona/">Arquivo Torrent: O que &eacute; e como funciona</a></p>
]]></content:encoded>
			<wfw:commentRss>http://fdweb.com.br/arquivo-torrent-o-que-e-como-funciona/feed/</wfw:commentRss>
		<feedburner:origLink>http://fdweb.com.br/arquivo-torrent-o-que-e-como-funciona/</feedburner:origLink></item>
		<item>
		<title>Download sem custo do Visual Studio 2005 Professional Edition, Visual SourceSafe 2005, SQL Server 2005 Developer Edition e o Expression Web</title>
		<link>http://feeds.feedburner.com/~r/fdweb/~3/189300836/</link>
		<comments>http://fdweb.com.br/download-sem-custo-do-visual-studio-2005-professional-edition-visual-sourcesafe-2005-sql-server-2005-developer-edition-e-o-expression-web/#comments</comments>
		<pubDate>Fri, 23 Nov 2007 02:01:50 +0000</pubDate>
		<dc:creator>Daniel Nogueira</dc:creator>
		
		<category><![CDATA[Geral]]></category>

		<category><![CDATA[Download]]></category>

		<category><![CDATA[Expression Web]]></category>

		<category><![CDATA[Imagine Cup]]></category>

		<category><![CDATA[SQL Server 2005 Developer Edition]]></category>

		<category><![CDATA[Visual SourceSafe 2005]]></category>

		<category><![CDATA[Visual Sudio 2005 Professional Edition]]></category>

		<guid isPermaLink="false">http://fdweb.com.br/download-sem-custo-do-visual-sudio-2005-professional-edition-visual-sourcesafe-2005-sql-server-2005-developer-edition-e-o-expression-web/</guid>
		<description><![CDATA[A Microsoft fez o que ningu&#233;m esperava, disponibilizou gratuitamente quatro dos seus grandes produtos para quem se inscrever no Imagine Cup 2008. O Imagine Cup, &#233; uma competi&#231;&#227;o entre estudantes de todo o mundo. Dividida entre tr&#234;s categorias principais, a competi&#231;&#227;o gira em torno de um tema, que nesta pr&#243;xima edi&#231;&#227;o ser&#225; o meio ambiente.
Para [...]]]></description>
			<content:encoded><![CDATA[<p>A Microsoft fez o que ningu&eacute;m esperava, disponibilizou gratuitamente quatro dos seus grandes produtos para quem se inscrever no Imagine Cup 2008. O Imagine Cup, &eacute; uma competi&ccedil;&atilde;o entre estudantes de todo o mundo. Dividida entre tr&ecirc;s categorias principais, a competi&ccedil;&atilde;o gira em torno de um tema, que nesta pr&oacute;xima edi&ccedil;&atilde;o ser&aacute; o meio ambiente.</p>
<p>Para esta edi&ccedil;&atilde;o o slogan da competi&ccedil;&atilde;o ser&aacute;: “Imagine um mundo onde a tecnologia permita um meio ambiente sustent&aacute;vel.”.</p>
<p>E as categorias ser&atilde;o: Design de Software, Desenvolvimento Embarcado, Desenvolvimento de Games, Projeto Hoshimi, IT Challenge, Algoritmo, Fotografia, Filme e Design de Interface.</p>
<p>Para se cadastrar no Imagine Cup e obter informa&ccedil;&otilde;es sobre a competi&ccedil;&atilde;o, entre neste link:<br />
<a rel="nofollow" href="http://imaginecup.com/Registration/Default.aspx">http://imaginecup.com/Registration/Default.aspx</a></p>
<p>Para efetuar o download dos sotwares, entre neste link:<br />
<a rel="nofollow" href="http://imaginecup.com/MyStuff/FreeSoftware.aspx">http://imaginecup.com/MyStuff/FreeSoftware.aspx</a></p><p>Confira ofertas de: <a href="http://centenaro.org/submarino/?pal=DVD" rel="external" target="_Blank">DVD</a>, <a href="http://centenaro.org/submarino/?pal=filmes" rel="external" target="_Blank">filmes</a>, <a href="http://centenaro.org/submarino/?pal=celular" rel="external" target="_Blank">celular</a>, <a href="http://centenaro.org/submarino/?pal=notebook" rel="external" target="_Blank">notebook</a>, <a href="http://centenaro.org/submarino/?pal=livros" rel="external" target="_Blank">livros</a>, <a href="http://centenaro.org/submarino/?pal=jogos" rel="external" target="_Blank">jogos</a>, <a href="http://centenaro.org/submarino/?pal=Wii" rel="external" target="_Blank">Wii</a>, <a href="http://centenaro.org/submarino/?pal=PS3" rel="external" target="_Blank">PS3</a>, <a href="http://centenaro.org/submarino/?pal=MP4" rel="external" target="_Blank">MP4</a></p><p>a</p>
<p><a href="http://fdweb.com.br/download-sem-custo-do-visual-studio-2005-professional-edition-visual-sourcesafe-2005-sql-server-2005-developer-edition-e-o-expression-web/">Download sem custo do Visual Studio 2005 Professional Edition, Visual SourceSafe 2005, SQL Server 2005 Developer Edition e o Expression Web</a></p>
]]></content:encoded>
			<wfw:commentRss>http://fdweb.com.br/download-sem-custo-do-visual-studio-2005-professional-edition-visual-sourcesafe-2005-sql-server-2005-developer-edition-e-o-expression-web/feed/</wfw:commentRss>
		<feedburner:origLink>http://fdweb.com.br/download-sem-custo-do-visual-studio-2005-professional-edition-visual-sourcesafe-2005-sql-server-2005-developer-edition-e-o-expression-web/</feedburner:origLink></item>
		<item>
		<title>Enviar email no Visual Basic por Winsock</title>
		<link>http://feeds.feedburner.com/~r/fdweb/~3/186882661/</link>
		<comments>http://fdweb.com.br/enviar-email-no-visual-basic-por-winsock/#comments</comments>
		<pubDate>Sun, 18 Nov 2007 23:55:41 +0000</pubDate>
		<dc:creator>Daniel Nogueira</dc:creator>
		
		<category><![CDATA[Programação]]></category>

		<category><![CDATA[Visual Basic]]></category>

		<category><![CDATA[email]]></category>

		<category><![CDATA[enviar]]></category>

		<category><![CDATA[winsock]]></category>

		<guid isPermaLink="false">http://fdweb.com.br/enviar-email-no-visual-basic-por-winsock/</guid>
		<description><![CDATA[Uma boa alternativa para enviar emails pelo Visual Basic &#233; utilizar o componente Winsock. Trabalhando com o Winsock temos a liberdade de poder controlar passo a passo o envio da mensagem, podendo tratar todos os erros poss&#237;veis. A &#250;nica coisa que precisamos &#233; do modulo de encripta&#231;&#227;o em Base64, para encriptar o usu&#225;rio e senha [...]]]></description>
			<content:encoded><![CDATA[<p>Uma boa alternativa para enviar emails pelo Visual Basic &eacute; utilizar o componente Winsock. Trabalhando com o Winsock temos a liberdade de poder controlar passo a passo o envio da mensagem, podendo tratar todos os erros poss&iacute;veis. A &uacute;nica coisa que precisamos &eacute; do modulo de encripta&ccedil;&atilde;o em Base64, para encriptar o usu&aacute;rio e senha para a autentica&ccedil;&atilde;o no servidor SMTP. E Inserir no nosso projeto o componente Microsoft Winsock Control.</p>
<p>Vou montar um simples exemplo, demonstrando o envio de um email.</p>
<h2>Exemplo</h2>
<p>Trabalhar com Winsock &eacute; muito simples, voc&ecirc; se conecta ao seu servidor SMTP, e envia comandos para ele interpretar, que retornam resposta para voc&ecirc; tratar. Os primeiros tr&ecirc;s caracteres da mensagem retornada formam um c&oacute;digo, para voc&ecirc; identificar o significado da mensagem retornada.</p>
<p>Vamos criar a interface do nosso exemplo:</p>
<p>1. Crie um formul&aacute;rio e o nomeie para frmPrincipal.</p>
<p>2. Insira 5 Labels, e defina a propriedade Caption para cada Label respectivamente: &#8220;Smtp&#8221;, &#8220;Remetente&#8221;, &#8220;Destinat&aacute;rio&#8221;, &#8220;Assunto&#8221;, &#8220;Mensagem&#8221;.</p>
<p>3. Insira 5 TextBoxs, e defina a propriedade Name para cada TextBox respectivamente: &#8220;txtSmtp&#8221;, &#8220;txtRemetente&#8221;, &#8220;txtDestinatario&#8221;, &#8220;txtAssunto&#8221;, &#8220;txtMensagem&#8221;.</p>
<p>4. Insira um CommandButton, e defina a propriedade Name para &#8220;cmdEnviarEmail&#8221; e a propriedade Caption para &#8220;Enviar Email&#8221;.</p>
<p>5. Insira um controle Winsock, e defina a propriedade Name para &#8220;winsockEmail&#8221;. Para inserir o componente Winsock na sua barra de controles, v&aacute; at&eacute; o menu Project-&gt;Components na lista procure por Microsoft Winsock Control, marque a caixa de sele&ccedil;&atilde;o, e confirme a altera&ccedil;&atilde;o no bot&atilde;o OK.</p>
<p>Organize a interface da maneira que achar melhor.</p>
<p>No formul&aacute;rio frmPrincipal, crie as seguintes constantes:</p>
<blockquote><p>Const cntConectando = 0</p>
<p>Const cntDesconectar = 1</p>
<p>Const cntConectado = 2</p>
<p>Const cntAutenticar = 3</p>
<p>Const cntAutenticarUsuario = 4</p>
<p>Const cntAutenticarSenha = 5</p>
<p>Const cntRemetente = 6</p>
<p>Const cntPara = 7</p>
<p>Const cntMensagem = 8</p>
<p>Const cntFinalizar = 9</p></blockquote>
<p>Crie tambem as seguintes variaveis:</p>
<blockquote><p>Dim strUsuarioSMTP As String</p>
<p>Dim strSenhaSMTP As String</p>
<p>Dim blnAutenicarSMTP As Boolean</p></blockquote>
<h2>Base 64</h2>
<p>Agora vamos criar o modulo para encripta&ccedil;&atilde;o do usu&aacute;rio e a senha enviados para o servidor SMTP, renomei-e para mdlBase64. E insira o c&oacute;digo abaixo:</p>
<blockquote><p>Public Function sBase64Decode(BASE64TEXT_IN As String) As String</p>
<p>Dim i As Long, sText As String, rc As Integer</p>
<p>Dim sFour As String, sThree As String</p>
<p>Dim sOut As String</p>
<p>sText = sRemoveWhitespace(BASE64TEXT_IN)</p>
<p>For i = 1 To Len(sText) Step 4</p>
<p>sFour = Mid$(sText, i, 4)</p>
<p>While Len(sFour) &lt; 4: sFour = sFour &amp; &#8220;=&#8221;: Wend</p>
<p>sThree = sDecode4(sFour)</p>
<p>If Len(sThree) = 3 Then</p>
<p>sOut = sOut &amp; sThree</p>
<p>Else</p>
<p>rc = MsgBox(&#8221;Illegal Characters &lt;&#8221; &amp; sFour &amp; &#8220;&gt; found&#8221;, vbOKCancel, &#8220;PROGRAM ERROR&#8221;)</p>
<p>If rc = vbCancel Then Exit For</p>
<p>sOut = sOut &amp; &#8220;???&#8221;</p>
<p>End If</p>
<p>Next i</p>
<p>sBase64Decode = sOut</p>
<p>End Function</p>
<p>Public Function sBase64Encode(TEXT_IN As String) As String</p>
<p>Dim i As Long, sText As String, sThree As String, sFour As String</p>
<p>Dim sOut As String, nLineLength As Integer</p>
<p>Dim nNulls As Integer</p>
<p>sText = TEXT_IN</p>
<p>For i = 1 To Len(sText) Step 3</p>
<p>sThree = Mid$(sText, i, 3)</p>
<p>nNulls = Len(sThree) Mod 3</p>
<p>If nNulls &gt; 0 Then nNulls = 3 - nNulls</p>
<p>sThree = sThree &amp; Left$(Chr$(0) &amp; Chr$(0), nNulls)</p>
<p>sFour = sEncode3(sThree)</p>
<p>If nNulls &gt; 0 Then</p>
<p>sFour = Left$(sFour, 4 - nNulls)</p>
<p>sFour = sFour &amp; Left$(&#8221;==&#8221;, nNulls)</p>
<p>End If</p>
<p>sOut = sOut &amp; sFour</p>
<p>nLineLength = nLineLength + 4</p>
<p>If nLineLength &gt;= 64 Then</p>
<p>sOut = sOut &amp; vbNewLine</p>
<p>nLineLength = 0</p>
<p>End If</p>
<p>Next i</p>
<p>sBase64Encode = sOut</p>
<p>End Function</p>
<p>Private Function nBase64Digit(VALUE_IN As Integer) As Byte</p>
<p>Dim Digit64 As Byte, n As Integer</p>
<p>Debug.Assert VALUE_IN &gt;= 0 And VALUE_IN &lt;= 63</p>
<p>n = VALUE_IN</p>
<p>Select Case n</p>
<p>Case Is &lt;= 25: Digit64 = Asc(&#8221;A&#8221;) + n</p>
<p>Case Is &lt;= 51: Digit64 = Asc(&#8221;a&#8221;) + (n - 26)</p>
<p>Case Is &lt;= 61: Digit64 = Asc(&#8221;0&#8243;) + (n - 52)</p>
<p>Case 62: Digit64 = Asc(&#8221;+&#8221;)</p>
<p>Case 63: Digit64 = Asc(&#8221;/&#8221;)</p>
<p>Case Else</p>
<p>Digit64 = &#8220;?&#8221;</p>
<p>Debug.Assert False</p>
<p>End Select</p>
<p>nBase64Digit = Digit64</p>
<p>End Function</p>
<p>Private Function nBase64Value(ONEBYTE_IN As String) As Integer</p>
<p>Dim n As Integer</p>
<p>Select Case ONEBYTE_IN</p>
<p>Case &#8220;A&#8221; To &#8220;Z&#8221;: n = Asc(ONEBYTE_IN) - Asc(&#8221;A&#8221;)</p>
<p>Case &#8220;a&#8221; To &#8220;z&#8221;: n = 26 + Asc(ONEBYTE_IN) - Asc(&#8221;a&#8221;)</p>
<p>Case &#8220;0&#8243; To &#8220;9&#8243;: n = 52 + Asc(ONEBYTE_IN) - Asc(&#8221;0&#8243;)</p>
<p>Case &#8220;+&#8221;: n = 62</p>
<p>Case &#8220;/&#8221;: n = 63</p>
<p>Case &#8220;=&#8221;: n = 0</p>
<p>Case Else</p>
<p>n = 255</p>
<p>End Select</p>
<p>nBase64Value = n</p>
<p>End Function</p>
<p>Private Function sDecode4(BASE64TEXT_IN As String) As String</p>
<p>Dim nBits As Long</p>
<p>Dim s1 As String, s2 As String, s3 As String, s4 As String</p>
<p>Dim t1 As String, t2 As String, t3 As String</p>
<p>Dim n1 As Byte, n2 As Byte, n3 As Byte, n4 As Byte</p>
<p>If Len(BASE64TEXT_IN) &lt;&gt; 4 Or Not IsBase64(BASE64TEXT_IN) Then</p>
<p>Debug.Assert False</p>
<p>sDecode4 = &#8220;&#8221;</p>
<p>Exit Function</p>
<p>End If</p>
<p>s1 = Mid$(BASE64TEXT_IN, 1, 1)</p>
<p>s2 = Mid$(BASE64TEXT_IN, 2, 1)</p>
<p>s3 = Mid$(BASE64TEXT_IN, 3, 1)</p>
<p>s4 = Mid$(BASE64TEXT_IN, 4, 1)</p>
<p>n1 = nBase64Value(s1)</p>
<p>n2 = nBase64Value(s2)</p>
<p>n3 = nBase64Value(s3)</p>
<p>n4 = nBase64Value(s4)</p>
<p>If n1 = 255 Or n2 = 255 Or n3 = 255 Or n4 = 255 Then</p>
<p>sDecode4 = &#8220;&#8221;</p>
<p>Exit Function</p>
<p>End If</p>
<p>nBits = nBits Or n4</p>
<p>nBits = nBits Or (n3 * 64&amp;)</p>
<p>nBits = nBits Or (n2 * 64&amp; * 64&amp;)</p>
<p>nBits = nBits Or (n1 * 64&amp; * 64&amp; * 64&amp;)</p>
<p>t3 = Chr$(nBits And 255)</p>
<p>t2 = Chr$((nBits \ 256) And 255)</p>
<p>t1 = Chr$((nBits \ 256 \ 256))</p>
<p>sDecode4 = t1 &amp; t2 &amp; t3</p>
<p>End Function</p>
<p>Private Function sEncode3(THREEBYTES_IN As String) As String</p>
<p>Dim s1 As String, s2 As String, s3 As String</p>
<p>Dim n1 As Byte, n2 As Byte, n3 As Byte</p>
<p>Dim nBits As Long</p>
<p>Dim t1 As Byte, t2 As Byte, t3 As Byte, t4 As Byte</p>
<p>Debug.Assert Len(THREEBYTES_IN) = 3</p>
<p>s1 = Mid$(THREEBYTES_IN, 1, 1)</p>
<p>s2 = Mid$(THREEBYTES_IN, 2, 1)</p>
<p>s3 = Mid$(THREEBYTES_IN, 3, 1)</p>
<p>n1 = Asc(s1)</p>
<p>n2 = Asc(s2)</p>
<p>n3 = Asc(s3)</p>
<p>nBits = nBits Or n3</p>
<p>nBits = nBits Or (n2 * 256&amp;)</p>
<p>nBits = nBits Or (n1 * 256&amp; * 256&amp;)</p>
<p>t4 = nBase64Digit(nBits And 63)</p>
<p>t3 = nBase64Digit((nBits \ 64) And 63)</p>
<p>t2 = nBase64Digit((nBits \ 64 \ 64) And 63)</p>
<p>t1 = nBase64Digit((nBits \ 64 \ 64 \ 64) And 63)</p>
<p>sEncode3 = Chr$(t1) &amp; Chr$(t2) &amp; Chr$(t3) &amp; Chr$(t4)</p>
<p>End Function</p>
<p>Public Function IsBase64(TEXT_IN As String, Optional MSGBOX_IN As Boolean = False) As Boolean</p>
<p>Dim i As Long, sText As String</p>
<p>If TEXT_IN = &#8220;&#8221; Then</p>
<p>IsBase64 = False</p>
<p>Exit Function</p>
<p>End If</p>
<p>sText = sRemoveWhitespace(TEXT_IN)</p>
<p>For i = 1 To Len(sText)</p>
<p>Select Case Mid$(sText, i, 1)</p>
<p>Case &#8220;A&#8221; To &#8220;Z&#8221;, &#8220;a&#8221; To &#8220;z&#8221;, &#8220;0&#8243; To &#8220;9&#8243;, &#8220;+&#8221;, &#8220;/&#8221;, vbCr, vbLf</p>
<p>Case &#8220;=&#8221;</p>
<p>If i = Len(sText) - 1 Then</p>
<p>If Mid$(sText, i + 1, 1) = &#8220;=&#8221; Then</p>
<p>End If</p>
<p>ElseIf i = Len(sText) Then</p>
<p>Else</p>
<p>If MSGBOX_IN Then MsgBox &#8220;Text Error: Equal Sign not at end of text&#8221;, , &#8220;TRIM END OF TEXT&#8221;</p>
<p>IsBase64 = False</p>
<p>Exit Function</p>
<p>End If</p>
<p>Case Else</p>
<p>If MSGBOX_IN Then MsgBox &#8220;Non-base64 character &lt;&#8221; _</p>
<p>&amp; Mid$(TEXT_IN, i, 1) &amp; &#8220;&gt; found in base64&#8243; _</p>
<p>&amp; &#8221; text&#8221;, , &#8220;ILLEGAL BASE64 BYTE&#8221;</p>
<p>IsBase64 = False</p>
<p>Exit Function</p>
<p>End Select</p>
<p>Next i</p>
<p>IsBase64 = True</p>
<p>End Function</p>
<p>Private Function sRemoveWhitespace(TEXT_IN As String) As String</p>
<p>Dim sText As String</p>
<p>sText = TEXT_IN</p>
<p>sText = Replace(sText, vbCr, &#8220;&#8221;)</p>
<p>sText = Replace(sText, vbLf, &#8220;&#8221;)</p>
<p>sText = Replace(sText, vbTab, &#8220;&#8221;)</p>
<p>sText = Replace(sText, &#8221; &#8220;, &#8220;&#8221;)</p>
<p>sRemoveWhitespace = sText</p>
<p>End Function</p></blockquote>
<h2>Winsock</h2>
<p>Vamos criar o c&oacute;digo para tratar os eventos do winsockEmail, no evento DataArrival vamos inserir este c&oacute;digo:</p>
<blockquote><p>Private Sub winsockEmail_DataArrival(ByVal bytesTotal As Long)</p>
<p>Dim strDadosRecebidos As String</p>
<p>Dim strStatusCodigo As String</p>
<p>Dim strEmailHTML As String</p>
<p>Dim strEmailMensagem As String</p>
<p>&#8216;* Verifica se o winsock foi conectado<br />
If Trim(winsockEmail.Tag) &lt;&gt; &#8220;&#8221; Then _</p>
<p>winsockEmail.GetData strDadosRecebidos</p>
<p>&#8216;* Define o codigo do status<br />
strStatusCodigo = Left(strDadosRecebidos, 3)</p>
<p>Select Case strStatusCodigo</p>
<p>&#8216;* Caso tenha retornado um status valido<br />
Case &#8220;250&#8243;, &#8220;220&#8243;, &#8220;354&#8243;, &#8220;221&#8243;, &#8220;334&#8243;, &#8220;235&#8243;:</p>
<p>&#8216;* Caso nao tenha retornado um resultado valido<br />
Case Else:</p>
<p>MsgBox &#8220;Erro: &#8221; &amp; strDadosRecebidos, vbCritical</p>
<p>&#8216;* Define o status do winsock<br />
winsockEmail.Tag = cntDesconectar</p>
<p>&#8216;* Define o codigo do status<br />
strStatusCodigo = Mid(strDadosRecebidos, 4)</p>
<p>End Select</p>
<p>Select Case winsockEmail.Tag</p>
<p>&#8216;* Caso esteja conectando<br />
Case cntConectando:</p>
<p>&#8216;* Verifica se deve autenticar o smtp<br />
If blnAutenicarSMTP = True Then</p>
<p>&#8216;* Define o status para autenticar<br />
winsockEmail.Tag = cntAutenticar</p>
<p>Else</p>
<p>&#8216;* Define o status para conectado<br />
winsockEmail.Tag = cntConectado</p>
<p>End If</p>
<p>&#8216;* Envia o IP da maquina<br />
winsockEmail.SendData &#8220;ehlo &#8221; &amp; winsockEmail.LocalIP &amp; vbCrLf</p>
<p>&#8216;* Caso esteja autenticando<br />
Case cntAutenticar:</p>
<p>&#8216;* Envia pedido de autenticacao<br />
winsockEmail.SendData &#8220;auth login&#8221; &amp; vbCrLf</p>
<p>&#8216;* Define o status para autenticar o usuario<br />
winsockEmail.Tag = cntAutenticarUsuario</p>
<p>&#8216;* Caso esteja autenticando o usuario<br />
Case cntAutenticarUsuario:</p>
<p>&#8216;* Codifica o usuario do smtp e envia para o servidor SMTP<br />
winsockEmail.SendData sBase64Encode(Trim(strUsuarioSMTP)) &amp; vbCrLf</p>
<p>&#8216;* Define o status para autenticar senha<br />
winsockEmail.Tag = cntAutenticarSenha</p>
<p>&#8216;* Caso esteja autenticando a senha<br />
Case cntAutenticarSenha:</p>
<p>&#8216;* Codifica a senha e envia o servidor SMTP<br />
winsockEmail.SendData sBase64Encode(Trim(strSenhaSMTP)) &amp; vbCrLf</p>
<p>&#8216;* Define o status como conectado<br />
winsockEmail.Tag = cntConectado</p>
<p>&#8216;* Caso esteja conectado<br />
Case cntConectado:</p>
<p>&#8216;* Envia para o servidor SMTP o email do remetente<br />
winsockEmail.SendData &#8220;mail from:&lt;&#8221; &amp; Trim(txtRemetente.Text) &amp; &#8220;&gt;&#8221; &amp; vbCrLf</p>
<p>&#8216;* Define o status como remetente<br />
winsockEmail.Tag = cntRemetente</p>
<p>&#8216;* Case esteja com o status remetente<br />
Case cntRemetente:</p>
<p>&#8216;* Envia para o servidor SMTP quem ira receber a mensagem<br />
winsockEmail.SendData &#8220;rcpt to:&lt;&#8221; &amp; Trim(txtDestinatario.Text) &amp; &#8220;&gt;&#8221; &amp; vbCrLf</p>
<p>&#8216;* Define o status para quem ira receber a mensagem<br />
winsockEmail.Tag = cntPara</p>
<p>&#8216;* Caso esteja enviado quem ira receber a mensagem<br />
Case cntPara:</p>
<p>&#8216;* Enviar para o servidor SMTP o comando data<br />
winsockEmail.SendData &#8220;data&#8221; &amp; vbCrLf</p>
<p>&#8216;* Define o status para enviar a mensagem<br />
winsockEmail.Tag = cntMensagem</p>
<p>&#8216;* Caso tenha que enviar a mensagem<br />
Case cntMensagem:</p>
<p>&#8216;* Monta o cabecalho do email<br />
strEmailHTML = &#8220;subject:&#8221; &amp; txtAssunto.Text &amp; vbCrLf &amp; _<br />
&#8220;from:&#8221; &amp; txtRemetente.Text &amp; vbCrLf &amp; _<br />
&#8220;to:&#8221; &amp; txtDestinatario.Text &amp; vbCrLf &amp; _<br />
&#8220;MIME-Version: 1.0&#8243; &amp; vbCrLf &amp; _<br />
&#8220;Content-type: text/html; charset=iso-8859-1&#8243; &amp; vbCrLf</p>
<p>&#8216;* Monta a mensagem<br />
strEmailMensagem = &#8220;&lt;body&gt;&#8221; &amp; vbCrLf &amp; vbCrLf &amp; Trim(txtMensagem.Text) &amp; vbCrLf &amp; vbCrLf &amp; &#8220;&lt;/body&gt;&#8221;</p>
<p>&#8216;* Troca . entre quebra de linhas por ..<br />
While InStr(strEmailMensagem, vbCrLf &amp; &#8220;.&#8221; &amp; vbCrLf) &lt;&gt; 0</p>
<p>strEmailMensagem = Replace(strEmailMensagem, vbCrLf &amp; &#8220;.&#8221; &amp; vbCrLf, vbCrLf &amp; &#8220;..&#8221; &amp; vbCrLf)</p>
<p>Wend</p>
<p>&#8216;* Envia para o servidor SMTP o texto do email<br />
winsockEmail.SendData strEmailHTML &amp; strEmailMensagem &amp; vbCrLf &amp; &#8220;.&#8221; &amp; vbCrLf</p>
<p>&#8216;* Define o status para finalizar a conexao<br />
winsockEmail.Tag = cntFinalizar</p>
<p>&#8216;* Caso tenha que finalizar a conexao<br />
Case cntFinalizar:</p>
<p>MsgBox &#8220;Mensagem enviada!&#8221;</p>
<p>&#8216;* Envia para o servidor SMTP a saida<br />
winsockEmail.SendData &#8220;quit&#8221; &amp; vbCrLf</p>
<p>&#8216;* Define o status para desconectar o winsock<br />
winsockEmail.Tag = cntDesconectar</p>
<p>&#8216;* Caso queira desconectar o winsock<br />
Case cntDesconectar:</p>
<p>&#8216;* Fecha o winsock<br />
winsockEmail.Close</p>
<p>&#8216;* Limpa o status do winsock<br />
winsockEmail.Tag = &#8220;&#8221;</p>
<p>End Select</p>
<p>End Sub</p></blockquote>
<p>No evento Connect, vamos inserir o seguinte c&oacute;digo:</p>
<blockquote><p>Private Sub winsockEmail_Connect()</p>
<p>&#8216;* Define o status do winsock<br />
winsockEmail.Tag = cntConectando</p>
<p>End Sub</p></blockquote>
<h2>Conectar e Enviar</h2>
<p>Agora vamos criar o evento click do bot&atilde;o para enviar o email, insira o seguinte c&oacute;digo:</p>
<blockquote><p>Private Sub cmdEnviarEmail_Click()</p>
<p>&#8216;* Pergunta ao usuario se quer autenticar no servidor smtp<br />
If MsgBox(&#8221;Autenticar no servidor SMTP?&#8221;, vbYesNo, &#8220;Autentica&ccedil;&atilde;o&#8221;) = vbYes Then</p>
<p>blnAutenicarSMTP = True</p>
<p>&#8216;* Abre a caixa para o usuario digitar o usuario do smtp<br />
strUsuarioSMTP = InputBox(&#8221;Digite o usuario do servidor smtp&#8221;)</p>
<p>&#8216;* Abre a caixa para o usuario digitar a senha do smtp<br />
strSenhaSMTP = InputBox(&#8221;Digite a senha do servidor smtp&#8221;)</p>
<p>Else</p>
<p>&#8216;* Definir e limpar variaveis para nao autenticar<br />
blnAutenicarSMTP = False</p>
<p>strUsuarioSMTP = &#8220;&#8221;</p>
<p>strSenhaSMTP = &#8220;&#8221;</p>
<p>End If</p>
<p>&#8216;* Conectar ao servidor SMTP via winsock, no ip apontado por txtSMTP e a porta 25<br />
winsockEmail.Connect txtSmtp.Text, 25</p>
<p>End Sub</p></blockquote>
<h2>Testando o exemplo</h2>
<p>Apos preencher os dados, clique no bot&atilde;o de enviar mensagem. Uma MsgBox vai aparecer perguntado se quer voc&ecirc; quer autenticar no servidor SMTP. Caso queira, digite o usuario e a senha do seu servidor SMPT.</p>
<p>O winsockEmail conecta-se ao servidor SMTP apontado por txtSmtp.Text, na porta 25:</p>
<blockquote><p>&#8216;* Conectar ao servidor SMTP via Winsock, no ip apontado por txtSMTP e a porta 25<br />
winsockEmail.Connect txtSmtp.Text, 25</p></blockquote>
<p>As respostas do servidor SMTP s&atilde;o recebidas no evento DataArrival. Onde definimos na string strStatusCodigo o c&oacute;digo de identifica&ccedil;&atilde;o da mensagem, e verificamos se o codigo retornado &eacute; valido:</p>
<blockquote><p>&#8216;* Define o codigo do status<br />
strStatusCodigo = Left(strDadosRecebidos, 3)</p>
<p>Select Case strStatusCodigo</p>
<p>&#8216;* Caso tenha retornado um status valido<br />
Case &#8220;250&#8243;, &#8220;220&#8243;, &#8220;354&#8243;, &#8220;221&#8243;, &#8220;334&#8243;, &#8220;235&#8243;:</p>
<p>&#8216;* Caso nao tenha retornado um resultado valido<br />
Case Else:</p>
<p>MsgBox &#8220;Erro: &#8221; &amp; strDadosRecebidos, vbCritical</p>
<p>&#8216;* Define o status do winsock<br />
winsockEmail.Tag = cntDesconectar</p>
<p>&#8216;* Define o codigo do status<br />
strStatusCodigo = Mid(strDadosRecebidos, 4)</p>
<p>End Select</p></blockquote>
<p>Agora verificamos o status do winsock, caso ele esteja conectando verificamos se devemos executar a autentica&ccedil;&atilde;o no servidor SMTP, ou conectar sem autenticar:</p>
<blockquote><p>Select Case winsockEmail.Tag</p>
<p>&#8216;* Caso esteja conectando<br />
Case cntConectando:</p>
<p>&#8216;* Verifica se deve autenticar o smtp<br />
If blnAutenicarSMTP = True Then</p>
<p>&#8216;* Define o status para autenticar<br />
winsockEmail.Tag = cntAutenticar</p>
<p>Else</p>
<p>&#8216;* Define o status para conectado<br />
winsockEmail.Tag = cntConectado</p>
<p>End If</p>
<p>&#8216;* Envia o IP da maquina<br />
winsockEmail.SendData &#8220;ehlo &#8221; &amp; winsockEmail.LocalIP &amp; vbCrLf</p></blockquote>
<p>Codificamos e enviamos o usuario e a senha apontados por &#8220;strUsuarioSMTP&#8221; e &#8220;strSenhaSMTP&#8221;, respectivamente:</p>
<blockquote><p>&#8216;* Caso esteja autenticando<br />
Case cntAutenticar:</p>
<p>&#8216;* Envia pedido de autenticacao<br />
winsockEmail.SendData &#8220;auth login&#8221; &amp; vbCrLf</p>
<p>&#8216;* Define o status para autenticar o usuario<br />
winsockEmail.Tag = cntAutenticarUsuario</p>
<p>&#8216;* Caso esteja autenticando o usuario<br />
Case cntAutenticarUsuario:</p>
<p>&#8216;* Codifica o usuario do smtp e envia para o servidor SMTP<br />
winsockEmail.SendData sBase64Encode(Trim(strUsuarioSMTP)) &amp; vbCrLf</p>
<p>&#8216;* Define o status para autenticar senha<br />
winsockEmail.Tag = cntAutenticarSenha</p>
<p>&#8216;* Caso esteja autenticando a senha<br />
Case cntAutenticarSenha:</p>
<p>&#8216;* Codifica a senha e envia o servidor SMTP<br />
winsockEmail.SendData sBase64Encode(Trim(strSenhaSMTP)) &amp; vbCrLf</p>
<p>&#8216;* Define o status como conectado<br />
winsockEmail.Tag = cntConectado</p></blockquote>
<p>Ap&oacute;s confirmar a conex&atilde;o envia os dados do remetente e destinat&aacute;rios. Ap&oacute;s envia o comando data, para come&ccedil;ar a enviar a mensagem:</p>
<blockquote><p>&#8216;* Caso esteja conectado<br />
Case cntConectado:</p>
<p>&#8216;* Envia para o servidor SMTP o email do remetente<br />
winsockEmail.SendData &#8220;mail from:&lt;&#8221; &amp; Trim(txtRemetente.Text) &amp; &#8220;&gt;&#8221; &amp; vbCrLf</p>
<p>&#8216;* Define o status como remetente<br />
winsockEmail.Tag = cntRemetente</p>
<p>&#8216;* Case esteja com o status remetente<br />
Case cntRemetente:</p>
<p>&#8216;* Envia para o servidor SMTP quem ira receber a mensagem<br />
winsockEmail.SendData &#8220;rcpt to:&lt;&#8221; &amp; Trim(txtDestinatario.Text) &amp; &#8220;&gt;&#8221; &amp; vbCrLf</p>
<p>&#8216;* Define o status para quem ira receber a mensagem<br />
winsockEmail.Tag = cntPara</p>
<p>&#8216;* Caso esteja enviado quem ira receber a mensagem<br />
Case cntPara:</p>
<p>&#8216;* Enviar para o servidor SMTP o comando data<br />
winsockEmail.SendData &#8220;data&#8221; &amp; vbCrLf</p>
<p>&#8216;* Define o status para enviar a mensagem<br />
winsockEmail.Tag = cntMensagem</p></blockquote>
<p>Monta a estrutura do html que ser&aacute; enviado. Contendo um cabe&ccedil;alho com alguns dados do email como assunto, remetente, destinat&aacute;rio. E a mensagem em html. Ap&oacute;s, envia a mensagem pelo winsockEmail:</p>
<blockquote><p>&#8216;* Caso tenha que enviar a mensagem<br />
Case cntMensagem:</p>
<p>&#8216;* Monta o cabecalho do email<br />
strEmailHTML = &#8220;subject:&#8221; &amp; txtAssunto.Text &amp; vbCrLf &amp; _<br />
&#8220;from:&#8221; &amp; txtRemetente.Text &amp; vbCrLf &amp; _<br />
&#8220;to:&#8221; &amp; txtDestinatario.Text &amp; vbCrLf &amp; _<br />
&#8220;MIME-Version: 1.0&#8243; &amp; vbCrLf &amp; _<br />
&#8220;Content-type: text/html; charset=iso-8859-1&#8243; &amp; vbCrLf</p>
<p>&#8216;* Monta a mensagem<br />
strEmailMensagem = &#8220;&lt;body&gt;&#8221; &amp; vbCrLf &amp; vbCrLf &amp; Trim(txtMensagem.Text) &amp; vbCrLf &amp; vbCrLf &amp; &#8220;&lt;/body&gt;&#8221;</p>
<p>&#8216;* Troca . entre quebra de linhas por ..<br />
While InStr(strEmailMensagem, vbCrLf &amp; &#8220;.&#8221; &amp; vbCrLf) &lt;&gt; 0</p>
<p>strEmailMensagem = Replace(strEmailMensagem, vbCrLf &amp; &#8220;.&#8221; &amp; vbCrLf, vbCrLf &amp; &#8220;..&#8221; &amp; vbCrLf)</p>
<p>Wend</p>
<p>&#8216;* Envia para o servidor SMTP o texto do email<br />
winsockEmail.SendData strEmailHTML &amp; strEmailMensagem &amp; vbCrLf &amp; &#8220;.&#8221; &amp; vbCrLf</p>
<p>&#8216;* Define o status para finalizar a conexao<br />
winsockEmail.Tag = cntFinalizar</p></blockquote>
<p>Caso tenha finalizado, mostra uma mensagem de conclu&iacute;do e fecha winsockEmail:</p>
<blockquote><p>&#8216;* Caso tenha que finalizar a conexao<br />
Case cntFinalizar:</p>
<p>MsgBox &#8220;Mensagem enviada!&#8221;</p>
<p>&#8216;* Envia para o servidor SMTP a saida<br />
winsockEmail.SendData &#8220;quit&#8221; &amp; vbCrLf</p>
<p>&#8216;* Define o status para desconectar o winsock<br />
winsockEmail.Tag = cntDesconectar</p>
<p>&#8216;* Caso queira desconectar o winsock<br />
Case cntDesconectar:</p>
<p>&#8216;* Fecha o winsock<br />
winsockEmail.Close</p>
<p>&#8216;* Limpa o status do winsock<br />
winsockEmail.Tag = &#8220;&#8221;</p></blockquote>
<h2>Download do exemplo</h2>
<p>O link para download do exemplo:</p>
<p><a href="http://www.fdweb.com.br/downloads/enviaremailvisualbasic.zip" target="_blank">http://www.fdweb.com.br/downloads/enviaremailvisualbasic.zip</a></p><p>Confira ofertas de: <a href="http://centenaro.org/submarino/?pal=DVD" rel="external" target="_Blank">DVD</a>, <a href="http://centenaro.org/submarino/?pal=filmes" rel="external" target="_Blank">filmes</a>, <a href="http://centenaro.org/submarino/?pal=celular" rel="external" target="_Blank">celular</a>, <a href="http://centenaro.org/submarino/?pal=notebook" rel="external" target="_Blank">notebook</a>, <a href="http://centenaro.org/submarino/?pal=livros" rel="external" target="_Blank">livros</a>, <a href="http://centenaro.org/submarino/?pal=jogos" rel="external" target="_Blank">jogos</a>, <a href="http://centenaro.org/submarino/?pal=Wii" rel="external" target="_Blank">Wii</a>, <a href="http://centenaro.org/submarino/?pal=PS3" rel="external" target="_Blank">PS3</a>, <a href="http://centenaro.org/submarino/?pal=MP4" rel="external" target="_Blank">MP4</a></p><p>a</p>
<p><a href="http://fdweb.com.br/enviar-email-no-visual-basic-por-winsock/">Enviar email no Visual Basic por Winsock</a></p>
]]></content:encoded>
			<wfw:commentRss>http://fdweb.com.br/enviar-email-no-visual-basic-por-winsock/feed/</wfw:commentRss>
		<feedburner:origLink>http://fdweb.com.br/enviar-email-no-visual-basic-por-winsock/</feedburner:origLink></item>
		<item>
		<title>String de conexão para banco de dados</title>
		<link>http://feeds.feedburner.com/~r/fdweb/~3/183963982/</link>
		<comments>http://fdweb.com.br/string-de-conexao-para-banco-de-dados/#comments</comments>
		<pubDate>Tue, 13 Nov 2007 06:00:45 +0000</pubDate>
		<dc:creator>Fabio Centenaro</dc:creator>
		
		<category><![CDATA[Geral]]></category>

		<category><![CDATA[banco de dados]]></category>

		<category><![CDATA[conexão]]></category>

		<category><![CDATA[Programação]]></category>

		<category><![CDATA[string]]></category>

		<guid isPermaLink="false">http://fdweb.com.br/string-de-conexao-para-banco-de-dados/</guid>
		<description><![CDATA[Uma coisa que eu sempre precisei, em todos esses anos trabalhando com inform&#225;tica e programa&#231;&#227;o, &#233; que quando eu tinha que acessar um banco de dados  n&#227;o lembrava da string de conex&#227;o.
Para quem n&#227;o sabe, string de conex&#227;o (ou connection string) &#233; um c&#243;digo utilizado pelo sistema para se conectar ao banco de dados. [...]]]></description>
			<content:encoded><![CDATA[<p>Uma coisa que eu sempre precisei, em todos esses anos trabalhando com inform&aacute;tica e programa&ccedil;&atilde;o, &eacute; que quando eu tinha que acessar um banco de dados  n&atilde;o lembrava da string de conex&atilde;o.</p>
<p>Para quem n&atilde;o sabe, <strong>string de conex&atilde;o (ou connection string)</strong> &eacute; um c&oacute;digo utilizado pelo sistema para se conectar ao banco de dados. Claro que pra facilitar as coisas, cada banco de dados tem a sua pr&oacute;pria <em>string</em>. Ent&atilde;o, para quem trabalha com SQL Server, Access, mySQL, PostgreSQL, &eacute; dif&iacute;cil lembrar de cabe&ccedil;a todas as conex&otilde;es, at&eacute; porque geralmente se usa apenas uma vez dentro do sistema.</p>
<p><span id="more-37"></span></p>
<p>Ent&atilde;o, por esse motivo, resolvi colocar aqui as principais strings que eu tenho utilizado:</p>
<blockquote><p> <strong>SQL Server: </strong><span id="sqlserveroledb" style="cursor: default"> “Provider=sqloledb;Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;Initial Catalog=pubs;User ID=sa;Password=asdasd;<br />
<strong>Access: “</strong></span><span id="access"><span id="jetoledb" style="cursor: default">Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb”;<br />
<strong>Access (com senha):</strong> </span></span><span id="access"><span id="jetoledb" style="cursor: default">“Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;Jet OLEDB:Database Password=MyDbPassword;”<br />
<strong>mySQL:</strong></span></span> “DRIVER={MySQL ODBC 3.51 Driver}; SERVER=myServer; PORT=3306; DATABASE=myDatabase; USER=myUsername; PASSWORD=myPassword; OPTION=3;”</p></blockquote>
<p>Existe um site contendo praticamente todas as strings de conex&atilde;o existentes. J&aacute; fiz muitas consultas &agrave; ele e j&aacute; me salvou de poucas e boas. O site &eacute; <a href="http://www.connectionstrings.com/" title="ConnectionStrings.com" target="_blank">www.connectionstrings.com</a> .</p>
<p>Agora n&atilde;o tem mais desculpa para n&atilde;o conseguir conectar ao banco de dados!</p><p>Confira ofertas de: <a href="http://centenaro.org/submarino/?pal=DVD" rel="external" target="_Blank">DVD</a>, <a href="http://centenaro.org/submarino/?pal=filmes" rel="external" target="_Blank">filmes</a>, <a href="http://centenaro.org/submarino/?pal=celular" rel="external" target="_Blank">celular</a>, <a href="http://centenaro.org/submarino/?pal=notebook" rel="external" target="_Blank">notebook</a>, <a href="http://centenaro.org/submarino/?pal=livros" rel="external" target="_Blank">livros</a>, <a href="http://centenaro.org/submarino/?pal=jogos" rel="external" target="_Blank">jogos</a>, <a href="http://centenaro.org/submarino/?pal=Wii" rel="external" target="_Blank">Wii</a>, <a href="http://centenaro.org/submarino/?pal=PS3" rel="external" target="_Blank">PS3</a>, <a href="http://centenaro.org/submarino/?pal=MP4" rel="external" target="_Blank">MP4</a></p><p>a</p>
<p><a href="http://fdweb.com.br/string-de-conexao-para-banco-de-dados/">String de conex&atilde;o para banco de dados</a></p>
]]></content:encoded>
			<wfw:commentRss>http://fdweb.com.br/string-de-conexao-para-banco-de-dados/feed/</wfw:commentRss>
		<feedburner:origLink>http://fdweb.com.br/string-de-conexao-para-banco-de-dados/</feedburner:origLink></item>
		<item>
		<title>Trabalhando com multithread no C#</title>
		<link>http://feeds.feedburner.com/~r/fdweb/~3/183724812/</link>
		<comments>http://fdweb.com.br/trabalhando-com-multithread-no-c/#comments</comments>
		<pubDate>Mon, 12 Nov 2007 19:54:39 +0000</pubDate>
		<dc:creator>Daniel Nogueira</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<category><![CDATA[Programação]]></category>

		<category><![CDATA[multithread]]></category>

		<guid isPermaLink="false">http://fdweb.com.br/trabalhando-com-multithread-no-c/</guid>
		<description><![CDATA[Para quem trabalhava ou ainda trabalha com Visual Basic, sabe que n&#227;o pode contar com uma solu&#231;&#227;o multithread, a n&#227;o ser que crie um Activex por exemplo para executar esta tarefa. Mas para quem migrou para C#, se deparou com uma linguagem bem completa, gra&#231;as as evolu&#231;&#245;es do framework .NET. Em C# &#233; poss&#237;vel trabalhar [...]]]></description>
			<content:encoded><![CDATA[<p>Para quem trabalhava ou ainda trabalha com Visual Basic, sabe que n&atilde;o pode contar com uma solu&ccedil;&atilde;o multithread, a n&atilde;o ser que crie um Activex por exemplo para executar esta tarefa. Mas para quem migrou para C#, se deparou com uma linguagem bem completa, gra&ccedil;as as evolu&ccedil;&otilde;es do framework .NET. Em C# &eacute; poss&iacute;vel trabalhar com a tecnologia multithread. E sua utiliza&ccedil;&atilde;o &eacute; muito &uacute;til para aplica&ccedil;&otilde;es que necessitam executar processos em separado, sem perda de performance no sistema. Num novo processo voc&ecirc; pode executar m&eacute;todos lentos e demorados que pendurariam a maquina, e o resto da sua aplica&ccedil;&atilde;o funcionara normalmente, poupando muito mais a paci&ecirc;ncia do usu&aacute;rio, de ficar parado olhando a aplica&ccedil;&atilde;o pensar.</p>
<p>Neste artigo, vamos mostrar casos simples de uso de multithread na sua aplica&ccedil;&atilde;o. Como execu&ccedil;&atilde;o de uma simples thread, intera&ccedil;ao entre threads e sincroniza&ccedil;&atilde;o de threads.</p>
<h2>O que &eacute; multithread?</h2>
<p>Multithread &eacute; a mesma coisa que comparar o DOS com o Windows, no DOS s&oacute; era poss&iacute;vel executar uma tarefa de cada vez e n&atilde;o abrir v&aacute;rias tarefas ao mesmo tempo, como o Windows nos permite. Com multithread &eacute; criada uma ilus&atilde;o de que todas as tarefas est&atilde;o sendo executadas ao mesmo tempo, mas na verdade est&atilde;o sendo executadas em partes, aos poucos cada processo executa um trecho do c&oacute;digo. Assim n&atilde;o sobrecarrega o sistema, podendo manter v&aacute;rias tarefas em execu&ccedil;&atilde;o ao mesmo tempo.</p>
<h2>Criar e executar uma Thread</h2>
<p>1. Crie um novo projeto C# Windows Application, e o renomeie-o para MultiThreadExemplo.<br />
2. Crie um formul&aacute;rio e o nomeie para clsfrmPrincipal.<br />
3. No formul&aacute;rio crie um TextBox chamado textBoxEvento, altere a propriedade Multiline para True e a propriedade ScrollsBar para Vertical.<br />
4. Insira dois ButtonBox no formul&aacute;rio, o primeiro com o nome butExecutarSemThread e defina a propriedade Text para &#8220;Executar sem Thread&#8221;, e o segundo para butExecutarThread e defina a propriedade Text para &#8220;Executar Thread&#8221;.</p>
<p>Criado a interface do exemplo, vamos para a parte de c&oacute;digos. Crie o evento FormClosing no formul&aacute;rio principal:</p>
<blockquote><p>private void clsfrmPrincipal_FormClosing(object sender, FormClosingEventArgs e)<br />
{</p>
<p>//* Fecha a aplica&ccedil;&atilde;o<br />
System.Environment.Exit(System.Environment.ExitCode);</p>
<p>}</p></blockquote>
<p>Crie o m&eacute;todo fncMostraMensagem para mostrar uma MenssageBox para o usu&aacute;rio:</p>
<blockquote><p>private void fncMostraMensagem(string strMensagem)<br />
{</p>
<p>//* Mostra um mensagem box<br />
MessageBox.Show(strMensagem);</p>
<p>return;</p>
<p>}</p></blockquote>
<p>Crie o evento Click do bot&atilde;o butExecutarSemThread, e insira o c&oacute;digo abaixo:</p>
<blockquote><p>private void butExecutarSemThread_Click(object sender, EventArgs e)<br />
{</p>
<p>//* Limpa a textbox<br />
textBoxEvento.Text = &#8220;&#8221;;</p>
<p>for (long lngQuantiadeMensagens = 0; lngQuantiadeMensagens &lt; 5; lngQuantiadeMensagens++)<br />
{</p>
<p>//* Executa o metodo<br />
fncMostraMensagem(lngQuantiadeMensagens.ToString());</p>
<p>//* Insere o indice no textbox<br />
textBoxEvento.Text += lngQuantiadeMensagens.ToString() + Environment.NewLine;</p>
<p>}</p>
<p>return;</p>
<p>}</p></blockquote>
<p>Crie o evento Click do bot&atilde;o butExecutarThread, e insira o c&oacute;digo abaixo:</p>
<blockquote><p>private void butExecutarThread_Click(object sender, EventArgs e)<br />
{</p>
<p>System.Threading.Thread[] threadMensagem;</p>
<p>//* Limpa a textbox<br />
textBoxEvento.Text = &#8220;&#8221;;</p>
<p>for (long lngQuantiadeMensagens = 0; lngQuantiadeMensagens &lt; 5; lngQuantiadeMensagens++)<br />
{</p>
<p>//* Incrementa a quantidade de itens do array<br />
threadMensagem = new System.Threading.Thread[lngQuantiadeMensagens + 1];</p>
<p>//* Cria uma nova ThreadStart com o metodo fncMensagem<br />
System.Threading.ThreadStart threadstartMensagem = delegate { fncMostraMensagem(lngQuantiadeMensagens.ToString()); };</p>
<p>//* Instancia a Thread<br />
threadMensagem[lngQuantiadeMensagens] = new System.Threading.Thread(threadstartMensagem);</p>
<p>//* Inicia a Thread<br />
threadMensagem[lngQuantiadeMensagens].Start();</p>
<p>//* Insere o indice no textbox<br />
textBoxEvento.Text += lngQuantiadeMensagens.ToString() + Environment.NewLine;</p>
<p>}</p>
<p>return;</p>
<p>}</p></blockquote>
<p>Neste simples exemplo vamos executar o m&eacute;todo fncMostraMensagem que mostra uma MessageBox com o texto passado por par&acirc;metro. E insere o &iacute;ndice atual no textBoxEvento.</p>
<p>Ao clicar no bot&atilde;o butExecutarSemThread, o programa passa por um la&ccedil;o mostrando para o usu&aacute;rio uma mensagem com o &iacute;ndice do la&ccedil;o em uma MessageBox e insere o &iacute;ndice atual no textBoxEvento. Mas enquanto o usu&aacute;rio n&atilde;o clicar no bot&atilde;o OK da mensagem, a pr&oacute;xima n&atilde;o aparecera.</p>
<p>Ao clicar no bot&atilde;o butExecutarThread, executamos praticamente a mesma fun&ccedil;&atilde;o, mas ao inv&eacute;s de chamar o m&eacute;todo fncMostraMensagem no mesmo processo que nossa aplica&ccedil;&atilde;o, executamos ele em separado, sendo assim, ele continua o la&ccedil;o, mesmo com a mensagem na tela, porque cada mensagem est&aacute; num processo independente uma da outra.</p>
<h2>Intera&ccedil;&atilde;o entre Threads</h2>
<p>Continuando o nosso exemplo, no mesmo projeto crie mais dois ButtonBox, o primeiro com o nome butNaoInteragirThreads e defina a propriedade Text para &#8220;N&atilde;o Interagir Threads&#8221;, e o segundo para butInteragirThreads e defina a propriedade Text para &#8220;Interagir Threads&#8221;.</p>
<p>Crie um delegate para a classe clsfrmPrincipal:</p>
<blockquote><p> private delegate void delegateInsereTexto(string Texto);</p></blockquote>
<p>Crie o m&eacute;todo fncInsereTextoThread que executa um la&ccedil;o, e insere o &iacute;ndice no textBoxEvento:</p>
<blockquote><p> private void fncInsereTextoThread(bool blnInsereDelegate)<br />
{</p>
<p>for (long lngCountMensagem = 0; lngCountMensagem &lt; 10; lngCountMensagem++)<br />
{<br />
//* Verifica se deve inserir o delegate<br />
if (blnInsereDelegate == true)<br />
{</p>
<p>//* Insere o texto na textbox<br />
this.Invoke(new delegateInsereTexto(fncInsereTextoEvento), lngCountMensagem.ToString() + Environment.NewLine);</p>
<p>}<br />
else<br />
{</p>
<p>textBoxEvento.Text += lngCountMensagem.ToString() + Environment.NewLine;</p>
<p>}</p>
<p>}</p>
<p>return;</p>
<p>}</p></blockquote>
<p>Insira o m&eacute;todo fncInsereTextoEvento que insere o texto passado como par&acirc;metro no textBoxEvento, que ser&aacute; usado pelo delegate que criamos anteriormente:</p>
<blockquote><p> private void fncInsereTextoEvento(string strTexto)<br />
{</p>
<p>//* Insere o texto na textbox<br />
textBoxEvento.Text += strTexto;</p>
<p>}</p></blockquote>
<p>Crie o envento Click do bot&atilde;o butNaoInteragirThreads, e insira o c&oacute;digo abaixo:</p>
<blockquote><p> private void butNaoInteragirThreads_Click(object sender, EventArgs e)<br />
{</p>
<p>System.Threading.Thread threadMensagem;</p>
<p>System.Threading.ThreadStart threadstartMensagem;</p>
<p>//* Limpa a textbox<br />
textBoxEvento.Text = &#8220;&#8221;;</p>
<p>//* Cria uma nova ThreadStart com o metodo fncInsereMensagemTexto n&atilde;o sincronizado<br />
threadstartMensagem = delegate { fncInsereTextoThread(false); };</p>
<p>//* Instancia a Thread<br />
threadMensagem = new System.Threading.Thread(threadstartMensagem);</p>
<p>//* Inicia a Thread<br />
threadMensagem.Start();</p>
<p>}</p></blockquote>
<p>Crie o evento Click do bot&atilde;o butInteragirThreads, e insira o c&oacute;digo abaixo:</p>
<blockquote><p> private void butInteragirThreads_Click(object sender, EventArgs e)<br />
{</p>
<p>System.Threading.Thread threadMensagem;</p>
<p>System.Threading.ThreadStart threadstartMensagem;</p>
<p>//* Limpa a textbox<br />
textBoxEvento.Text = &#8220;&#8221;;</p>
<p>//* Cria uma nova ThreadStart com o metodo fncInsereMensagemTexto n&atilde;o sincronizado<br />
threadstartMensagem = delegate { fncInsereTextoThread(true); };</p>
<p>//* Instancia a Thread<br />
threadMensagem = new System.Threading.Thread(threadstartMensagem);</p>
<p>//* Inicia a Thread<br />
threadMensagem.Start();</p>
<p>}</p></blockquote>
<p>Nesta segunda parte do exemplo, vamos ver como interagir threads. Criamos uma thread para chamar o m&eacute;todo fncInsereTextoThread que executa um la&ccedil;o, que insere o &iacute;ndice no textBoxEvento. Vamos executar este m&eacute;todo de duas maneiras, uma sem delegate e a outra com delegate.</p>
<p>Ao clicar no bot&atilde;o butNaoInteragirThreads, criamos uma thread que chama o m&eacute;todo fncInsereTextoThread definido pelo par&acirc;metro, para n&atilde;o usar delegate. Sendo assim ocorrer&aacute; um erro, como o textBoxEvento foi instanciado em outra thread ao tentar inserir o texto no textBoxEvento, a thread n&atilde;o consegue modifica-lo.</p>
<p>Para isto precisamos de um delegate, que execute este trabalho, como mostra o butInteragirThreads. Ao clicar no butInteragirThreads, &eacute; passado como par&acirc;metro para o m&eacute;todo fncInsereTextoThread para usar o delegate, sendo assim, quando ele alterar o textBoxEvento, o delegate executa o m&eacute;todo fncInsereTextoEvento no processo onde se encontra o objeto.</p>
<h2>Sincroniza&ccedil;&atilde;o entre Threads</h2>
<p>Finalizando este artigo, vou mostrar como sincronizar duas threads.</p>
<p>No mesmo projeto crie mais dois ButtonBox, o primeiro com o nome butNaoSincronizarThread e defina a propriedade Text para &#8220;N&atilde;o Sincronizar Thread&#8221;, e o segundo para butSincronizarThread e defina a propriedade Text para &#8220;Sincronizar Thread&#8221;.</p>
<p>Crie uma vari&aacute;vel boolean na classe clsfrmPrincipal:</p>
<blockquote><p> private bool blnAguardaThread = false;</p></blockquote>
<p>Crie o m&eacute;todo fncInsereMensagemTextoSincronizado que executa um la&ccedil;o, nele &eacute; chamado o delegate para inserir no textBoxEvento (como mostrado no exemplo anterior) o &iacute;ndice no textBoxEvento:</p>
<blockquote><p> private void fncInsereMensagemTextoSincronizado(long lngIndex, bool blnSincronizar)<br />
{</p>
<p>for (long lngCountMensagem = 0; lngCountMensagem &lt; 10; lngCountMensagem++)<br />
{<br />
//* Bloqueia o bloco atual pela thread<br />
lock (this)<br />
{</p>
<p>//* Verifica se deve executar a sincroniza&ccedil;ao entre thread<br />
if (blnSincronizar == true)<br />
{</p>
<p>System.Threading.Monitor.Pulse(this);</p>
<p>blnAguardaThread = true;</p>
<p>}</p>
<p>//* Insere o texto na textbox<br />
this.Invoke(new delegateInsereTexto(fncInsereTextoEvento), &#8220;Thread &#8221; + lngIndex.ToString() + &#8220;: &#8221; + lngCountMensagem.ToString() + Environment.NewLine);</p>
<p>//* Verifica se deve executar a sincroniza&ccedil;ao entre thread<br />
//* Verifica se deve aguardar outra thread ser executada<br />
if (blnSincronizar == true &amp;&amp; blnAguardaThread == true)<br />
{</p>
<p>blnAguardaThread = false;</p>
<p>//* Aguarda a outra thread terminar<br />
System.Threading.Monitor.Wait(this);</p>
<p>}</p>
<p>}</p>
<p>}</p>
<p>return;</p>
<p>}</p></blockquote>
<p>Crie o evento Click do bot&atilde;o butNaoSincronizarThread, e insira o c&oacute;digo abaixo:</p>
<blockquote><p> private void butNaoSincronizarThread_Click(object sender, EventArgs e)<br />
{</p>
<p>System.Threading.Thread[] arrthreadMensagem;</p>
<p>System.Threading.ThreadStart[] arrthreadstartMensagem;</p>
<p>//* Limpa a textbox<br />
textBoxEvento.Text = &#8220;&#8221;;</p>
<p>//* Redimensiona o array<br />
arrthreadMensagem = new System.Threading.Thread[2];<br />
arrthreadstartMensagem = new System.Threading.ThreadStart[2];</p>
<p>//* Cria uma nova ThreadStart com o metodo fncInsereMensagemTexto n&atilde;o sincronizado<br />
arrthreadstartMensagem[0] = delegate { fncInsereMensagemTextoSincronizado(0,false); };</p>
<p>//* Instancia a Thread<br />
arrthreadMensagem[0] = new System.Threading.Thread(arrthreadstartMensagem[0]);</p>
<p>//* Inicia a Thread<br />
arrthreadMensagem[0].Start();</p>
<p>//* Cria uma nova ThreadStart com o metodo fncInsereMensagemTexto n&atilde;o sincronizado<br />
arrthreadstartMensagem[1] = delegate { fncInsereMensagemTextoSincronizado(1, false); };</p>
<p>//* Instancia a Thread<br />
arrthreadMensagem[1] = new System.Threading.Thread(arrthreadstartMensagem[1]);</p>
<p>//* Inicia a Thread<br />
arrthreadMensagem[1].Start();</p>
<p>return;</p>
<p>}</p></blockquote>
<p>Crie o evento Click do bot&atilde;o butSincronizarThread, e insira o c&oacute;digo abaixo:</p>
<blockquote><p> private void butSincronizarThread_Click(object sender, EventArgs e)<br />
{</p>
<p>System.Threading.Thread[] arrthreadMensagem;</p>
<p>System.Threading.ThreadStart[] arrthreadstartMensagem;</p>
<p>//* Limpa a textbox<br />
textBoxEvento.Text = &#8220;&#8221;;</p>
<p>//* Redimensiona o array<br />
arrthreadMensagem = new System.Threading.Thread[2];<br />
arrthreadstartMensagem = new System.Threading.ThreadStart[2];</p>
<p>//* Cria uma nova ThreadStart com o metodo fncInsereMensagemTexto sicronizado<br />
arrthreadstartMensagem[0] = delegate { fncInsereMensagemTextoSincronizado(0, true); };</p>
<p>//* Instancia a Thread<br />
arrthreadMensagem[0] = new System.Threading.Thread(arrthreadstartMensagem[0]);</p>
<p>//* Cria uma nova ThreadStart com o metodo fncInsereMensagemTexto sincronizado<br />
arrthreadstartMensagem[1] = delegate { fncInsereMensagemTextoSincronizado(1, true); };</p>
<p>//* Instancia a Thread<br />
arrthreadMensagem[1] = new System.Threading.Thread(arrthreadstartMensagem[1]);</p>
<p>//* Inicia a Thread<br />
arrthreadMensagem[0].Start();</p>
<p>//* Inicia a Thread<br />
arrthreadMensagem[1].Start();</p>
<p>return;</p>
<p>}</p></blockquote>
<p>E finalizando o artigo, vamos ver como criamos uma sincroniza&ccedil;&atilde;o entre threads.</p>
<p>Ao clicar no bot&atilde;o butNaoSincronizarThread, criamos um array de threads, e redimensionamos ele para 2 itens. Cada item executa o m&eacute;todo fncInsereMensagemTextoSincronizado, passando como par&acirc;metro a index do item, e um valor boolean para n&atilde;o sincronizar as threads. Ao executar o m&eacute;todo fncInsereMensagemTextoSincronizado executamos um la&ccedil;o onde inserimos no textBoxEvento a index da thread e o &iacute;ndice do la&ccedil;o apontado por lngCountMensagem. Como n&atilde;o sincronizamos as threads, os itens no textBoxEvento aparassem embaralhados n&atilde;o respeitando uma seq&uuml;&ecirc;ncia, de qual thread vai inserir.</p>
<p>Ao clicar no bot&atilde;o butSincronizarThread, executamos quase a mesma fun&ccedil;&atilde;o do bot&atilde;o butNaoSincronizarThread com a diferen&ccedil;a que, enquanto uma thread est&aacute; sendo executada, esperamos ela terminar, e ent&atilde;o executamos a outra, sendo assim, mantendo uma sincroniza&ccedil;&atilde;o entre elas. Para isto usamos o m&eacute;todo System.Threading.Monitor.Wait para entrar na fila das thread a serem executadas, e System.Threading.Monitor.Pulse para informar a fila que o objeto esta desbloqueado, e assim poder executar a pr&oacute;xima thread que est&aacute; aguardando.</p>
<h2>Download do Exemplo</h2>
<p>E por ultimo, mas n&atilde;o menos importante, o link para download do exemplo:  <a href="http://www.fdweb.com.br/downloads/csharpmultithreadexemplo.zip" target="_blank">http://www.fdweb.com.br/downloads/csharpmultithreadexemplo.zip</a></p><p>Confira ofertas de: <a href="http://centenaro.org/submarino/?pal=DVD" rel="external" target="_Blank">DVD</a>, <a href="http://centenaro.org/submarino/?pal=filmes" rel="external" target="_Blank">filmes</a>, <a href="http://centenaro.org/submarino/?pal=celular" rel="external" target="_Blank">celular</a>, <a href="http://centenaro.org/submarino/?pal=notebook" rel="external" target="_Blank">notebook</a>, <a href="http://centenaro.org/submarino/?pal=livros" rel="external" target="_Blank">livros</a>, <a href="http://centenaro.org/submarino/?pal=jogos" rel="external" target="_Blank">jogos</a>, <a href="http://centenaro.org/submarino/?pal=Wii" rel="external" target="_Blank">Wii</a>, <a href="http://centenaro.org/submarino/?pal=PS3" rel="external" target="_Blank">PS3</a>, <a href="http://centenaro.org/submarino/?pal=MP4" rel="external" target="_Blank">MP4</a></p><p>a</p>
<p><a href="http://fdweb.com.br/trabalhando-com-multithread-no-c/">Trabalhando com multithread no C#</a></p>
]]></content:encoded>
			<wfw:commentRss>http://fdweb.com.br/trabalhando-com-multithread-no-c/feed/</wfw:commentRss>
		<feedburner:origLink>http://fdweb.com.br/trabalhando-com-multithread-no-c/</feedburner:origLink></item>
		<item>
		<title>Curso gratuito de PHP em Português</title>
		<link>http://feeds.feedburner.com/~r/fdweb/~3/181848071/</link>
		<comments>http://fdweb.com.br/curso-gratuito-de-php-em-portugues/#comments</comments>
		<pubDate>Thu, 08 Nov 2007 21:34:48 +0000</pubDate>
		<dc:creator>Fabio Centenaro</dc:creator>
		
		<category><![CDATA[Geral]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Programação]]></category>

		<category><![CDATA[curso]]></category>

		<category><![CDATA[gratuito]]></category>

		<category><![CDATA[portugues]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://fdweb.com.br/curso-gratuito-de-php-em-portugues/</guid>
		<description><![CDATA[Um dos assuntos que mais tem estado em pauta aqui no blog &#233; a linguagem PHP. E dessa vez n&#227;o vai ser diferente. Na comunidade PHP Brasil no Orkut foi divulgado um curso de PHP em portugu&#234;s. Ele consiste de v&#237;deo aulas abordando o b&#225;sico da linguagem, desde como criar um script mais simples - [...]]]></description>
			<content:encoded><![CDATA[<p>Um dos assuntos que mais tem estado em pauta aqui no blog &eacute; a linguagem PHP. E dessa vez n&atilde;o vai ser diferente. Na comunidade <a href="http://www.orkut.com/Community.aspx?cmm=19610" title="PHP Brasil - Orkut" target="_blank">PHP Brasil</a> no Orkut foi divulgado um curso de PHP em portugu&ecirc;s. Ele consiste de v&iacute;deo aulas abordando o b&aacute;sico da linguagem, desde como criar um script mais simples - o famoso <em>Hello World - </em>at&eacute; fun&ccedil;&otilde;es para trabalhar com arrays e enviar e-mails.</p>
<p>De cara  admito que n&atilde;o &eacute; o melhor curso j&aacute; feito, mas pela simplicidade e principalmente pelo fato de ser totalmente em <strong>portugu&ecirc;s </strong>e <strong>gratuito</strong>, o curso de PHP j&aacute; vale o download.</p>
<p>Falando em  download, fa&ccedil;a o download do curso de PHP em portugu&ecirc;s no link abaixo:<br />
<a href="http://rapidshare.com/files/34095879/curso_php.rar" title="Curso de PHP em Portugu&ecirc;s" target="_blank">http://rapidshare.com/files/34095879/curso_php.rar</a></p><p>Confira ofertas de: <a href="http://centenaro.org/submarino/?pal=DVD" rel="external" target="_Blank">DVD</a>, <a href="http://centenaro.org/submarino/?pal=filmes" rel="external" target="_Blank">filmes</a>, <a href="http://centenaro.org/submarino/?pal=celular" rel="external" target="_Blank">celular</a>, <a href="http://centenaro.org/submarino/?pal=notebook" rel="external" target="_Blank">notebook</a>, <a href="http://centenaro.org/submarino/?pal=livros" rel="external" target="_Blank">livros</a>, <a href="http://centenaro.org/submarino/?pal=jogos" rel="external" target="_Blank">jogos</a>, <a href="http://centenaro.org/submarino/?pal=Wii" rel="external" target="_Blank">Wii</a>, <a href="http://centenaro.org/submarino/?pal=PS3" rel="external" target="_Blank">PS3</a>, <a href="http://centenaro.org/submarino/?pal=MP4" rel="external" target="_Blank">MP4</a></p><p>a</p>
<p><a href="http://fdweb.com.br/curso-gratuito-de-php-em-portugues/">Curso gratuito de PHP em Portugu&ecirc;s</a></p>
]]></content:encoded>
			<wfw:commentRss>http://fdweb.com.br/curso-gratuito-de-php-em-portugues/feed/</wfw:commentRss>
		<feedburner:origLink>http://fdweb.com.br/curso-gratuito-de-php-em-portugues/</feedburner:origLink></item>
	<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetFeedData?uri=fdweb</feedburner:awareness></channel>
</rss>
