TN057: localização de componentes MFC

Observação

A nota técnica a seguir não foi atualizada desde que foi incluída pela primeira vez na documentação online. Como resultado, alguns procedimentos e tópicos podem estar desatualizados ou incorretos. Para obter as informações mais recentes, é recomendável que você pesquise o tópico de interesse no índice de documentação online.

Esta observação descreve alguns dos designs e procedimentos que você pode usar para localizar seu componente, seja um aplicativo, um controle OLE ou uma DLL que use MFC.

Visão geral

Há realmente dois problemas a serem resolvidos ao localizar um componente que usa o MFC. Primeiro, você deve localizar seus recursos: cadeias de caracteres, caixas de diálogo e outros recursos específicos do componente. A maioria dos componentes criados usando o MFC também inclui e usa vários recursos definidos pelo MFC. Você também deve fornecer recursos de MFC localizados. Felizmente, vários idiomas já são fornecidos pelo próprio MFC.

Além disso, seu componente deve estar preparado para ser executado em seu ambiente de destino (ambiente europeu ou habilitado para DBCS). Na maioria das vezes, isso depende de seu aplicativo tratar caracteres com o conjunto de bits mais significativo corretamente e manipular cadeias de caracteres com caracteres de bytes duplos. O MFC está habilitado, por padrão, para ambos os ambientes, de modo que é possível ter um só binário mundial usado em todas as plataformas com apenas recursos diferentes conectados no momento da instalação.

Como localizar os recursos do componente

A localização do aplicativo ou da DLL deve envolver simplesmente a substituição dos recursos por recursos que correspondem ao idioma de destino. Para seus recursos, isso é relativamente simples: edite os recursos no editor de recursos e compile seu aplicativo. Se o código for gravado corretamente, não haverá cadeias de caracteres ou texto a localizar embutida em código no código-fonte do C++: toda a localização pode ser feita simplesmente modificando recursos. Na verdade, você pode implementar seu componente de modo que fornecer uma versão localizada não envolva sequer um build do código original. Isso é mais complexo, mas vale a pena e é o mecanismo escolhido para o MFC em si. Também é possível localizar um aplicativo carregando o arquivo EXE ou DLL no editor de recursos e editando os recursos diretamente. Embora possível, isso requer a reaplicação dessas alterações sempre que você cria uma versão do aplicativo.

Uma forma de evitar isso é localizar todos os recursos em uma DLL separada, às vezes chamada de DLL satélite. Essa DLL é carregada dinamicamente em runtime e os recursos são carregados dessa DLL, em vez do módulo principal com todo o código. O MFC dá suporte direto a essa abordagem. Considere um aplicativo chamado MYAPP.EXE; ele pode ter todos os recursos localizados em uma DLL chamada MYRES.DLL. Na InitInstance do aplicativo, seguinte seria executado para carregar essa DLL e fazer com que o MFC carregasse recursos desse local:

CMyApp::InitInstance()
{
    // one of the first things in the init code
    HINSTANCE hInst = LoadLibrary("myres.dll");

    if (hInst != NULL)
        AfxSetResourceHandle(hInst);

    // other initialization code would follow
    // ...
}

Daí, o MFC carregará recursos dessa DLL em vez de carregá-los de myapp.exe. Porém, todos os recursos devem estar presentes nessa DLL; O MFC não pesquisará a instância do aplicativo na pesquisa de um determinado recurso. Essa técnica se aplica igualmente bem a DLLs MFC regulares, bem como a controles OLE. Seu programa de instalação copiaria a versão apropriada de MYRES.DLL dependendo de qual localidade de recurso o usuário gostaria.

É relativamente fácil criar uma DLL somente de recurso. Você cria um projeto de DLL, adiciona seu arquivo .RC a ele e adiciona os recursos necessários. Se você tiver um projeto que não usa essa técnica, poderá copiar os recursos desse projeto. Depois de adicionar o arquivo de recurso ao projeto, você está quase pronto para compilar o projeto. A única coisa que você deve fazer é definir as opções do vinculador para incluir /NOENTRY. Isso informa o vinculador de que a DLL não tem ponto de entrada; como ela não tem código, não tem ponto de entrada.

Observação

O editor de recursos no Visual C++ 4.0 e posterior dá suporte a vários idiomas por arquivo .RC. Isso pode tornar muito fácil gerenciar sua localização em um só projeto. Os recursos para cada idioma são controlados por diretivas de pré-processador geradas pelo editor de recursos.

Como usar os recursos localizados do MFC fornecidos

Qualquer aplicativo MFC que você compilar reutiliza duas coisas do MFC: código e recursos. Ou seja, o MFC tem várias mensagens de erro, caixas de diálogo internas e outros recursos que são usados pelas classes MFC. Para localizar completamente seu aplicativo, você precisa localizar não apenas os recursos do aplicativo, mas também os recursos que vêm diretamente do MFC. O MFC fornece vários arquivos de recursos de idioma diferentes automaticamente, assim, se o idioma que você está direcionando for um dos idiomas que o MFC já dá suporte, bastará usar esses recursos localizados.

No momento em que este texto foi escrito, o MFC dava suporte a chinês, alemão, espanhol, francês, italiano, japonês e coreano. Os arquivos que contêm essas versões localizadas estão nos diretórios MFC\INCLUDE\L.* (o 'L' significa localizado). Os arquivos em alemão estão em MFC\INCLUDE\L.DEU, por exemplo. Para fazer com que seu aplicativo use esses arquivos RC em vez dos arquivos localizados em MFC\INCLUDE, adicione um /IC:\PROGRAM FILES\MICROSOFT VISUAL STUDIO .NET 2003\VC7\MFC\INCLUDE\L.DEU à linha de comando RC (esse é apenas um exemplo; você precisaria substituir sua localidade de escolha, bem como o diretório no qual você instalou o Visual C++).

As instruções acima funcionarão se o aplicativo for vinculado estaticamente ao MFC. A maioria dos aplicativos é vinculado dinamicamente (porque esse é o padrão AppWizard). Nesse cenário, não apenas o código é vinculado dinamicamente, seus recursos também são. Como resultado, você pode localizar seus recursos em seu aplicativo, mas os recursos de implementação do MFC ainda serão carregados do MFC7x.DLL (ou de uma versão posterior) ou de MFC7xLOC.DLL se ele existir. Você pode abordar isso de dois ângulos diferentes.

A abordagem mais complexa é enviar um dos MFC7xLOC.DLLs localizados (como MFC7xDEU, para alemão, MFC7xESP.DLL para espanhol etc.) ou uma versão posterior e instalar o MFC7xLOC.DLL apropriado no diretório do sistema quando o usuário instalar seu aplicativo. Isso pode ser muito complexo tanto para o desenvolvedor quanto para o usuário final, portanto, não é recomendado. Confira a Nota Técnica 56 para mais informações sobre essa técnica e suas ressalvas.

A abordagem mais simples e segura é incluir os recursos de MFC localizados em seu aplicativo ou na própria DLL (ou em sua DLL satélite se você estiver usando uma). Isso evita os problemas de instalar MFC7xLOC.DLL corretamente. Para fazer isso, siga as mesmas instruções para o caso estático especificado acima (definindo a linha de comando RC corretamente para apontar para os recursos localizados), exceto que você também deve remover a definição /D_AFXDLL adicionada pelo AppWizard. Quando /D_AFXDLL é definido, AFXRES. H (e os outros arquivos RC do MFC) não definem nenhum recurso (porque eles serão extraídos das DLLs MFC).

Confira também

Observações técnicas por número
Observações técnicas por categoria