6 de novembro de 2012

Integrando o Outlook em aplicações Delphi - Parte I

Embora eu não tenha números exatos, o Outlook é o programa de email mais utilizado em desktops. Parte desse sucesso se deve à ampla adoção da ferramenta no ambiente corporativo, já que ela também centraliza funções de calendário, acompanhamento de tarefas e agenda de contatos, permitindo compartilhar facilmente as informações.

Um outro aspecto positivo é que o Outlook é componentizado, o que abre caminho para criação de extensões e integrações com outros sistemas. Neste post, mostro como utilizar os recursos COM do Outlook para integrá-lo a uma aplicação Delphi.

Do mesmo modo que as outras aplicações do Microsoft Office (como o Excel), todos os recursos disponíveis do Outlook devem se acessados a partir de um objeto centralizador que representa a própria aplicação. Neste caso, precisamos obter uma instância de Outlook.Application, mapeada pelo Delphi na unit OutlookXP, junto com as demais interfaces existentes para se trabalhar com a ferramenta.

O quadro abaixo mostra um exemplo dos passos básicos necessários para interagir com o Outlook. O código apresentado percorre os contatos registrados na pasta local do Outlook, listando informações de cada um deles numa tabela:
procedure TForm1.btnListarContatosClick(Sender: TObject);
var i : integer;
OutlookApp: TOutlookApplication;
ns : NameSpace;
pasta: MAPIFolder;
contato : _ContactItem;
begin
StringGrid1.RowCount := 2;
OutlookApp := TOutlookApplication.Create(Nil);

ns := OutlookApp.GetNamespace('MAPI');
pasta := ns.GetDefaultFolder(olFolderContacts);

for i := 1 to pasta.Items.Count do
begin
if (i > 1) then
StringGrid1.RowCount := StringGrid1.RowCount + 1;

contato := pasta.Items.Item(i) As _ContactItem;

StringGrid1.Cells [1,i] := contato.FullName;
StringGrid1.Cells [2,i] := contato.Email1Address;
StringGrid1.Cells [3,i] := contato.EntryID;
StringGrid1.Cells [4,i] := contato.CompanyName;
StringGrid1.Cells [5,i] := contato.BusinessAddress;
end;

OutlookApp.Disconnect;
OutlookApp.Free;
end;
Vamos destrinchar esse código. Após criar uma instância para acessar a aplicação (classe TOutlookApplication), o trecho recupera um tipo de objeto denominado Namespace. Atualmente, apenas o namespace MAPI (API de Mensagens do Windows) está disponível, concentrando todos os registros, isto é, os emails, contatos, tarefas e entradas do calendário. Um Namespace é organizado em pastas dispostas hierarquicamente, podendo haver pastas dentro de pastas para armazenar os itens.

Há algumas formas de acessar as pastas do Outlook. A propriedade Folders do Namespace lista todas as pastas, incluindo as compartilhadas com outros usuários no servidor. As subpastas eventualmente existentes são acessíveis por meio de propriedade Folders própria. E como saber que tipo de item uma pasta contém? Em princípio, pode-se consultar a propriedade DefaultItemType para se ter uma ideia. Mas, certas pastas (como a DeletedItems) podem conter itens de tipos diferentes misturados. Neste caso, recomenda-se checar a propriedade Class do item ou fazer um cast dinâmico para o tipo desejado e ver se a conversão foi bem sucedida.

Outra forma de acesso é requerer ao Namespace a pasta padrão para um determinado tipo de item, como no código mostrado acima. Lá, uso GetDefaultFolder para recuperar exclusivamente a pasta que armazena meus contatos. Por fim, se eu possuir a identificação única da pasta (seu entryID, posso recuperá-la diretamente com a função GetItemFromID do Namespace.

Voltando ao código, agora tenho uma instância da pasta de contatos para trabalhar. Como toda pasta, esta possui uma lista Items que dá acesso ao conteúdo específico - no exemplo, os contatos cadastrados. Então, percorro a lista para prencher a tabela com as informações desejadas de cada um dos contatos.

Para concluir, desconecto minha instância do Outlook e removo-a da memória para liberar os recursos utilizados.

Note que não foi preciso informar usuário e senha para fazer logon. Isso acontece porque o Outlook pode ser configurado para se conectar automaticamente com o mesmo usuário do Windows. Se for preciso, pode-se logar manualmente usando a função Logon do Namespace.

Aproveitando os mesmos conceitos, podemos criar automaticamente um novo contato, conforme mostra o trecho de código a seguir:
contato := pasta.Items.Add(olContactItem) As _ContactItem;
contato.FirstName := 'Balaio';
contato.LastName := 'Tecnológico';
contato.CompanyName := 'ABC71 Soluções Em Informática';
contato.Save;
contato.Display(1);
Como se vê, a criação é bastante simples. Primeiro, chamo o método Add da lista de itens da pasta, fornecendo-lhe o tipo de item que deve ser criado - um item de contato, neste caso. Após prover algumas informações básicas do contato, salvo o registro. A última linha não é imprescindível; ela apenas exibe no próprio Outlook o contato recém-criado para que o usuário possa complementar as informações, se desejar.

De forma similar, conseguimos trabalhar com tarefas e compromissos no calendário. Também é possível fazer o envio de email aproveitando a infraestrutra já configurada do Outlook, operação que mostro no próximo post.

Obviamente, todos os recursos apresentados aqui exigem que haja uma cópia do Outlook instalado no computador local para funcionar.

5 comentários :

George De Luca disse...

Olá Meu Caro,
Sabe se isso funciona tb para o Windows Live Mail?

Luís Gustavo Fabbro disse...

George

Não encontrei qualquer documentação relativa a automação de tarefas com o WLM. Ao que parece, ele não permite automação.

De qquer modo, o mapeamento de classes COM distribuido com o Delphi aponta para o ClassID do outlook. Isso significa que as classes só trabalharão com essa ferramenta.

Pode ver se existem classes COM para o WLM tentando importá-las manualmente em um computador que tenha tanto o Delphi quanto o WLM.

[]s

TH SISTEMAS - Soluções Comerciais e Web disse...

Ola boa noite meu amigo, eu testei a função que você desenvolveu no artigo mas toda vez que o delphi conecta pra visualizar o contato da lista aparrece uma janela pedindo permissão, isso aconteceu comigo com o Office 2010, teria como evitar essa janela chata.

At: Thiago Oliveira

Luís Gustavo Fabbro disse...

Thiago

Isso é uma questão de segurança do Outlook. Você pode desligar tais alertas seguindo as instruções
do post http://sogeeky.blogspot.com.br/2007/04/how-to-disable-outlook-security-warning.html. Isso, no entanto pode ser perigoso já que qualquer outro programa (um vírus, por exemplo), poderá acessar o outlook sem ser detectado.

Dependendo da forma como a segurança é tratada onde sua aplicação for rodar, há a possibilidade de gerenciar esses acessos através da central de confiabilidade do Outlook. A melhor solução exigirá que você assine digitalmente sua aplicação e inclua o certificado na lista de fornecedores confiáveis do Oulook.

[]s

TH SISTEMAS - Soluções Comerciais e Web disse...

Entendi e não tinha pensado nessa parte, vou rever a situação aqui da empresa e obrigado pela atenção

Postar um comentário

OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.

Observação: somente um membro deste blog pode postar um comentário.