Changer le texte des ressources à l’exécution

Dans cet article je vous expliquerai comment changer le texte contenu dans les ressources de C++Builder pendant l’exécution de votre programme. Si vous concevez une application multilingue, cette technique sera pratique.

Dans votre fichier d’en-tête, ajoutez la déclaration suivante:

    void __fastcall HookResourceString(TResStringRec& ResStringRec, Char* StrID);

Voici la méthode à ajouter à votre code:

void __fastcall TForm1::HookResourceString(TResStringRec& ResStringRec, Char* StrID)
{
    DWORD OldProtect;

    VirtualProtect(&ResStringRec, sizeof(ResStringRec), PAGE_EXECUTE_READWRITE, &OldProtect);
#if __BORLANDC__ >= 0x630
    // Pour C++Builder XE et plus
    ResStringRec.Identifier = Integer(StrID);
#else
    ResStringRec.ident = Integer(StrID);
#endif
    VirtualProtect(&ResStringRec, sizeof(ResStringRec), OldProtect, &OldProtect);
}

Le code est assez simple: on change la protection sur ResStringRec pour que l’on puisse y mettre un pointeur vers la chaîne de caractères StrID. Lorsque la modification est terminée, on remet la protection précédente.

Il est à noter que la structure TResStringRec n’est pas la même sur C++Builder 2010 et C++Builder XE. Étant donné que je n’ai pas d’autre version à ma disposition, je n’ai pas pu les vérifier.

Sur C++Builder 2010:

struct PACKAGE TResStringRec
{
    long *module;
    long ident;
};

Sur C++Builder XE:

struct DECLSPEC_DRECORD TResStringRec
{
public:
    unsigned *Module;
    int Identifier;
};

Voici un exemple d’utilisation avec la fonction MessageDlg:

HookResourceString(_SMsgDlgConfirm, L"Mon titre");
HookResourceString(_SMsgDlgYes, L"Absolument");
HookResourceString(_SMsgDlgNo, L"Pas du tout");
HookResourceString(_SMsgDlgCancel, L"Laisse faire");

MessageDlg("Veux-tu faire quelque chose?", mtConfirmation,
        TMsgDlgButtons() << mbYes << mbNo << mbCancel, 0, mbCancel);

Le premier paramètre de la méthode est le nom de la ressource qui correspond aux noms que l’on retrouve dans le fichier Consts.hpp. Donc, il est important d’inclure ce fichier d’en-tête dans votre code. Si vous êtes intéressés à connaître le texte original, alors je vous conseil de jeter un coup d’œil au fichier Consts.pas.

Je vous laisse avec un capture d’écran du résultat.
Boite de dialogue personnalisée