sexta-feira, 13 de março de 2009

Exibir imagem no fundo do Form

Igual a Web, colocar uma imagem ao fundo de um formulário, só que em Win32, já pensou em fazer isso? Bom, é bastante simples fazer com que seu sistema carregue uma imagem com extensão *.bmp e escreva esta imagem no form, usando o objeto Canvas do formulário, sem usar nenhum componente de imagem. Crie um novo projeto e adicione a ele um Button e um OpenDialog da paleta Dialogs, e já no código declare a seguinte função:
Procedure TForm1.ImgFundoForm(CaminhoBMP:String; DistH, DistV:Integer); Var Imagem :TBitMap; begin Imagem := TBitMap.Create; Try Imagem.LoadFromFile(CaminhoBMP); Canvas.Draw(DistH,DistV,Imagem); Except On e: Exception do ShowMessage('Problemas ao escrever imagem:'+#13+e.message); end; end;

Essa função fará com que seja criado, em runtime um objeto BitMap que por sua vez carregará a imagem bmp a partir do caminho informado. Já na linha seguinte, utilizando o Canvas escrevemos a imagem no form definindo as cordenadas para que a mesma seja exibida.

Para que a imagem seja de fato carregada, adicione ao evento OnClick do Button a seguinte linha de código, responsável pela configuração do OpenDialog, localização da imagem e execução da função.
Pronto, agora você poderá personalizar os formulários do seu sistema aplicando a eles imagens de fundo. Abraço e até a próxima...

quinta-feira, 12 de março de 2009

Tradução de palavras, frases, textos no MSN

Sim, exatamente isso que você leu, agora no MSN você pode traduzir palavras, frases, textos, e o melhor, são 14 idiomas diferente que você poderá escolher. A ferramenta trata-se de uma integração anunciada pela Microsoft entre as ferramentas Windows Live Translator e a ferramenta de comunicação instantânea MSN.

Para iniciar suas traduções, basta que adicione o contato mtbot@hotmail.com à sua lista de contatos e inicie uma conversa. Trata-se de um robô que lhe fará uma simpática apresentação e oferecerá seus recursos de ajuda. A listagem de comandos poderá ser feita ao digitar "TBot ?", onde obterá a seguinte lista:

1 TBot lang - Mostrar línguas de tradução
2 TBot change - Selecionar línguas de tradução

3 TBot stop - Desligar o tradutor

4 TBot start - Ligar o tradutor novamente

5 TBot set - Selecionar sua língua preferida
6 TBot ? - Listar os comandos


Os idiomas de tradução disponíveis são:

1 Alemão

2 Chinês simplificado

3 Chinês tradicional

4 Coreano

5 Espanhol
6 Francês

7 Holandês

8 Inglês
9 Italiano

10 Japonês
11 Polonês

12 Português

13 Russo
14 Árabe


Bom, agora para qualquer dúvida de tradução, converse com o TBot, o seu robô tradutor.

Boas conversas e até a próxima.

Exportar relatórios em Rave Reports para PDF

Quem já não passou por uma experiência onde o cliente solicita que os relatórios sejam exportados do seu sistema em formato PDF? Bom, pode até ser fácil você instalar um impressora PDF na máquina e orientar que ele imprima para o formato, mas, e porque não exportar diretamente o relatório no formato solicitado? Na grande maioria dos geradores de relatórios, esta utilidade está disponível, e no Rave Reports, exportar para PDF é prático e rápido de ser implementado. Vamos montar um pequena estrutura de relatório, e codificar a exportação.

Crie uma nova aplicação Delphi for Win32, e adicione os seguintes componentes:
RvProject (paleta Rave) - Integração com o projeto do relatório
RvSystem (paleta Rave) - Configurações do relatório
RvRenderPDF (paleta Rave) - Exportação do relatório para PDF
ClientDataSet (paleta Data Access) - Importação de XML com dados para o relatório
RvDataSetConnection (paleta Rave) - Ligação do DataSet para exibição dos campos na estrutura do Rave Reports
SaveDialog (paleta Dialogs) - Localizar destino de exportação do relatório
Button (paleta Standard) - altere
Caption para "Exportar para PDF"

Inicialmente, selecione o RvProject e ligue sua propriedade Engine ao componente RvSystem1. Num segundo passo, selecione o ClientDataSet, com o botão direito sobre o mesmo selecione a opção Load from MyBase Table e selecione uma fonte de dados XML (C:\Arquivos de Programas\Arquivos Comuns\Borland Shared\Data\). Também, no componente RvDataSetConnection relacione a propriedade DataSet ao componente ClientDataSet para que a ligação dos dados entre Delphi e Rave Reports seja realizada. Com um duplo clique sobre o RvProject, abra o Rave Design e vamos à criação do arquivo de relatório. Selecionei como fonte de dados o arquivo Country.xml e irei montar um esquema de relatório para exibição de países e capitais. Salve o projeto do rave no mesmo diretório do sistema.
Criado o relatório, retomaremos o Delphi para configuração do RvProject onde iremos incorporar o projeto de relatório. Na propriedade StoreRAV localize o arquivo *.rav criado e em seguida clique em Load. Isso fará com que o relatório seja incorporado ao executável, sem necessidade de que o arquivo seja distribuído junto com a aplicação.

Para codificarmos então a exportação do relatório, adicione o bloco a seguir no evento OnClick do Button onde definimos as configurações do objeto SaveDialog e solicitamos ao usuário que informe um nome e local para que o relatório possa ser salvo. Em seguida, desabilitamos a opção de Preview exibida durante a execução de um relatório, definimos que o mesmo será renderizado para PDF, selecionamos o nome do relatório a ser executado e chamamos a ação.
procedure TForm1.Button1Click(Sender: TObject);
begin
SaveDialog1.Filter := 'Arquivos PDF (*.pdf)|*.pdf';
SaveDialog1.DefaultExt := '*.pdf';
SaveDialog1.Execute;
if SaveDialog1.FileName <> '' then
begin
RvSystem1.SystemSetups := RvSystem1.SystemSetups - [ssAllowSetup];
RvSystem1.DefaultDest := rdFile;
RvSystem1.DoNativeOutput:= false;
RvSystem1.RenderObject:= rvRenderPDF1;
RvProject1.SelectReport('Report1',True);
RvSystem1.OutputFileName:= SaveDialog1.FileName;
rvproject1.Execute;
end;
end;


Ao final do processo, um arquivo PDF será salvo no destino escolhido, pronto para ser enviado por e-mail ou disponibilizado para download em sites Web.
Pela sua leitura muito obrigado, e até o próximo post.

quarta-feira, 11 de março de 2009

SQLConnection - utilizando arquivo de configurações

Bom, creio que muitos já utilizaram este método de desenvolvimento, outros muitos procuram uma maneira de deixar o caminho de conexão ao banco de dados dinâmica, para que em tempo de design na sua estação de trabalho você possa utilizar a base de dados em determinado caminho e que no cliente, sem precisar recompilar o sistema, ou ainda, possa estar conectando a uma base em rede alterando apenas um único arquivo de configurações, chamados de arquivos INI.

Adicionado e configurado um novo componente SQLConnection à sua aplicação, adicione em seu evento OnBeforeConnect (antes de conectar) o seguinte trecho de código:

procedure TDM.CONEXAOBeforeConnect(Sender: TObject);
var
Arquivo: TIniFile{uses IniFiles};
begin
Try
Arquivo:= TIniFile.Create(ExtractFilePath(Application.ExeName)+'CONF.ini');
with DM.CONEXAO do
begin
Params.Values['DATABASE'] := Arquivo.ReadString('DADOS','DATABASE','');
Params.Values['USERNAME'] := Arquivo.ReadString('DADOS','USERNAME','');
Params.Values['PASSWORD'] := Arquivo.ReadString('DADOS','PASSWORD','');
Arquivo.Free
end;
Except
ShowMessage('Não foi possivel conectar! Nenhum servidor disponível...');
End;
end;


Note que estamos criando um novo objeto de inicialização, o qual carregará do mesmo diretório onde encontra-se o executável da aplicação um arquivo "Conf.ini". Este arquivo por sua vez contém as configurações como endereço da base de dados, usuário do banco e senha. Atribuimos então os valores a estes parâmetros de configuração do SQLConnection, acessando os valores da seção "DADOS" e lendo qual valor está armazenado em cada uma das propriedades.

NOTA: Aconselho deixar a propriedade Connected do SQLConnection como False para evitar problemas de conexão.

Criando o Arquivo *.INI

A criação do arquivo de configurações é muito simples, basta que através do bloco de notas crie um novo documento, adicione a ele uma nova seção "[DADOS]" e dentro desta seção, vá adicionando as propriedade que serão lidas pela sua aplicação, ficando assim organizado:
[DADOS]
DATABASE=192.160.10.100/3050:C:\Banco\banco.fdb
USERNAME=SYSDBA
PASSWORD=*********


NOTA: Há diferentes maneiras de você informar o caminho da base de dados, levando em consideração a estrutura e a segurança da rede onde o mesmo será instalado. O uso do IP antecendo o caminho físico do banco é altamente recomendado, em casos do sistema rodar apenas em localhost, use o IP 127.0.0.1, seguido do caminho físico da base, em casos de possuir um servidor de banco de dados, utilize o IP do servidor seguido pelo caminho físico da base no servidor, assim:
192.160.10.100:C:\Banco\banco.fdb
Mas, se você usa a base de dados em rede, e o servidor da aplicação possui Firewall de acesso, será necessário a liberação de acesso à porta 3050 (conexão utilizada pelo Firebird) e passar a utilizar o número da porta junto ao endereço IP, assim:
192.160.10.100/3050:C:\Banco\banco.fdb

Bom, desta forma você conseguirá criar suas aplicações, instalar as mesmas em seus clientes sem necessidade de recompilar pelo motivo do caminho físico da base. Abraço e até o próximo post.

terça-feira, 10 de março de 2009

Verificar se programa está em execução

Você desenvolveu seu programa, mas quer evitar que o mesmo seja aberto novamente quando já está em execução, ou não quer que seja executado enquanto outro processo estiver rodando, como fazer?

Aproveitando parte da rotina que postei no ínicio da semana sobre finalizar processos, criaremos uma rotina para apenas verificar se o processo existe ou não. Crie um novo projeto no Delphi, e declare já no code do projeto a seguinte função:

function TForm1.ProcessoExiste(ExeFileName: string): boolean;
const
PROCESS_TERMINATE=$0001;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32{declarar Uses Tlhelp32};
begin
result := false;

FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle,FProcessEntry32);

