Probleme mit Sprach-Dlls



  • Hallo,

    ich versuche ein Programm (MFC-MDI mit VS9) mehrsprachig zu machen und hab dazu den entsprechenden Artikel auf der Seite durchgearbeitet (Dialogbasierend). Alles i.O. Nun wollte ich das ganze mit MDI machen und es klappt nicht: bei (Afx)LoadLibary läd er die dll nicht richtig. Die Funktion liefert aber auch nicht null zurück. Wie kann ich herausfinden wo der Fehler ist?
    Dazu ne Frage: was muss denn alles in der Resource dll drin sein? reicht der StringTable (und das Menü)?
    Ich hab noch von Martin Richter eine Seite gefunden wo ein SDI/MDI Projekt mehrsprachig ist http://www.mpdvc.de/artikel/MultilingualeProgramme.htm aber die Beschreibung dazu ist leider nicht immer eindeutig.
    Kenn noch jemand eine Seite, wo ein Beispiel oder eine Beschreibung für ein mehrsprachiges SDI/MDI projekt ist?

    Micha


  • Mod

    Was ist nicht eindeutig?
    Ob Dialog, oder SDI/MDI ist doch wurscht.

    Wenn AfxLoadLibrary fehl schlägt empfehle ich Dir GetLastError mal anzusehen um zu sehen was die Ursache ist. AfxLoadLibrary braucht gar von sich aus erstmal gar keine Ressourcen.

    Was meinst Du mit: "Lädt die DLL nicht richtig." Entweder wird sie geladen oder eben nicht...
    Schau doch selbst in die DL rein was drin ist. Öffne die DLL mit dem Ressourcen Editor von Visual-Studio. Vermutlich sind einfach die Ressourcen nicht drin, die benötigt werden.



  • Nicht eindeutig:
    Vieles ist (für Dummies wie mich) nicht genau beschrieben. Aber OK.

    GetLastError gibt 0 zurück. Also scheinbar i.O. der enstsprechende String ändert sich aber nicht.

    DWORD err;
    hDll = AfxLoadLibrary(_T("deutsch.dll"));
    err=GetLastError();  //err=0
    

    die benötigten Resourcen...
    mein Projekt hat ja noch mehr Resourcen als ein Stringtable. An sich muss ich nur das Menü und den Stringtable übersetzen und in die DLL packen. Ist das machbar? Muss die ganze Stringtable 1:1 kopiert werden, oder reicht es die benötigten Strings(mit gleichen Werten) in die DLL zu packen.
    Was ist eigentlich mit den Buttons in automatisch erstellten Dialogen (MessageBox, CFileDialog,...). Bekommen IDOK und IDCANCEL die Beschriftung in der jeweiligen OS-Sprache?

    Micha


  • Mod

    der_micha1981 schrieb:

    mein Projekt hat ja noch mehr Resourcen als ein Stringtable. An sich muss ich nur das Menü und den Stringtable übersetzen und in die DLL packen. Ist das machbar?

    Das ist in meinem Artikel beschrieben.
    Du musst die Common Ressourcen auch in jede DLL packen. Es gibt kein Fallback in dem Sinne: Findest Du die ressource hier nicht, suche in der EXE...

    der_micha1981 schrieb:

    Muss die ganze Stringtable 1:1 kopiert werden, oder reicht es die benötigten Strings(mit gleichen Werten) in die DLL zu packen.

    Verstehe ich niciht. Alles muss rüber. Zu jeder Ressourcen ID muss ein entsprechender Eintrag für jede Sprache vorhanden sein.

    der_micha1981 schrieb:

    Was ist eigentlich mit den Buttons in automatisch erstellten Dialogen (MessageBox, CFileDialog,...). Bekommen IDOK und IDCANCEL die Beschriftung in der jeweiligen OS-Sprache?

    Nein! Die kommen aus dem OS und werden in der Sprache angezeigt, die der Nutzer gewählt hat (MUI, oder eben nur eine Sprache installiert).



  • Martin, ich hab dein Artikel soweit durchgearbeitet und geschafft. Grob funktioniert es auch. Es gibt aber noch ein Problem:

    Es Scheint, die afxres.rc und afxprint.rc werden nicht ordentlich includiert. Beim Klicken auf Datei/Öffnen oder Druckvorchau kommt ein ASSERT. Es liegt dann daran, das bei einem LoadString die Ressource nicht bekannt ist (z.B. beim Öffnen ist AFX_IDS_OPENFILE 0xF000 unbekannt).
    Bei der exe .rc hab ich den Part so belassen:

    #ifndef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    ...
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    LANGUAGE 9, 1
    #pragma code_page(1252)
    #include "res\MyExe.rc2"  // Nicht mit Microsoft Visual C++ bearbeitete Ressourcen
    #include "afxres.rc"          // Standardkomponenten
    #include "afxprint.rc"        // Ressourcen für Drucken/Seitenansicht
    #endif
    /////////////////////////////////////////////////////////////////////////////
    #endif    // not APSTUDIO_INVOKED
    

    bei den SprachDLLs entsprechend angepasst.

    Wieso findet er die Ressourcen nicht?

    Micha


  • Mod

    Hast Du mal die DLL im Ressourcen-Editor angesehen. Ist die Ressource drin?



  • Also wenn du meinst, das ich die fertige DLL mit VS öffne dann sind da nur die Ressourcen drin, welche auch im Hauptprojekt erscheinen plus RT_MANIFEST. Also nein. afxres.rc und afxprint.rc waren bei mir noch nie in einem Ressourceneditor zu sehen, sondern nur in der .rc des Projektes (exe/dll). Was muss ich denn da machen?
    (Vielleicht wichtig: ursprünglich war die exe ein deutsches Projekt. Ich hab aber, so denke ich, alles auf ENU umgestellt.)

    Noch eine Frage: Ich hab die exe statisch zur MFC gelinkt, da ich das Programm auf Rechnern ausführen möchte, wo keine Entwicklungsumgebung installiert ist. Die dlls sind dynamisch gelinkt. Ist es richtig, das die DLLs nicht auf "normalen" rechnern laufen werden? Wenn ja: recht es das linken auf statisch umzustellen um das Problem zu lösen?

    Micha


  • Mod

    Ist AFX_TARG_ENU auch in den Projekteinstellungen für den Ressourcen-Compiler definiert?

    Gemäß meiner Beschreibung sollte das folgende definiert sein für Englisch:

    AFX_RESOURCE_DLL;AFX_TARG_NEU;AFX_TARG_ENU
    


  • Ja, so hab ichs gemacht.


  • Mod

    Dann wird aber entweder dieser Block nicht kompiliert oder der #ifdef greift nicht.
    Mehr kann ich dazu auch nicht sagen.
    Bau mal einen Fehler in diesen Block.

    Bist Du sicher, dass Du Release/Debug Version gleichermaßen behandelt hast?



  • Ja debug und release sind gleich.

    welchen zweck hat eigentlich die definition von AFX_RESSOURCE_DLL ? in der .rc hat #ifdef !(AFX_RESSOURCE_DLL) immer 0. Dann kann ich die doch auch weglessen?!

    ich hab etwas rumprobiert und in testprojekten hatte es keinen einfluss, ob ich in der afxres.rc und afxprint.rc noch diverse sprachen versucht einzustellen (l.CHS\...Chinesisch). es kommen immer deutsche dialoge.
    Muss ich bei den Fremdsprachen noch etwas beachten?
    in den DLLs ist übrigens nichts von afxres und afxprint zu sehen. sollte ich da irgendwas zu sehen?

    Edit:
    vielleicht bedeutunglos: In einer Dialogbar hab ich ein Editfeld. Im rc, was die exe automatisch erstellt steht da

    IDD_DIALOGBAR DIALOGEX 0, 0, 502, 42
    STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
    FONT 8, "MS Shell Dlg", 400, 0, 0x0
    BEGIN
        CONTROL         "Button1",IDC_BUTTON_PREV,"Button",BS_OWNERDRAW | WS_TABSTOP,12,1,21,17
        EDITTEXT        IDC_SHOWNDS,34,1,40,17,ES_CENTER | ES_AUTOHSCROLL
        CONTROL         "Button2",IDC_BUTTON_NEXT,"Button",BS_OWNERDRAW | BS_BITMAP | WS_TABSTOP,74,1,22,17
        EDITTEXT        IDC_EDIT_DLGBAR,356,2,137,12,0,0,[b]HIDC_EDIT_DLGBAR/b]
    CONTROL         "Statist",IDC_BUTTON_STATISTIK,"Button",BS_OWNERDRAW,98,1,22,17
    END
    

    kopiere ich die rc und füge sie in die DLL ein kommt beim kompilieren die Meldung das HIDC_EDIT_DLGBAR nicht definiert ist. Ich weiß nicht was das HIDC sein soll. sie taucht bei mir nigends anders auf. Ich hab kurzerhand alles hinter der 12 in der Zeile auskommentiert. so ist das erstellen der DLLs dann möglich.

    Micha



  • So, ich hab da was gefunden:
    in den afxres und afxprint.rc wird

    #ifndef _AFXDLL
    

    abgefragt und dann erst die Ressourcen eingebunden.
    um das zu erreichen hab ich ein #undef _AFXDLL eingefügt.

    Martin, ich will noch fragen, wie genau du das erstellen der primären Sprache von statten geht:
    "...Wir legen hier eine leere RC Datei an." Meinst du mit leer absolut leer oder standard erstellt leer?
    ->Also ich hab die Standard dll.rc Datei gelassen, VersionInfo gelöscht und die exe.rc includiert hier die primär SprachDll.rc:

    #ifndef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    #define _AFX_NO_SPLITTER_RESOURCES
    #define _AFX_NO_OLE_RESOURCES
    #define _AFX_NO_TRACKER_RESOURCES
    #define _AFX_NO_PROPERTY_RESOURCES
    
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
    LANGUAGE 7, 1
    #pragma code_page(1252)
    #include "exe.rc"        //hier exe.rc includiert
    #include "res\DEUz.rc2"  // Nicht mit Microsoft Visual C++ bearbeitete Ressourcen
    //#undef _AFXDLL
    //#include "l.DEU\afxres.rc"      // Standardkomponenten
    //#include "l.DEU\afxprint.rc"        // Ressourcen für Drucken/Seitenansicht
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    #endif    // not APSTUDIO_INVOKED
    

    der Teil in der exe.rc sieht so aus:

    #ifndef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    #define _AFX_NO_SPLITTER_RESOURCES
    #define _AFX_NO_OLE_RESOURCES
    #define _AFX_NO_TRACKER_RESOURCES
    #define _AFX_NO_PROPERTY_RESOURCES
    
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
    LANGUAGE  7,1
    #pragma code_page(1252)
    #include "res\ZFG3000.rc2"  // Nicht mit Microsoft Visual C++ bearbeitete Ressourcen
    #undef _AFXDLL
    #include "l.DEU\afxres.rc"          // Standardkomponenten
    #include "l.DEU\afxprint.rc"        // Ressourcen für Drucken/Seitenansicht
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    #endif    // not APSTUDIO_INVOKED
    

    Ist der Code so i.O.?
    Es ist aber noch nicht alles supi, denn ich bekomm jetzt ASSERTS beim aufruf von GetDlgItem die früher nicht da waren:
    Das beim OnInitDialog einer Dialogbar. Alles aber nach LoadLibrary. Hast du eine Idee, was es ist?

    Das ist ganz schön nervend...

    Micha


  • Mod

    Ja. So ähnlich. Schau Dir das Sample an, von dem Artikel.
    Diese Basis-Sprachen-DLL ist tatsächlich leer bis eben auf die includes der anderen RC.

    Wenn es ASSERTs gibt, dann hast Du vermutlich unterschiedliche Ressource.h Dateien in Benutzung! Dadurch verändern sich die Dialog internen IDs je nach DLL. Das mag die EXE natürlich nicht.



  • Also Stichprobenartiges vergleichen der Dll IDs hat gezeigt, das die richtigen IDs vergeben wurden.

    Dein Beispiel ist da ja schon etwas anders als in deinem Artikel beschrieben.
    Die exeResource.h gibt es nicht und dafür steht in der enuResource.h alles drin. Dann klappt aber das Erstellen der Exe nicht.
    Kannst du mir bitte mal kurz sagen, wie sie das mit den resourcen verhält?

    Micha


  • Mod

    Also zu jeder Resourceen Datei (RC Datei) gehört eine Header Datei. Ohne geht nicht.

    Nehmen wir mal an Du baust eine Basic.rc Datei. Dann könnest Du dieser im Ressourcen Editor auch die BasisRes.h Datei zuordnen.
    Dieses BasisRes.h muss las Readonly include von allen anderen Sprachen Ressourcen-Dateien benutzt werden.
    - Nehmen wir mal an die Basissprache ist ENU.
    Dann hättest Du eine ENU.RC mit der ENURes.h, die beide leer sind und nur die Basis.rc und Basisres.h includen.
    - Jetzt baust Du DEU
    Dann hättest Du eine DEU.RC mit der DEURes.h. Die DEURes.h ist leer. Die BasisRes.h wird als Readonly Header definiert.
    - So geht das mit jeder weiteren Sprache.

    So ist es auch um Artikel gemeint.



  • OK, hab den Fehler gefunden:

    1. also das #undef _AFXDLL hat gefehlt, damit die afxres und afxprint eingebunden werden und
    2. Eine IDD_DIALOGBAR (103) welche ich in meinem Projekt vergeben hatte ist mit der Toolbar der Druckvorschau (30723) "kollidiert". Ein Umbenennen der IDD_DIALOGBAR in IDD_MYDIALOGBAR hat ausgereicht den Fehler zu beheben.

    Danke Martin für deine Unterstützung
    Micha


Anmelden zum Antworten