Associando extensão de arquivo à uma aplicação Delphi

Escrito em 06 de agosto de 2007 em Delphi,Programação por Jeferson Oliveira

Introdução

É comum uma aplicação precisar abrir arquivos externos, sejam eles arquivos proprietários ou arquivos de tipo conhecido, e exibir seu conteúdo para o usuário. Para isso, normalmente, haverá na aplicação um formulário para seleção e abertura do arquivo desejado. Mas se o usuário sempre quiser, ou precisar, abrir esse tipo de arquivo com sua aplicação, seria mais prático que ao abrí-lo pelo Windows Explorer sua aplicação seja acionada imediatamente para exibição do conteúdo. Para que a abertura ocorra automaticamente, é necessário que a extensão do arquivo seja associada à sua aplicação.

Nesse artigo será demonstrado como preparar uma aplicação para ser associada com tipos de arquivos, como utilizar parâmetros de execução em uma aplicação, como associar uma extensão de arquivo à uma aplicação manualmente, e como realizar essa associação automaticamente pela própria aplicação ou utilizando um instalador.

A extensão de exemplo

Para exemplificar a associação de arquivos à uma aplicação Delphi, vamos criar um projeto no Delphi 7 capaz de exibir o conteúdo de arquivos de visualização do gerador de relatórios QuickReport (.QRP), mas os passos indicados aqui, à exceção é claro do método para abertura dos arquivos .QRP, poderão ser utilizados para associação de arquivos de qualquer extensão e em qualquer versão do Delphi.

Para criar um arquivo .QRP basta visualizar um relatório gerado com o QuickReport e salvar o conteúdo da visualização. Por não ser o objetivo desse artigo, detalhes sobre a utilização do gerador de relatórios QuickReport não serão abordados aqui.

Criando o projeto de exemplo

No Delphi 7 crie uma nova aplicação(File/New/Application), adicione ao formulário um TButton e um TOpenDialog. Renomeie o TButton para btnVisualizar, o TOpenDialog para odArquivoVisualizar e o formulário para frmPrincipal, e salve o projeto como AbrirQRP.dpr.

Para que o OpenDialog só exiba os arquivos da extensão que interessa à aplicação, defina a propriedade Filter com o valor Arquivos QRP|*.QRP.

Vamos agora definir um método para visualização de arquivos QRP e invocá-lo no evento OnClick do botão, ficando o código como exemplificado abaixo:

implementation

uses
  QuickRpt, QRPrntr, Registry, ShlObj;

{$R *.dfm}

procedure VisualizarQRP(const NomeArquivoQRP: string);
var
  QuickRep: TQuickRep;
begin
  QuickRep := TQuickRep.Create(nil);
  QuickRep.QRPrinter := TQRPrinter.Create(QuickRep);
  try
    QuickRep.QRPrinter.Load(NomeArquivoQRP);
    QuickRep.QRPrinter.Preview;
  finally
    QuickRep.Free;
  end;
end;

procedure TfrmPrincipal.btnVisualizarClick(Sender: TObject);
begin
  if odArquivoVisualizar.Execute then
    VisualizarQRP(odArquivoVisualizar.FileName);
end;

Nesse ponto nossa aplicação já está apta à exibir o conteúdo de arquivos .QRP ao clicar no botão btnVisualizar.

Utilizando parâmetros de execução

Quando um arquivo associado à uma aplicação é aberto pelo
Windows, o sistema operacional aciona a aplicação associada passando como parâmetro o nome do arquivo a ser aberto. Para que a aplicação consiga responder adequadamente à essa solicitação, ela deve estar preparada para ler e interpretar os parâmetros enviados pelo sistema operacional. No Delphi, para identificar se algum parâmetro foi passado para a aplicação é disponibilizada a variável global ParamCount que indica a quantidade de parâmetros que foram passados; e para acessar o valor de um parâmetro é disponibilizada a função ParamStr, que recebe como argumento o índice do parâmetro a ser lido, e retorna seu valor.

  • Nota: ParamStr(0) retorna o caminho do executável corrente, portanto, o índice do primeiro parâmetro é 1, do segundo 2, e assim sucessivamente.

Preparando a aplicação para a associação de extensões

No evento OnShow do formulário, adicione o código abaixo que, caso algum parâmetro tenha sido passado para a aplicação, acionará o método de abertura de arquivos .QRP informando o valor do primeiro parâmetro como o nome do arquivo a ser aberto:

procedure TfrmPrincipal.FormShow(Sender: TObject);
begin
  if ParamCount > 0 then
    VisualizarQRP(ParamStr(1));
end;

Para testar o comportamento da aplicação quando algum parâmetro for informado, acesse o menu Run/Parameters e informe no campo Parameters um valor para o parâmetro.

RunParameters