while integer(ContinueLoop) <> 0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName))
or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then
begin
Result := true;
exit;
end;
ContinueLoop := Process32Next(FSnapshotHandle,FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;


NOTA: declare a uses Tlhelp32

A função será o principal agente para varedura dos processos, onde adicionamos a lista de processos para a memória e depois, através de um While percorremos todos eles, localizando a entrada desejada. Ao encontrar o processo desejado, alteramos o resultado da função para True e abandonamos o while.

Para mostrar o resultado na tela, adicione um componente Edit (Edit1) e um Button (Button1), adicionando o código a seguir ao evento OnClick do Button:

procedure TForm1.Button1Click(Sender: TObject);
begin
if ProcessoExiste(Edit1.Text) then
ShowMessage('Processo encontrado')
else
ShowMessage('Processo não existe');
end;

Pronto, execute o projeto e faça o teste para verificar se o processo do explorer por exemplo está rodando, conforme demostração.
Abraço... até o próximo post.

sexta-feira, 6 de março de 2009

Abrindo documentos Word no Delphi

Quantas vezes você já pensou em como conseguiria abrir um documento do Word dentro da sua aplicação Delphi? Sim, eu sei, tem o RichEdit, mas e se o DOC possuir imagens? E a formatação de parágrafos, tabelas, auto-formas e todos os demais recursos que o Word oferece, sem chances de exibir num RichEdit, certo?

Bem, no Delphi há disponível um componente chamado OleContainer, o qual permite que através de um ActiveX a interface dos programas seja carregada a partir do prórprio formulário da sua aplicação, valendo não apenas para Word, mas para outros aplicativos como Excel, PowerPoint, etc.

Crie uma nova aplicação Delphi for Win32, arraste com componente Panel organizando sua propriedade Align para AlTop e dentro deste, adicione dois componentes Button, alterando o Caption destes para "Abrir Documento" e "Criar Documento". Na área ainda disponível do formulário, adicione um componente OleContainer da paleta System e altere sua propriedade Align para alClient, para que ele use todo o espaço do formulário. Arraste também para a tela da paleta Dialogs um componente OpenDialog e outro SaveDialog.

Realizando a codificação, adicionaremos o seguinte código ao evento OnClick do botão "Abrir Documento", no qual o diálogo de busca de documentos será executado e ao selecionar um documento, a aplicação do Word será criada através do componente OleContainer e o documento carregado.


procedure TForm1.btAbrirClick(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
Screen.Cursor := crHourGlass;
try
OleContainer1.CreateObjectFromFile(OpenDialog1.FileName, True);
OleContainer1.DoVerb(0);
finally
Screen.Cursor := crDefault;
end;
end;
end;


NOTA: Configure a propriedade Filter do OpenDialog permitindo apenas extensões relacionadas ao Word.

No botão "Criar Documento" adicione a lista de códigos a seguir, a qual é responsável por criar um novo objeto do tipo "Word Document" exibindo-o na tela e adicionando um texto a sua área.


procedure TForm1.btCriarClick(Sender: TObject);
begin
OleContainer1.CreateObject('Word.Document', False);
OleContainer1.AllowInPlace := True;
OleContainer1.DoVerb(ovPrimary);
OleContainer1.OleObject.Application.Selection.TypeText('Passagem do Texto para o Documento');
end;


Por último, precisamos que o documento também seja salvo quando saírmos do formulário, pois de nada adiantaria abrir o documento, permitir que alterações nele sejam feitas e não salvar as mesmas. Para isto, adicione ao evento OnDeactivate do OleContainer o seguinte código, que fará uma verificação relacionada ao nome do arquivo para identificar se o mesmo foi aberto ou criado, em seguida salva-o no computador.

procedure TForm1.OleContainer1Deactivate(Sender: TObject);
var
FileName : String;
begin
if OpenDialog1.FileName <> '' then
FileName := OpenDialog1.FileName
else
begin
if SaveDialog1.Execute then
FileName := SaveDialog1.FileName;
end;
if FileName <> '' then
self.OleContainer1.SaveAsDocument(OpenDialog1.FileName) ;
end;


NOTA: Configure a propriedade DefaultExt do SaveDialog para "*.doc". Configure também sua propriedade Filter.

Dessa forma, finalizo este post, deixando-lhe o desafio de criar aplicações Delphi integradas com demais ferramentas disponíveis em seu computador. Abraço e até o próximo post.

quinta-feira, 5 de março de 2009

Obter texto de uma página Web

Quantas vezes você já procurou rotinas para capturar e salvar o texto de uma página web? Obter valores, salvar notícias em uma base de dados, enfim várias funcionalidades que podem ser vinculadas de um sistema Win32 utilizando recursos/dados contidos em páginas Web.
Ao contrário de que você deve estar pensando, não importaremos o código fonte da página e depois remover as tags para limpar o texto, a rotina a seguir obterá apenas texto puro, ignorando a captura de qualquer tag HTML. Crie um novo projeto Delphi for Win32, adicione um componente Edit (edtNavigate) para que seja a barra de navegação, um Button com Caption "Navegar". Logo abaixo adicione um componente WebBrowser que usaremos para exibir a página Web em sua forma original, e de onde também iremos retirar o texto da página que está sendo exibida. Por último, adicione logo abaixo ao WebBrowser outro componente Button alterando o Caption para "Obter Texto" e um componente Memo onde iremos exibir o texto extraído da página Web. Altere a propriedade ScrollBars do Memo para ssBoth a fim de que sejam exibidas as barras de rolagem no sentido vertical e horizontal.
Para dar início ao processo de codificação, adicione ao botão "Navegar" a seguinte linha de código, que irá atribuir uma URL ao componente WebBrowser e exibir o conteúdo:


WebBrowser1.Navigate(edtNavega.Text);

Por último, adicionaremos o código ao botão "Obter Texto", que se trata de uma função disponibilizada no componente WebBrowser, a fim de extrair o conteúdo da página exibida.

memo1.Text := WebBrowser1.OleObject.Document.documentElement.innerText;

Pronto, execute agora seu sistema, digite uma URL válida na barra de navegação e exiba o conteúdo da página na tela. Após carregada a página, clique sobre o botão obter texto e observe que todo o texto foi capturado e jogado ao componente Memo, onde poderia ser salvo em uma base de dados ou qualquer outra ação necessária.

Obrigado pela leitura, até a próxima.

quarta-feira, 4 de março de 2009

Finalizar Processos

Algumas vezes nos deparamos com situações em que não queremos que certo processo esteja executando no computador, durante um processo demorado do sistema por exemplo, você pode querer fechar algum player de áudio, finalizar o messenger entre outras situações. Há diversas formas de realizar e implementar esta rotina, ou seja pelo ID utilizado pelo processo, ou através do próprio nome do executável, "wmplayer.exe" por exemplo.

Criando um novo projeto, altere o Caption do formulário para "Fechar Programas" e arraste para ele um componente Label alterando Caption para "Digite o nome do Processo", um componente Edit (edtProcesso) e um componente Button com Caption "Finalizar Processo". Antes de codificar o evento OnClick do botão, vá ao código e declare na seção Private a seguinte função que receberá por parâmetro o nome do executável:

function Finalizaprocesso(ExeFileName: string): integer;

Na implementação da função, adicione o código a seguite:

function TForm1.Finalizaprocesso(ExeFileName: string): integer;

const
PROCESS_TERMINATE=$0001;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32{declarar Uses Tlhelp32};
begin
result := 0;

FSnapshotHandle := CreateToolhelp32Snapshot
(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle,
FProcessEntry32);

while integer(ContinueLoop) <> 0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName))
or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then
Result := Integer(TerminateProcess(OpenProcess(
PROCESS_TERMINATE, BOOL(0),
FProcessEntry32.th32ProcessID), 0));
ContinueLoop := Process32Next(FSnapshotHandle,FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);

