Prefácio
Nas últimas semanas de trabalho, tive um problema de dor de cabeça, ou seja, o controle ActiveX escrito em VB6 tem muitos problemas estranhos no ambiente Delphi. Depois de muitas reviravoltas, finalmente procurei em quase todos os fóruns e informações. , encontrou soluções para problemas que ocorrem em diferentes versões do Delphi.
Uma das exceções fatais inexplicáveis no Delphi5
Primeiro, vamos dar uma olhada no estranho comportamento dos controles ActiveX escritos em VB no Delphi5.
Por exemplo: Usamos VB para escrever um controle UserTest (para simplificar, exportamos apenas uma classe, o controle de usuário), uma propriedade TestName e um método TestMethod. Em seguida, compile-o em um controle ActiveX, registre-o e importe-o para o ambiente de desenvolvimento Delphi5 (se não houver nada claro sobre as etapas acima, verifique vários materiais de referência, deve haver respostas padrão), até agora tudo parece normal.
Então, estamos acostumados a arrastar e soltar controles no formulário, redimensioná-los e atribuir valores às propriedades na janela de propriedades, ou o mesmo no código. No entanto, aí vem o problema. Se você chamar esse TestMethod com entusiasmo, receberá uma exceção estranha "OleError800a01a9" e, em seguida, o programa será encerrado. Infelizmente, você não poderá rastrear essa exceção. em VB Claro, se você é bom em montagem, você pode seguir passo a passo a janela de depuração do Delphi...
Quando encontrei esse problema pela primeira vez, fiquei quase irritado porque nem a Microsoft nem a Borland tinham qualquer explicação para o erro, nem qualquer informação para encontrar. Tive que ir a vários fóruns que frequentava, claro que o mais importante era o CSDN, e procurei perguntas semelhantes na versão VB e na versão Delphi. Infelizmente, só havia perguntas semelhantes, mas nenhuma resposta. ferramenta, depois de testar quase todas as ferramentas e ambientes de desenvolvimento no Windows (incluindo desktop e WEB), esqueci do Delphi.
Nos dois dias restantes, quase corri ao redor do mundo, ligando para todos os meus amigos e perguntando se os especialistas em Delphi sabiam dessa situação. Finalmente, encontrei um link do Google. Infelizmente, esqueci a localização exata desse link. , mas consegui um método quase mágico (é assim que o descobridor o chama):
Um método de modificação manual do arquivo da biblioteca de tipos de proxy XXX_TLB.PAS (onde XXX se refere ao nome da classe do controle) gerado pelo Delphi após a importação do controle VBActiveX pode resolver esse problema. Exemplo:
Existe um controle UserControl1 escrito em VB. Após importá-lo no Delphi, dois arquivos são gerados. Um deles, UserControl1_TLB.PAS, é o arquivo que queremos modificar.
Encontre algo assim em um arquivo
FintF:_UserControl1;
FunctionGetControlInterface:_UserControl1;
e
PRopertyControlInterface:_UserControl1readGetControlInterface;
GetControlInterface;
assim como
procedimentoTUserControl1.CreateControl;
procedimentoDoCreate;
começar
Finf:=IUnknown(OleObject)as_UserControl1;
Fim;
Começar
IfFinf=nilthenDoCreate;
Fim;
FunctionTUserControl1.GetControl1Interface:_UserControl1;
Começar
CriarControle;
Resultado:=Fimfl;
Fim;
Observação: todos os _UserControl1 marcados em vermelho aqui devem ser substituídos por _UserControl1Disp. Se a compilação não for bem-sucedida, substitua todos os _UserControl1 relatados no aviso de compilação por _UserControl1Disp e compile desta forma ao chamar o método de controle. ocorrer.
Obrigado por esta grande descoberta, só posso descrevê-la assim, caso contrário ainda poderia ficar preso neste círculo, ou teria que usar outra ferramenta para desenvolver novamente este controle (não consigo imaginar quanto trabalho isso vai dar , e Ou pode haver outros problemas de compatibilidade).
Delphi5 exceção fatal inexplicável 2
Porém, o Delphi não me deixou ir depois que eu contornei essa restrição. Logo, o cliente descobriu outro problema problemático. No ambiente de desenvolvimento, uma exceção aparecia toda vez que o formulário contendo o controle era fechado em tempo de execução. não acontece no aplicativo compilado, embora não afete o uso dos usuários finais, mas é um grande problema para os desenvolvedores. Então tentei usar o exemplo acima e descobri que isso não aconteceu. (Eu enlouqueci na época. Isso provavelmente foi causado por algum uso incompatível no código. Foi extremamente assustador descobrir se dezenas de milhares de linhas de código eram regulares em um dia.) Num acesso de raiva, bloqueei o controle no meu controle. Todo o código, deixando apenas a interface do usuário em si, e então algo estranho aconteceu, eu não escrevi nenhum código, mas Esse erro ainda ocorre ao carregar meu controle, o que me deixa feliz e surpreso é que esse problema não tem nada a ver com meu código, então será muito mais fácil de encontrar. abandonar alguns padrões nos controles VB pode realmente causar erros horríveis. A contradição entre Delphi5 e VB6 não é tão profunda. Nas 2 horas seguintes, continuei excluindo controles na interface para testar quem causou essa exceção fatal.
Depois de 2 horas, respirei aliviado e descobri o problema fundamental:
Se você usar controles de contêiner como Frame e PictureBox (que podem conter outros controles dentro) em controles de usuário VB, você não será capaz de adicionar controles windowLess como Label, Line e Image a esses controles (ou seja, nenhum controle Window, eles são desenhados pelo VB em tempo real durante a execução), caso contrário você receberá o relatório de erro como o acima.
Controles ActiveX ocultos no Delphi6 e 7
Precisamente por causa da experiência horrível no Delphi5, achei ainda necessário testar se o mesmo problema existe no Delphi6 e 7 (a versão anterior não é mais necessária porque há poucos usuários e o Delphi8 ainda não foi lançado oficialmente, então não está disponível no momento não são considerados). O resultado é: ...não importa quantas vezes eu carregue, nunca encontro aquele pequeno ícone tão esperado na barra ActiveX. Esse resultado é claro que é muito engraçado, não consigo nem carregá-lo, muito menos se o teste está normal ou não.
Da mesma forma, pesquisei em vários fóruns e sites e encontrei mais pessoas fazendo perguntas semelhantes no CSDN, mas a resposta ainda era zero. Em desespero, tive que ajustar as opções em cada Delphi6 e 7...
Depois de 3 horas, 15 minutos e 54 segundos, encontrei a causa, ou a solução, desse maldito problema (por favor, perdoe-me por chamá-lo assim, simplesmente não conseguia suportar), o que na verdade é muito simples.
Agora, por favor, siga-me: clique no menu Ferramentas->EnvironmentOptions->TypeLibrary, devemos encontrar um item: IgnorespecialCoClassFlagsWhenImporting, selecione-o e selecione o item CanCreate, então agora, vamos tentar importar aquele controle ActiveX ruim (deve ser observe aqui que se você o importou uma vez, exclua os dois arquivos gerados, arquivos .dcr e .pas, caso contrário, ele não será atualizado). Se desta vez você ainda não conseguir encontrar o controle na coluna ActiveX, então terá que ligar para a Microsoft ou Borland e perguntar quando eles podem se casar, haha!
(Além disso, os erros acima que apareceram no Delphi5 não foram encontrados no Delphi6 e 7)
Meu ambiente de teste é:
Win2K
Delphi5Atualização1
Delphi6Atualização2
Delphi7