Outra forma de passar parâmetros para a aplicação é executando-a por linha de comando:

D:\\Prj\\AbrirQRP>AbrirQRP.exe C:\\Temp\\Arquivo.QRP

Associando manualmente uma extensão à aplicação

Há várias maneiras de associar manualmente um arquivo à uma aplicação. É possível criar uma chave para a extensão no registro do Windows, ou criar uma nova entrada em Painel de controle/Opções de Pasta/Tipos de arquivo, mas a forma mais simples de criar essa associação é clicar duas vezes sobre o arquivo pelo Windows Explorer, e no diálogo para seleção da aplicação a ser utilizada para a abertura do arquivo clicar no botão Procurar, e selecionar a aplicação desejada. Certifique-se que a opção “Sempre usar o programa selecionado para abrir este tipoe de arquivo” esteja selecionada.

AbrirCom

Registrando o tipo de arquivo pelo instalador da aplicação

Uma maneira de associar uma extensão é criar as chaves necessárias no registro do Windows durante a instalação da aplicação. Abaixo um exemplo de como realizar essa tarefa utilizando o gerador de instaladores InnoSetp, ferramenta muito utilizada por desenvolvedores de software em todo o planeta:

[Registry]
Root: HKCR; Subkey: .QRP; ValueType: string; ValueData: ArquivoQRP; Flags: uninsdeletekey
Root: HKCR; Subkey: ArquivoQRP; ValueType: string; ValueData: Arquivo de visualização de relatório; Flags: uninsdeletekey
Root: HKCR; Subkey: ArquivoQRP\\shell\\open; ValueType: string; ValueData: &Abrir com AbrirQRP; Flags: uninsdeletevalue
Root: HKCR; Subkey: ArquivoQRP\\shell\\open\\command; ValueType: string; ValueData: {app}\\AbrirQRP.exe %1; Flags: uninsdeletevalue
Root: HKCR; Subkey: ArquivoQRP\\DefaultIcon; ValueType: none; Flags: uninsdeletevalue

Automatizando a tarefa com o Delphi

Se nossa aplicação deve ser associada a um tipo de arquivo, pode ser interessante que ela consiga ter independência para registrar uma extensão. O código abaixo define os métodos para registro automático de um tipo de arquivo: 

procedure RegistrarExtensao(const Extensao, TipoArquivo, NomeAplicacao, Executavel: string);
var
  ChaveArquivo: string;
  Registro: TRegistry;

  procedure EditarChave(const Chave, Valor: string);
  begin
    Registro.OpenKey(Chave, True);
    Registro.WriteString('', Valor);
    Registro.CloseKey;
  end;

begin
  Registro := TRegistry.Create;
  try
    Registro.RootKey := HKEY_CLASSES_ROOT;
    Registro.LazyWrite := False;
    ChaveArquivo := 'Arquivo' + Extensao;

    //Registra a extensão
    EditarChave('.' + Extensao, ChaveArquivo);

    //Define a descrição para o tipo de arquivo
    EditarChave(Format('%s', [ChaveArquivo]), TipoArquivo);

    //Adiciona uma entrada no menu de contexto
    EditarChave(Format('%s\\shell\\open', [ChaveArquivo]), Format('&Abrir com %s', [NomeAplicacao]));

    //Associa a extensão à aplicação
    EditarChave(Format('%s\\shell\\open\\command', [ChaveArquivo]), Format('"%s" "%s"', [Executavel, '%1']));

    //Define o ícone associado ao tipo de arquivo
    EditarChave(Format('%s\\DefaultIcon', [ChaveArquivo]), Format('%s, 0', [Executavel]));
  finally
    Registro.Free;
  end;
  //Notifica o SO da alteração na associação do tipo de arquivo
  SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
end;

procedure RegistrarExtensaoQRP;
begin
  RegistrarExtensao('QRP', 'Arquivo de visualização de relatório', 'AbrirQRP', ParamStr(0));
end;

procedure TfrmPrincipal.FormCreate(Sender: TObject);
begin
  RegistrarExtensaoQRP;
end;
  • Nota: Como pôde ser observado o método RegistrarExtensaoQRP foi acionado no evento OnCreate do formulário, garantindo a cada execução que o tipo de arquivo esteja associado à aplicação, o que nem sempre é um comportamento desejado, pois poderá sobrepor alterações realizadas pelo usuário diretamente nas configurações do sistema operacional.

Considerações finais

Espero com esse artigo ter contribuído de alguma forma para a melhor compreensão do processo de associação de extensões de arquivos à aplicações, e que esse conhecimento possa ser útil para a melhoria do seu processo de desenvolvimento.

Comentários, críticas e sugestões serão muito bem-vindos para que os próximos artigos possam ser aprimorados.


11 comentários em 'Associando extensão de arquivo à uma aplicação Delphi' »