end;

A função irá localizar o processo, e quando localizado irá finalizá-lo.

Para executar a função, basta que adicione ao evento OnClick do botão uma chamada ao código, passando para o parâmetro o valor digitado no Edit. Antes de finalizar o processo, ainda solicitamos a confirmação ao usuário.

if Application.MessageBox('Deseja mesmo finalizar este processo?','Finalizar processo',MB_YESNO) = idYes then
Finalizaprocesso(edtProcesso.Text)






Por ora seria isto, abraço e até o próximo post.

quarta-feira, 21 de janeiro de 2009

Obtendo tamanho de arquivos

Alguma vez já pensou numa rotina para saber o tamanho de um arquivo? Bom, e isso é bem simples de fazer, com a declaração de uma única função já conseguimos resolver nosso problema, veja:

function TForm1.TamanhoArquivo(Arquivo: string): Integer;
begin
with TFileStream.Create(Arquivo, fmOpenRead or fmShareExclusive) do
try
Result := Size;{resultado em bytes}
finally
Free;
end;
end;


Agora para mostrar um resultado, você pode adicionar à tela um componente OpenDialog e um Button, adicionando ao evento OnClick do button o seguinte código:

if OpenDialog1.Execute then
begin
ShowMessage('Tamanho do arquivo é '+FloatToStr(TamanhoArquivo(OpenDialog1.FileName)/1024));
end;


