Dynamische/Statische MFC-Einbindung



  • Na hallo zusammen,

    ich habe mal wieder ein Problem, was ich nicht so ganz verstehe. Besser gesagt verstehe ich die MFC da nicht so richtig.

    Und zwar erstelle ich mir in meinem Programm aehnlich wie die Print_Preview von Code-Project eine neue CView zum Drucken:

    CFrameWnd* pOldFrame=(CFrameWnd*)AfxGetThread()->m_pMainWnd;
    
    m_pTemplate = new CSingleDocTemplate(IDR_DPV,NULL,RUNTIME_CLASS(CFrameWnd),RUNTIME_CLASS(CRVSDruckView));
    AfxGetApp()->AddDocTemplate(m_pTemplate);
    
    CFrameWnd *pFrameWnd = m_pTemplate->CreateNewFrame(NULL,NULL);
    m_pTemplate->InitialUpdateFrame(pFrameWnd,NULL);
    
    CRVSDruckView* pView=(CRVSDruckView*)pFrameWnd->GetActiveView();
    pView->m_pOldFrame=pOldFrame;
    if(todo) pView->OnFilePrintPreview();
    else 
    {
       pFrameWnd->ShowWindow(SW_HIDE);
       pView->OnFilePrint();
    }
    

    Wenn ich das ganze mit dynamisch eingebundener MFC-DLL kompiliere, dann klappt auch alles, aber wenn ich es auf statisch eingebundene MFC einstelle, dann kommt immer eine Fehlermeldung wenn er das OnFilePrintPreview() aufruft, was uebrigens nichts andres macht, als die OnPrintPreview() der CView aufzurufen!

    Und zwar meckert er da immer herum, dass ein DialogTemplate nicht initalisiert werden kann. Da verstehe ich erstens nicht, was bei einer CView ein DialogTemplate zu suchen hat und zweitens auch nicht, warum das nur bei statischer Einbindung auftritt und bei dynamischer Einbindung alles einwandfrei funktioniert!

    Kann mir da jemand einen Tip geben?!
    Vielen Dank schonmal!


  • Mod

    Du hast evtl. die Standard Ressourcen nicht eingebunden "afxres.rc"?



  • Martin Richter schrieb:

    Du hast evtl. die Standard Ressourcen nicht eingebunden "afxres.rc"?

    Danke erstmal fuer den Tip, aber irgendwie komme ich damit nicht klar.
    Hatte sie nicht eingebunden, war irgendwie bisher nicht noetig. Wenn ich sie jetzt mit einbinde, dann kommen verdammt viele Fehlermeldungen.
    Hier mal nur ein Auszug:

    c:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxres.rc(36) : error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'DISCARDABLE'
    c:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxres.rc(36) : error C2501: 'STRINGTABLE': Fehlende Speicherklasse oder Typspezifizierer
    c:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxres.rc(38) : error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'BEGIN'
    c:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxres.rc(38) : error C2501: 'DISCARDABLE': Fehlende Speicherklasse oder Typspezifizierer
    c:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxres.rc(38) : error C2143: Syntaxfehler: Es fehlt ';' vor 'constant'
    c:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxres.rc(38) : error C2501: 'BEGIN': Fehlende Speicherklasse oder Typspezifizierer
    

    Ich habe versucht sie in der "Hauptheaderdatei der Anwendung" einzubinden, oder muss man das woanders machen??


  • Mod

    Wir hast Du es denn gemacht? Hast Du die afxres.rc in Deine eigene rc Datei über die Resource Includes hinzugefügt?



  • Naja, da ich ehrlich gesagt keine Ahnung hab, wie man so eine Resource-Datei einbindet, habe ich es einfach mit #include "afxres.rc" in meiner Hauptheader-Datei eingebunden.

    Waere Dir wirklich sehr dankbar, wenn Du mir mal beschreibst, wie ich es machen muss! 😕



  • Ich habe gerade mal detailierter nachgesehen.
    In meiner Resource-Datei steht doch schon ein

    #include "afxres.h"
    

    und weiter unten dann auch noch

    "#include ""afxres.rc""
    

    Scheint also doch dabei zu sein...



  • So, habe nochmal intensiv den Debugger laufen lassen.
    Hier mal meine Erkenntnisse:
    Wie schon gesagt, tritt der Fehler ja beim Aufrufen der CView eigenen Funktion OnFilePrintPreview() auf.
    In dieser besagen OnFilePrintPreview() der CView (das sind jetzt Code-Ausschnitte aus der viewprew.cpp direkt aus der MFC) wird dann eine CDialogBar erstellt:

    // Create the toolbar from the dialog resource
    pView->m_pToolBar = new CDialogBar;
    

    Ein paar Zeilen spaeter wird die DialogBar dann auch initialisiert:

    if (!pView->m_pToolBar->Create(pParent, MAKEINTRESOURCE(nIDResource),CBRS_TOP, AFX_IDW_PREVIEW_BAR))
    

    Und dort tritt dann der Fehler in der Create-Funktion auf, genauer bei:

    if (!_AfxCheckDialogTemplate(lpszTemplateName, TRUE))
    {
    	ASSERT(FALSE);          // invalid dialog template name
    	PostNcDestroy();        // cleanup if Create fails too soon
    	return FALSE;
    }
    

    So, und zu guter Letzt passiert in der AfxCheckDialogTemplate folgendes:

    BOOL AFXAPI _AfxCheckDialogTemplate(LPCTSTR lpszResource, BOOL bInvisibleChild)
    {
    	ASSERT(lpszResource != NULL);
    	HINSTANCE hInst = AfxFindResourceHandle(lpszResource, RT_DIALOG);
    	HRSRC hResource = ::FindResource(hInst, lpszResource, RT_DIALOG);
    	if (hResource == NULL)
    	{
    		if (DWORD_PTR(lpszResource) > 0xffff)
    			TRACE(traceAppMsg, 0, _T("ERROR: Cannot find dialog template named '%s'.\n"),
    				lpszResource);
    		else
    			TRACE(traceAppMsg, 0, "ERROR: Cannot find dialog template with IDD 0x%04X.\n",
    				LOWORD((DWORD_PTR)lpszResource));
    		return FALSE;
    	}
    

    Die uebergebene Variable lpszResource ist dabei eine Resource mit der ID 30723, und zwar sowohl bei dynamisch gelinkter MFC als auch bei statisch eingebundener! Merkwuerdigerweise scheint diese ID im dynamischen Fall vorhanden zu sein, im statischen Fall aber nicht auffindbar(hResource==NULL). Im bezweifle zwar, dass jemand diese Resource-ID kennt, aber vielleicht kann mir ja doch jemand sagen, wozu die gehoert bzw. wo die auftaucht?!

    Ansonsten habe ich auf diese Funktionen ja keinen Einfluss, da sie direkt in der MFC ablaufen und nicht in meinem Quelltext. Von daher verstehe ich auch nicht, was das Problem ist, nur wenn ich die MFC statisch einbinde?!
    Ich weiss auch nicht genau, was das fuer eine DialogBar sein soll. Theoretisch kann es ja hoechstens die ToolBar sein, mit ganz links "Drucken", danach irgendwas mit "Druckeinstellungen", "Vergroessern", "Verkleinern", ...

    Eventuell hilft diese Praezisierung jemanden ja dabei, mir einen Tip zu geben, was ich noch ausprobieren kann, um es hinzubekommen!


  • Mod

    Die kennt jeder: 🤡
    #define AFX_IDD_PREVIEW_TOOLBAR 30723
    in afxres.h!

    Ich kann mich nur wiederholen. Deine Resourcen für die MFC werden nicht eingefügt! Evtl. Musst Du afxprint.rc separat in Deine Ressourcen includes aufnehmen.

    Erzeuge doch mal ein neues Projekt mit Druck Features und statischer Bindung an die MFC und schau dir die MFC Datei an.



  • Mir ist sie noch nicht ueber den Weg gelaufen. 🙂

    Vielen Dank fuer Deine Hilfe! Ich bin letzte Nacht auch auf die "afxprint.rc" gestossen und nach deren Einbindung lief es dann; hab die Toolbar jetzt zwar in Englisch, aber das kann man ja noch aendern. War dann nur zu muede und hab's nicht gleich reingeschrieben, dass es daran liegt.

    Trotzdem vielen Dank!


  • Mod

    #include "l.deu\afxprint.rc"



  • Danke!! Werde ich dann gleich mal ausprobieren! 🙂



  • Muß mich auch mal bedanken, habe/hatte das gleiche Problem aber jetzt läuft es.

    Gruß


Anmelden zum Antworten