O TWebBrowser pode causar Access Violation ao fechar um programa #AQuemPossaInteressar

Categoria: Artigos
Categoria Pai: Addicted 2 Delphi!
Acessos: 4397
Imagem meramente ilustrativa

Por mais estranho que isso possa parecer, é a mais pura verdade e aconteceu comigo. Estava desenvolvendo um tocador de MP3 que exibe também as letras das músicas e com o intuito de permitir a exibição desse tipo de texto de forma mais amigável resolvi utilizar um inocente componente TWebBrowser. O programa é organizado em páginas (TTabSheet) de um controle TPageControl e o TWebBrowser está em uma destas páginas, a qual pode ou não ser exibida, de acordo com a vontade do usuário, por exemplo, ele pode abrir um MP3 e nunca acessar a página onde está o TWebBrowser.

Quando o TWebBrowser é manipulado via código, isto é, tem seu conteúdo alterado via código, mas ele nunca é exibido de fato, isto é, ele nunca é renderizado, por algum motivo muito bizarro acontece um Access Violation ao fechar a aplicação! A relação entre o erro e o componente não é nem um pouco óbvia, o que me fez perder alguns dias tentando resolver o problema por conta própria, já que, sendo um programa que utiliza bibliotecas externas para manipular e/ou tocar o MP3 eu acreditava que o erro era causado por algo que eu havia feito errado.

Depois de me embrenhar nas entranhas da VCL descobri que havia uma relação entre o erro e o TWebBrowser, mas mesmo assim não consegui identificar o motivo exato e, sendo assim, não consegui resolver o problema por conta própria, tendo que recorrer ao Google. Achei algumas soluções no Stack Overflow e no JIRA da Embarcadero. Algumas soluções falavam em navegar para "about:blank" antes de fechar o programa ou "deletar" o componente (não sei bem se é usar free nele ou removê-lo da lista de componentes do TForm onde ele está, ou os dois, não testei), contudo, a solução mais elegante e simples foi proposta por Zarko Gajic: remover do dpr a linha Application.MainFormOnTaskbar.

Isso mesmo! A solução mais simples é tão bizarra quanto o próprio erro em si. Questionei Zarko Gajic a respeito de como ele chegou nesta resposta e o mesmo disse que não lembrava, e que provavelmente usou tentativa e erro. Certamente deve ter sido um trabalho muito braçal (ou pura sorte heheeh).

Vale ressaltar que este problema aconteceu no Delphi 26 (Delphi Rio) e que a ocorrência registrada no JIRA da Embarcadero diz respeito ao Delphi XE4 e XE8, ou seja, é um problema que não foi resolvido até hoje!