Agora simples, implemente a função nas suas rotinas de programação, deixando seus sistemas mais funcionais. Por ora seria isto, até a próxima.

Destacando palavras no RichEdit

Bom galera, de volta das férias, de volta aos posts. Já de início, uma coisa que a algum tempo vinha despertando minha curiosidade, e hoje, vendo um post de usuário no fórum do Imasters, resolvi colocar a cabeça pra pensar. Imagine, um formulário no Delphi onde você vai digitando normalmente seu texto, e dentro dele, algumas palavras vão ganhando destaque, cores diferentes, ficam em negrito. Da mesma forma como acontece no Word, ao digitar "microsoft" ele corrige e troca para "Microsoft", ou, porque não fazer com que fique imediatamente em negrito também, assim "Microsoft".

De início, crie um novo projeto Windows Forms (Win32) no Delphi, em seguida, adicione os seguintes componentes: Edit (Edit1), ColorBox (ColorBox1) da paleta additional,um Button (Button1) e um RichEdit (RichEdit1) da paleta Win32.

Agora, no código, no corpo da unit, crie um novo tipo (nova declaração de tipo), adicionando as seguintes linhas logo após a linha "type":

TRPalavras = Record
DS_PALAVRA: String;
VR_COR : TColor;
ESTILO : TFontStyles;
end;

