<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>GSaraiva&#039;s Projects &#187; Message</title>
	<atom:link href="http://projects.pro.br/gsaraiva/tag/message/feed/" rel="self" type="application/rss+xml" />
	<link>http://projects.pro.br/gsaraiva</link>
	<description>Step by step</description>
	<lastBuildDate>Tue, 01 Sep 2009 13:14:24 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Delphi: SetTimer</title>
		<link>http://projects.pro.br/gsaraiva/2008/05/delphi-settimer/</link>
		<comments>http://projects.pro.br/gsaraiva/2008/05/delphi-settimer/#comments</comments>
		<pubDate>Wed, 21 May 2008 15:45:35 +0000</pubDate>
		<dc:creator>Gilberto Saraiva</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[AllocateHWnd]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[DeallocateHWnd]]></category>
		<category><![CDATA[Handle]]></category>
		<category><![CDATA[HandleMessage]]></category>
		<category><![CDATA[KillTimer]]></category>
		<category><![CDATA[Message]]></category>
		<category><![CDATA[Objeto Windows]]></category>
		<category><![CDATA[ProcessMessages]]></category>
		<category><![CDATA[SetTimer]]></category>
		<category><![CDATA[TApplication]]></category>
		<category><![CDATA[Temporizador]]></category>
		<category><![CDATA[Timer]]></category>
		<category><![CDATA[VCL]]></category>
		<category><![CDATA[WM_TIMER]]></category>

		<guid isPermaLink="false">http://gsaraiva.projects.pro.br/?p=41</guid>
		<description><![CDATA[Camaradas,
O SetTimer é uma função disponibilizada pela plataforma Windows ( API ) que consiste em criar um Temporizador que notifica um Objeto Windows ( Handle ) sempre que atingir o términio do tempo estipulado. Um temporizador desse tipo é gerenciado pelo Windows, ou seja, não será relacionado com o processamento do seu aplicativo, ficando assim [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Camaradas,</strong></p>
<p>O SetTimer é uma função disponibilizada pela plataforma Windows ( API ) que consiste em criar um Temporizador que notifica um Objeto Windows ( Handle ) sempre que atingir o términio do tempo estipulado. Um temporizador desse tipo é gerenciado pelo Windows, ou seja, não será relacionado com o processamento do seu aplicativo, ficando assim com uma precisão boa mesmo enquanto seu aplicativo processa alguma coisa.</p>
<p>Um detalhe muito importante sobre o processamento da notificação do temporizador ( Timer ), é que como a notificação padrão é feita via mensagem, a WM_TIMER, e mensagens são administradas pela VCL através do Objeto TApplication application, em 2 respectivos locais, o primeiro em ProcessMessages que processa a fila inteira de mensagens que a aplicação possuí, e o segundo HandleMessage que processa apenas a primeira mensagem da fila, se existir alguma, sinaliza o <strong>Evento OnIde</strong> e aguarda uma nova mensagem (em caso de fila a liberação é instantanea), você podera perder a precisão do temporizador por falta de manipulação da recepção de mensagens. Já vi muita gente reclamando a precisão do SetTimer na utilização dentro de um aplicativo Delphi, mas nunca vi essa reclamação de um programador C, pois o mesmo tem o trabalho de gerênciar as notificações para o objeto receptor.</p>
<p>Então o fato é, temporizadores não são ruins, são ótimas opções para criação de simuladores de interação, Inteligências artificiais em alguns pontos, e até mesmo para criação de cronometros e agendamentos.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li><span style="color: #008000; font-style: italic;">{$EXTERNALSYM SetTimer}</span></li><li><span style="color: #000000; font-weight: bold;">function</span> SetTimer<span style="color: #000066;">&#40;</span>hWnd<span style="color: #000066;">:</span> HWND<span style="color: #000066;">;</span> nIDEvent<span style="color: #000066;">,</span> uElapse<span style="color: #000066;">:</span> UINT<span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;lpTimerFunc<span style="color: #000066;">:</span> TFNTimerProc<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> UINT<span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">stdcall</span><span style="color: #000066;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--><br />
O 1º parametro é referente ao Objeto Windows ( Handle ) receptor, qualquer objeto com Handle ( Objeto Windows ).<br />
O 2º parametro é referente ao índice controlado pelo programador, servirá como identificador na hora do processamento da notificação WM_TIMER.<br />
O 3º parametro indica o intervalo, em milisegundos, em que o temporizador notificará o objeto.<br />
O 4º parametro é nosso cargo chefe, deve ser analizado como primeira opção sempre pois utilizando este parametro deixaremos a necessidade de utilizar a VCL ou qualquer ou controle de Objetos Windows para a recepção da notificação.</p>
<p>Chegando neste ponto, podemos perceber que possuímos 2 caminhos, o primerio através de um Objeto Windows e o outro através de um Callback, a escolha é você quem faz na hora da utilização, vou exemplificar as duas maneiras de utilização, então preste atenção, pois é bastante interessante <img src='http://projects.pro.br/gsaraiva/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  .</p>
<h6>Como utilizar um temporizador através de um Objeto Windows?</h6>
<p>Para facilitar o entendimento e não aprofundar muito em matérias que não são a questão do artigo, vamos utilizar a VCL para administrar nosso Objeto Windows.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li></li><li>&nbsp;&nbsp;TfrmTest <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #000066;">&#40;</span>TForm<span style="color: #000066;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;btnStart<span style="color: #000066;">:</span> TButton<span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">procedure</span> btnStartClick<span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">private</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080; font-style: italic;">{ Private declarations }</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">procedure</span> WMTimer<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> Msg<span style="color: #000066;">:</span> TWMTimer<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> message WM_TIMER<span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li></li></ol></div></pre><!--END_DEVFMTCODE--><br />
Declaramos o a manipulação da mensagem WM_TIMER para o nosso &#8220;TForm&#8221; frmTest. No frmTest colocamos também um TButton btnStart para criamos o temporizador através de seu evento OnClick.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">procedure</span> TfrmTest<span style="color: #000066;">.</span><span style="color: #006600;">btnStartClick</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">begin</span></li><li>&nbsp;&nbsp;SetTimer<span style="color: #000066;">&#40;</span>Handle<span style="color: #000066;">,</span> 0<span style="color: #000066;">,</span> 1000<span style="color: #000066;">,</span> <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--><br />
Este é o evento OnClick do TButton btnStart. Entendendo melhor o que acontece aqui:</p>
<dl>
<li><strong>Handle</strong> é o Handle do frmTest, como é Handle é Objeto Windows e pode receber mensagens.</li>
<li><strong>0</strong> é o índice que eu informei para o temporizador, então sempre que eu receber um WM_TIMER vou verificar qual índice ele contém e poder estruturar tarefas em cima disso.</li>
<li><strong>1000</strong> é o intervalo em milisegundos que o temporizador irá me notificar no Handle do frmTest. 1000 milisegundos = 1 segundo, logo 60000 milisegundos = 1 minuto.
<li><strong>nil</strong> é indicado como NIL pois queremos interagir com a mensagem através de mensagens.</li>
</dl>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li></li><li><span style="color: #000000; font-weight: bold;">procedure</span> TfrmTest<span style="color: #000066;">.</span><span style="color: #006600;">WMTimer</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> Msg<span style="color: #000066;">:</span> TWMTimer<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">begin</span></li><li>&nbsp;&nbsp;KillTimer<span style="color: #000066;">&#40;</span>Handle<span style="color: #000066;">,</span> Msg<span style="color: #000066;">.</span><span style="color: #006600;">TimerID</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;ShowMessage<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Evento do temporizador: '</span> <span style="color: #000066;">+</span> <span style="color: #000066;">IntToStr</span><span style="color: #000066;">&#40;</span>Msg<span style="color: #000066;">.</span><span style="color: #006600;">TimerID</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--><br />
Este procedimento é a parte fundamental no funcionamento de um temporizador via Objeto Windows. Perceba que já aparece uma nova função, a KillTimer, que nada mais é que a contra-API da SetTimer, ou seja, cria o temporizador com SetTimer, e destroí o mesmo com KillTimer.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li><span style="color: #008000; font-style: italic;">{$EXTERNALSYM KillTimer}</span></li><li><span style="color: #000000; font-weight: bold;">function</span> KillTimer<span style="color: #000066;">&#40;</span>hWnd<span style="color: #000066;">:</span> HWND<span style="color: #000066;">;</span> uIDEvent<span style="color: #000066;">:</span> UINT<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">BOOL</span><span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">stdcall</span><span style="color: #000066;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--><br />
O 1º parametro é o Objeto Windows que recebe a notificação do temporizador, tem que ser igual ao que foi utilizado no SetTimer.<br />
O 2º parametro é o índice criado pelo programador, tem que ser igual ao que foi utilizado no SetTimer.</p>
<p>Pois bem, já vimos que a utilização do temporizador através da VCL é fácil, e pode se extender a um universo infinito de possibilidades. Vou mostrar um exemplo prático:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li></li><li><span style="color: #000000; font-weight: bold;">type</span></li><li>&nbsp;&nbsp;PTimerParam <span style="color: #000066;">=</span> <span style="color: #000066;">^</span>TTimerParam<span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;TTimerParam <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">record</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;s<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;i<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">integer</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">procedure</span> TfrmTest<span style="color: #000066;">.</span><span style="color: #006600;">btnStartClick</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">var</span></li><li>&nbsp;&nbsp;Param<span style="color: #000066;">:</span> PTimerParam<span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">begin</span></li><li>&nbsp;&nbsp;<span style="color: #000066;">New</span><span style="color: #000066;">&#40;</span>Param<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;Param<span style="color: #000066;">^</span><span style="color: #000066;">.</span><span style="color: #006600;">s</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">'Teste de título animado'</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;Param<span style="color: #000066;">^</span><span style="color: #000066;">.</span><span style="color: #006600;">i</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;SetTimer<span style="color: #000066;">&#40;</span>Handle<span style="color: #000066;">,</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">&#40;</span>Param<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> 100<span style="color: #000066;">,</span> <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">procedure</span> TfrmTest<span style="color: #000066;">.</span><span style="color: #006600;">WMTimer</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> Msg<span style="color: #000066;">:</span> TWMTimer<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">begin</span></li><li>&nbsp;&nbsp;KillTimer<span style="color: #000066;">&#40;</span>Handle<span style="color: #000066;">,</span> Msg<span style="color: #000066;">.</span><span style="color: #006600;">TimerID</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">with</span> PTimerParam<span style="color: #000066;">&#40;</span>Msg<span style="color: #000066;">.</span><span style="color: #006600;">TimerID</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">^</span> <span style="color: #000000; font-weight: bold;">do</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">begin</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;Caption <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Copy</span><span style="color: #000066;">&#40;</span>s<span style="color: #000066;">,</span> 1<span style="color: #000066;">,</span> i<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;i <span style="color: #000066;">:</span><span style="color: #000066;">=</span> i <span style="color: #000066;">+</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">if</span> i &lt;<span style="color: #000066;">=</span> <span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>s<span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">then</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetTimer<span style="color: #000066;">&#40;</span>Handle<span style="color: #000066;">,</span> Msg<span style="color: #000066;">.</span><span style="color: #006600;">TimerID</span><span style="color: #000066;">,</span> 100<span style="color: #000066;">,</span> <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">else</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000066;">Dispose</span><span style="color: #000066;">&#40;</span><span style="color: #000066; font-weight: bold;">Pointer</span><span style="color: #000066;">&#40;</span>Msg<span style="color: #000066;">.</span><span style="color: #006600;">TimerID</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Agora a segunda parte da história:</p>
<h6>Como utilizar um temporizador através de um Callback?</h6>
<p>Primeiramente, a utilização do SetTimer por Callback é mais eficiente em relação ao processo via Objeto Windows, pois não há dependência de objeto para que o reconhecimento da notificação do temporizador seja feita em relação a aplicação, pois o callback será chamado internamente pela DefWindowProc.</p>
<p>Então vamos entender como declarar um procedimento no padrão do Callback TimerProc:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="C"><div class="devcodeoverflow"><ol><li></li><li>VOID CALLBACK TimerProc<span style="color: #009900;">&#40;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;HWND hwnd<span style="color: #339933;">,</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;UINT uMsg<span style="color: #339933;">,</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;UINT_PTR idEvent<span style="color: #339933;">,</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwTime</li><li><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--><br />
Esse modelo traduzido para Delphi:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">procedure</span> TimerProc<span style="color: #000066;">&#40;</span>hwnd<span style="color: #000066;">:</span> HWND<span style="color: #000066;">;</span> uMsg<span style="color: #000066;">,</span> idEvent<span style="color: #000066;">:</span> UINT<span style="color: #000066;">;</span> dwTime<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">DWORD</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">stdcall</span><span style="color: #000066;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Então após entendermos a estrutura do último parametro do SetTimer podemos escrever um exemplo prático de resultado semelhante ao exemplo anterior:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li></li><li><span style="color: #000000; font-weight: bold;">type</span></li><li>&nbsp;&nbsp;PTimerParam <span style="color: #000066;">=</span> <span style="color: #000066;">^</span>TTimerParam<span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;TTimerParam <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">record</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;s<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;i<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">integer</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">procedure</span> TimerProc<span style="color: #000066;">&#40;</span>hwnd<span style="color: #000066;">:</span> HWND<span style="color: #000066;">;</span> uMsg<span style="color: #000066;">,</span> idEvent<span style="color: #000066;">:</span> UINT<span style="color: #000066;">;</span> dwTime<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">DWORD</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">stdcall</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">begin</span></li><li>&nbsp;&nbsp;KillTimer<span style="color: #000066;">&#40;</span>hwnd<span style="color: #000066;">,</span> idEvent<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">with</span> PTimerParam<span style="color: #000066;">&#40;</span>idEvent<span style="color: #000066;">&#41;</span><span style="color: #000066;">^</span> <span style="color: #000000; font-weight: bold;">do</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">begin</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;frmMain<span style="color: #000066;">.</span><span style="color: #006600;">Caption</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Copy</span><span style="color: #000066;">&#40;</span>s<span style="color: #000066;">,</span> 1<span style="color: #000066;">,</span> i<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;i <span style="color: #000066;">:</span><span style="color: #000066;">=</span> i <span style="color: #000066;">+</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">if</span> i &lt;<span style="color: #000066;">=</span> <span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>s<span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">then</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetTimer<span style="color: #000066;">&#40;</span>hwnd<span style="color: #000066;">,</span> idEvent<span style="color: #000066;">,</span> 100<span style="color: #000066;">,</span> <span style="color: #000066;">@</span>TimerProc<span style="color: #000066;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">else</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">begin</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000066;">Dispose</span><span style="color: #000066;">&#40;</span><span style="color: #000066; font-weight: bold;">Pointer</span><span style="color: #000066;">&#40;</span>idEvent<span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000066;">DeallocateHWnd</span><span style="color: #000066;">&#40;</span>hwnd<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">procedure</span> TfrmMain<span style="color: #000066;">.</span><span style="color: #006600;">btnRunClick</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">var</span></li><li>&nbsp;&nbsp;Param<span style="color: #000066;">:</span> PTimerParam<span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">begin</span></li><li>&nbsp;&nbsp;<span style="color: #000066;">New</span><span style="color: #000066;">&#40;</span>Param<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;Param<span style="color: #000066;">^</span><span style="color: #000066;">.</span><span style="color: #006600;">s</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">'Teste de título animado'</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;Param<span style="color: #000066;">^</span><span style="color: #000066;">.</span><span style="color: #006600;">i</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;SetTimer<span style="color: #000066;">&#40;</span><span style="color: #000066;">AllocateHWnd</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">&#40;</span>Param<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> 100<span style="color: #000066;">,</span> <span style="color: #000066;">@</span>TimerProc<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li></li></ol></div></pre><!--END_DEVFMTCODE--><br />
Antes de analizar o código vou citar um detalhe importante:</p>
<blockquote><p>Veja que ao chamar o SetTimer eu utilizo o AllocateHWnd como primeiro parametro, o porquê disso é que o SetTimer opera de maneira diferente ao se indicar um Objeto Windows que não pertence à aplicação, a definição é a seguinte:<br />
Caso o Handle passado como parametro pertença a aplicação, mais especificamente a mesma Thread que chama a SetTimer. No caso do Handle ser igual a 0 ( zero ) ou não pertencer a aplicação, o parametro passado como índice do temporizador será ignorado e um novo índice será criado e o retorno da chamada ao SetTimer indicará o novo índice.
</p></blockquote>
<p>Depois de entender esse detalhe importante podemos perceber porque fazemos a criação de um Objeto Windows utilizando o AllocateHWnd. A finalidade disso é não passar um Objeto Windows inválido e ter o índice, que no nosso caso indica um ponteiro que serve de parametro, resetado.</p>
<p>Agora entendendo um pouco o código:</p>
<p>Perceba que sempre que recebemos a notificação de términio do intervalo do temporizador, finalizamos o temporizador, e porque fazemos isso? Fazemos isso pois se dentro da notificação, seja na utilização do callback ou por mensagem ( WM_Timer ), o processo que escrevermos lá demorar mais do que o intervalo, criaremos uma fila de processamento, e que acaba por criar uma sequência de processamento e o efeito de execução por intervalo não será perceptível.</p>
<p>Fluxograma para entendimento rápido:<br />
<a href='http://gsaraiva.projects.pro.br/wp-content/uploads/2008/05/timerflux.png'><img src="http://gsaraiva.projects.pro.br/wp-content/uploads/2008/05/timerflux.png" alt="" title="timerflux" width="197" height="190"/></a></p>
<p><strong>Qualquer dúvida fique avontade em perguntar!</strong></p>
<p>Abraço a todos</p>
]]></content:encoded>
			<wfw:commentRss>http://projects.pro.br/gsaraiva/2008/05/delphi-settimer/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Delphi: RegisterHotkey</title>
		<link>http://projects.pro.br/gsaraiva/2008/05/delphi-registerhotkey/</link>
		<comments>http://projects.pro.br/gsaraiva/2008/05/delphi-registerhotkey/#comments</comments>
		<pubDate>Tue, 20 May 2008 01:33:22 +0000</pubDate>
		<dc:creator>Gilberto Saraiva</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[HotKey]]></category>
		<category><![CDATA[Message]]></category>
		<category><![CDATA[RegisterHotkey]]></category>
		<category><![CDATA[UnRegisterHotkey]]></category>

		<guid isPermaLink="false">http://gsaraiva.projects.pro.br/?p=29</guid>
		<description><![CDATA[Camaradas,
O RegisterHotkey e uma função disponibilizada pela plataforma Windows ( API ) que cria uma interação com o objeto passado como parametro no momento que o usuário faz uma combinação de teclas, exemplo: CTRL+X. Resumindo, ele registra um objeto para ser notificado quando uma combinação de teclas é acionada.
{$EXTERNALSYM RegisterHotKey}function RegisterHotKey&#40;hWnd: HWND; id: Integer; fsModifiers, [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Camaradas,</strong></p>
<p>O RegisterHotkey e uma função disponibilizada pela plataforma Windows ( API ) que cria uma interação com o objeto passado como parametro no momento que o usuário faz uma combinação de teclas, exemplo: <strong>CTRL+X</strong>. Resumindo, ele registra um objeto para ser notificado quando uma combinação de teclas é acionada.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li><span style="color: #008000; font-style: italic;">{$EXTERNALSYM RegisterHotKey}</span></li><li><span style="color: #000000; font-weight: bold;">function</span> RegisterHotKey<span style="color: #000066;">&#40;</span>hWnd<span style="color: #000066;">:</span> HWND<span style="color: #000066;">;</span> id<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span> fsModifiers<span style="color: #000066;">,</span> vk<span style="color: #000066;">:</span> UINT<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">BOOL</span><span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">stdcall</span><span style="color: #000066;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--><br />
O 1º parametro é o Handle do objeto que receberá a notificação quando a combinação de teclas selecionada for feita.<br />
O 2º parametro é um indice controlado pelo programador afim de possibilitar mais de um registro de combinação de teclas.<br />
O 3º e o 4º parametro são aonde o programador passa qual a combinação de teclas ele quer monitorar.</p>
<p>Exemplo:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li></li><li>&nbsp;&nbsp;RegisterHotkey<span style="color: #000066;">&#40;</span>form1<span style="color: #000066;">.</span><span style="color: #006600;">Handle</span><span style="color: #000066;">,</span> 1<span style="color: #000066;">,</span> MOD_CONTROL <span style="color: #000000; font-weight: bold;">or</span> MOD_SHIFT<span style="color: #000066;">,</span> <span style="color: #000066; font-weight: bold;">Byte</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">Ord</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Q'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;RegisterHotkey<span style="color: #000066;">&#40;</span>form1<span style="color: #000066;">.</span><span style="color: #006600;">Handle</span><span style="color: #000066;">,</span> 2<span style="color: #000066;">,</span> MOD_CONTROL <span style="color: #000000; font-weight: bold;">or</span> MOD_SHIFT<span style="color: #000066;">,</span> <span style="color: #000066; font-weight: bold;">Byte</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">Ord</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'A'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li></li></ol></div></pre><!--END_DEVFMTCODE--><br />
Aqui eu registro para o TForm form1 o recebimento da notificação no caso de <strong>CTRL+SHIFT+Q</strong> e <strong>CTRL+SHIFT+A</strong>.</p>
<p>Mas ainda falta uma coisa, como já sabemos objetos Windows são notificados através de mensagens ( Message ) então temos que gerenciar a mensagem certa que o Windows utiliza para notificar o objeto quando a combinação de teclas é feita. Essa mensagem é a WM_HOTKEY, uma mensagem que o Delphi já mapeia para você como TWMHotKey, então é só escrever o seguinte código para gerenciar as notificações:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li></li><li><span style="color: #000000; font-weight: bold;">type</span></li><li>&nbsp;&nbsp;TForm1 <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #000066;">&#40;</span>TForm<span style="color: #000066;">&#41;</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">private</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080; font-style: italic;">{ Private declarations }</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">procedure</span> WMHotKey<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> Msg<span style="color: #000066;">:</span> TWMHotKey<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> message WM_HOTKEY<span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li></li></ol></div></pre><!--END_DEVFMTCODE--><br />
E no procedimento separa através da propriedade HotKey da <strong>var Msg</strong></p>
<p>Exemplo:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">procedure</span> TForm1<span style="color: #000066;">.</span><span style="color: #006600;">WMHotKey</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> Msg<span style="color: #000066;">:</span> TWMHotKey<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">begin</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">case</span> Msg<span style="color: #000066;">.</span><span style="color: #006600;">HotKey</span> <span style="color: #000000; font-weight: bold;">of</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;1<span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">begin</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080; font-style: italic;">// Aqui eu recebi CTRL+SHIFT+Q</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;2<span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">begin</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080; font-style: italic;">// Aqui eu recebi CTRL+SHIFT+A</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li><li><span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>É muito simples a utilização da API RegisterHotkey, outra parte interessante é a possibilidade de desregistrar a notificação, através da contra-API UnRegisterHotkey.<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li><span style="color: #008000; font-style: italic;">{$EXTERNALSYM UnregisterHotKey}</span></li><li><span style="color: #000000; font-weight: bold;">function</span> UnregisterHotKey<span style="color: #000066;">&#40;</span>hWnd<span style="color: #000066;">:</span> HWND<span style="color: #000066;">;</span> id<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">BOOL</span><span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">stdcall</span><span style="color: #000066;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Baseando no nosso exemplo, desregistramos as 2 notificações assim:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li></li><li>&nbsp;&nbsp;UnRegisterHotkey<span style="color: #000066;">&#40;</span>Handle<span style="color: #000066;">,</span> 1<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li>&nbsp;&nbsp;UnRegisterHotkey<span style="color: #000066;">&#40;</span>Handle<span style="color: #000066;">,</span> 2<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li><li></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Simples não é?<br />
Qualquer dúvida fique avontade em perguntar.</p>
<p>Abraço a todos</p>
]]></content:encoded>
			<wfw:commentRss>http://projects.pro.br/gsaraiva/2008/05/delphi-registerhotkey/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Delphi: SendMessage</title>
		<link>http://projects.pro.br/gsaraiva/2008/05/delphi-sendmessage/</link>
		<comments>http://projects.pro.br/gsaraiva/2008/05/delphi-sendmessage/#comments</comments>
		<pubDate>Tue, 20 May 2008 01:01:07 +0000</pubDate>
		<dc:creator>Gilberto Saraiva</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[BN_CLICKED]]></category>
		<category><![CDATA[CN_COMMAND]]></category>
		<category><![CDATA[Handle]]></category>
		<category><![CDATA[HFILE]]></category>
		<category><![CDATA[HGLOBAL]]></category>
		<category><![CDATA[HHOOK]]></category>
		<category><![CDATA[HINST]]></category>
		<category><![CDATA[HLOCAL]]></category>
		<category><![CDATA[HMENU]]></category>
		<category><![CDATA[HWND]]></category>
		<category><![CDATA[Message]]></category>
		<category><![CDATA[SendMessage]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[WM_SETTEXT]]></category>

		<guid isPermaLink="false">http://gsaraiva.projects.pro.br/?p=28</guid>
		<description><![CDATA[Camaradas,
O SendMessage é uma função disponibilizada pela plataforma windows (API) que nos permite interagir sobre objetos Window, ou seja, todos os objetos que possuem Handle, seja esse handle de qual tipo for: HWND, HFILE, HMENU, HHOOK, HGLOBAL, HLOCAL, HINST e outros vários. Diante isso podemos entender que o acesso a certos objetos pode ser feito [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Camaradas,</strong></p>
<p>O SendMessage é uma função disponibilizada pela plataforma windows (API) que nos permite interagir sobre objetos Window, ou seja, todos os objetos que possuem Handle, seja esse handle de qual tipo for: HWND, HFILE, HMENU, HHOOK, HGLOBAL, HLOCAL, HINST e outros vários. Diante isso podemos entender que o acesso a certos objetos pode ser feito através da utilização dessa API. </p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li><span style="color: #008000; font-style: italic;">{$EXTERNALSYM SendMessage}</span></li><li><span style="color: #000000; font-weight: bold;">function</span> SendMessage<span style="color: #000066;">&#40;</span>hWnd<span style="color: #000066;">:</span> HWND<span style="color: #000066;">;</span> Msg<span style="color: #000066;">:</span> UINT<span style="color: #000066;">;</span> wParam<span style="color: #000066;">:</span> WPARAM<span style="color: #000066;">;</span> lParam<span style="color: #000066;">:</span> LPARAM<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> LRESULT<span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">stdcall</span><span style="color: #000066;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--><br />
Basicamente o SendMessage necessita apenas do Handle e da Mensagem ( Message ), os outros 2 parametros serão dependentes da Mensagem enviada.</p>
<p>Um exemplo:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li>&nbsp;&nbsp;SendMessage<span style="color: #000066;">&#40;</span>btn2<span style="color: #000066;">.</span><span style="color: #006600;">Handle</span><span style="color: #000066;">,</span> CN_COMMAND<span style="color: #000066;">,</span> BN_CLICKED<span style="color: #000066;">,</span> 0<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--><br />
Envia uma mensagem do tipo CN_COMMAND para o btn2 (no nosso caso esse é um TButton) com o parametro BN_CLICKED que faz o TButton btn2 entender que se deve executar o procedimento de click.</p>
<p>Outro exemplo interessante:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="Delphi"><div class="devcodeoverflow"><ol><li>&nbsp;&nbsp;SendMessage<span style="color: #000066;">&#40;</span>form1<span style="color: #000066;">.</span><span style="color: #006600;">Handle</span><span style="color: #000066;">,</span> WM_SETTEXT<span style="color: #000066;">,</span> 0<span style="color: #000066;">,</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">&#40;</span><span style="color: #000066; font-weight: bold;">PChar</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Novo Título'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--><br />
O código acima modifica o título do TForm form1 para o valor &#8220;Novo Título&#8221;.</p>
<p>A infinidade de coisas que dá pra se fazer com essa pequena API é incalculável.<br />
Se quiser ver como é vasta a capacidade proponha-me um problema! Eu ficarei grato pelo desafio.</p>
<p>Abraço a todos</p>
]]></content:encoded>
			<wfw:commentRss>http://projects.pro.br/gsaraiva/2008/05/delphi-sendmessage/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