Assine os comentários usando RSS ou faça um TrackBack para 'Associando extensão de arquivo à uma aplicação Delphi'.

[-]
[+]
Camila Lisboa disse,

Em 13 de agosto de 2007 às 09:47

Como se já não bastasse a imensa admiração que tenho por você, devo parabenizá-lo com ênfase pelo seu artigo! Não só pela qualidade do conteúdo, como também pela forma como foi escrito… Numa linguagem acessível e detalhada, facilitando a compreensão daqueles que não têm um conhecimento muito acurado no assunto.
Grande abraço!

 
[-]
[+]
Jeferson Oliveira disse,

Em 13 de agosto de 2007 às 14:13

Camila,

Quão honrado eu me sinto em ter por aqui você que conhece “até os erros do meu português ruim”.

Um beijo!

 
[-]
[+]
Samuel Viveiros Gomes disse,

Em 05 de setembro de 2007 às 14:18

Parabéns Jeferson, seu artigo ficou excelente. Atualmente, estou envolvido em um projeto Multimídia em Delphi. É um Player de mp3 bem simples, com direito a plugins e visualizações, e o seu artigo vai me ajudar muito com a interação com o Windows Explorer. Parabéns, e um grande abraço.

[-]
[+]
Jeferson Oliveira disse,

Em 05 de setembro de 2007 às 15:29

Obrigado Samuel!
Desejo-lhe muito sucesso nesse projeto!

Um abraço!

 
 
[-]
[+]

Em 27 de janeiro de 2009 às 14:56

Funcionou corretamente, porem com 2 detalhes:
Na linha:
QuickRep.QRPrinter := TQRPrinter.Create(QuickRep);
tive que mudar para funcionar:
QuickRep.QRPrinter := TQRPrinter.Create;
Não sei porque motivo.

E no preview não disponibiliza o botão de configurar a impressora (escolher impressora, etc).
Será que tem como habilitar aquele botão, tentei de tudo mas ele não habilita.

Aproveitando:
Seria excelente se nesse preview tivesse a opção de salvar no formato .pdf (atualmente utilizo o dopdf)

E parabens pelo artigo.

[-]
[+]
Jeferson Oliveira disse,

Em 27 de janeiro de 2009 às 16:54

Olá Fábio!

Sobre a alteração na chamada ao construtor de TQRPrinter, a passagem do Owner como parâmetro depende da versão do QuickReport utilizada. Se não me engano esse parâmetro foi adicionado na versão 4 do QuickReport (que é a que utilizei quando escrevi esse exemplo), e você talvez esteja usando uma versão 3.x, que é a que vinha instalada no Delphi 5, 7 e outros.

Para que o botão de configurar a impressora fique disponível no preview, é necessário alterar o fonte do QuickReport e recompilá-lo. Caso tenha o fonte, altere em QRPrev.pas, o método TQRStandardPreview.LoadClick, comentando a linha

PrintSetup.Enabled := False;

Sobre a exportação para PDF, a versão 4 do QuickReport disponibiliza alguns novos filtros de exportação, entre eles o TQRPDFFilter, que resolveria seu problema. Nas versões anteriores a única forma era utilizando algum outro componente para esse fim, como o eDocEngine ReportExport: http://www.gnostice.com/eDocEngine_VCL.asp

Espero ter ajudado!

 
 
[-]
[+]
renivaldo disse,

Em 29 de janeiro de 2009 às 16:11

gostari de saber como posso salvar arquivos da extenção QRP gerado por outra aplicação? ler o aquivo é simples só que para salvar tá dificil. a aplicação salva só o que foi gerado por ela.

 
[-]
[+]
Jean disse,

Em 13 de julho de 2009 às 12:32

olá amigo, muito bo mseu tutorial, eu consegui fazer o arquivo abrir o programa quando executado, mas preciso que ele coloque o que tem dentro do arquivo em uma ValueListEditor, como faço isso?
obs. já estou usando paranstr para outra função, qualquer coisa adc no msn: jeanmichelkowalski@hotmail.com
vlw, abraço!

 
[-]
[+]
Osmanito disse,

Em 26 de agosto de 2009 às 21:14

Amigo, que units eu preciso adicionar neste código de Associação de Extensão? Agradeço a dica.
osmanitobrito@hotmail.com

[-]
[+]
Jeferson Oliveira disse,

Em 26 de agosto de 2009 às 23:48

Olá Osmanito!

Registry e ShlObj, já que as demais contidas na cláusula “uses” (no início do código) são específicas do QuickReport.

 
 
[-]
[+]
Wagner Leão disse,

Em 19 de outubro de 2009 às 20:08

Parabens pela clareza.
Excelente explanação deste conteúdo.
Obrigado pela dica!
Deus te abençoe.