TAPalavras = array of TRPalavras;

Agora, declare uma variável do tipo private, da seguinte forma:

APalavras : array of TRPalavras;

Esta varável irá descender do tipo TRPalavras criado anteriormente.

Acessando agora o evento OnClick do botão, adicione o código a seguir, o qual será responsável por armazenar no array quais as palavras e respectivas cores que devem ser destacadas no texto a ser digitado no componente RichEdit.

{ Adicionando as palavras a lista }
SetLength( APalavras, Length( APalavras )+1 );
APalavras[ High( APalavras ) ].DS_PALAVRA := Edit1.Text;
APalavras[ High( APalavras ) ].VR_COR := ColorBox1.Selected;
APalavras[ High( APalavras ) ].ESTILO := [fsBold];

Por final, adicione também ao evento OnKeyUp do RichEdit o código a seguir, código este que irá identificar o início e fim de uma palavra que está sendo digitada, fazendo sua comparação com as palavras armazenadas. Caso a palavra digitada coincida com uma das armazenadas, um comando for será disparado fazendo com que todas as letras sejam destacadas em negrito e de acordo com a cor selecionada com componente ColorBox.

procedure TForm1.RichEdit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
const
LetrasValidas = ['a'..'z', 'A'..'Z', '0'..'9', '<', '>', '!', '='];

var
iPosIni: Integer;
iPosFim: Integer;
iSelStart: Integer;
iSelLength: Integer;
iLoopFor: Integer;
sText: String;
begin

LockWindowUpdate(RichEdit1.Handle);

{ guardaremos a posição inicial }
iSelStart := RichEdit1.SelStart;
iSelLength := RichEdit1.SelLength;

sText := RichEdit1.Text;

{ Acharemos o inicio da palavra }
iPosIni := iSelStart;
if sText[ iPosIni ] in LetrasValidas then
begin
for iLoopFor := iSelStart-1 downto 0 do
begin
if sText[ iLoopFor ] in LetrasValidas then
iPosIni := iLoopFor
else
Break;
end;
end;

{ Acharemos o final da palavra }
iPosFim := iSelStart;
for iLoopFor := iSelStart+1 to Length( RichEdit1.Text ) do
begin
if RichEdit1.Text[ iLoopFor ] in LetrasValidas then
iPosFim := iLoopFor
else
Break;
end;

{ Selecionaremos a palavra }
RichEdit1.SelStart := iPosIni-1;
RichEdit1.SelLength := (iPosFim)-RichEdit1.SelStart;

{ setaremos a cor original e estilo original }
RichEdit1.SelAttributes.Color := clBlack;
RichEdit1.SelAttributes.Style := [];

{ Atribuiremos a nova cor e estilo caso encontre a palavra }
for iLoopFor := 0 to High( APalavras ) do
begin
if UpperCase(APalavras[ iLoopFor ].DS_PALAVRA) = UpperCase(RichEdit1.SelText) then
begin
RichEdit1.SelAttributes.Color := APalavras[ iLoopFor ].VR_COR;
RichEdit1.SelAttributes.Style := APalavras[ iLoopFor ].ESTILO;
Break;
end;
end;

{ Posicionaremos o cursor na posição original }
RichEdit1.SelStart := iSelStart;
RichEdit1.SelLength := iSelLength;

LockWindowUpdate(0);

end;

Com o sistema em funcionamento, ao adicionarmos a palavra "microsoft", e digitarmos um texto no componente RichEdit da tela, ao digitarmos alguma das palavras adicionadas, a mesma será descada, conforme mostra a imagem.

Assim, faça a implementação em seus sistemas, boa leitura e até a próxima.
Obs.: Deixe um comentário com seu nome / e-mail para receber os fontes.