MFC Dialog aus C++ aufrufen

Lexx84

Grünschnabel
Hallo,
ich habe ein MFC-Projekt, das ich in VS2008 als statische Lib erstellt habe.
Diese Lib habe ich (nach einigen Linker-Errors) auch in mein C++ - Projekt einbinden können.
Jetzt zu meiner Frage: Ist es möglich, aus dem C++ - Projekt heraus ein komplettes MFC-Projekt zu starten? Und wenn ja, wie? Einen klassischen Startpunkt wie main() hat MFC ja nicht. Ich habe es schon auf diverse Arten versucht (InitInstance(); Hauptdialog.doModal() ) ... aber jedesmal bringt er mir Assertion - Fehler da ich wohl das Projekt nicht richtig starte.
Vielleicht kann mir hier jemand helfen?
Falls diese Infos noch nicht ausreichen, kann ich auch noch etwas Code posten :)
Vielen Dank
 
Du könntest auch einmal die Fehlermeldung posten.

MFC hat übrigens auch ein main (WinMain), das allerdings schon vorgefertigt ist, nicht in deinem Quelltext steht und über Umwege InitInstance etc aufruft.
 
Zuletzt bearbeitet:
Gut, dann zähl ich mal meine Versuche und die dazugehörigen Fehlermeldungen auf.

1. Versuch
Im C++ Projekt direkt versuchen das MFC-Projekt aufzurufen

C++:
Code:
void main()
{
	CWinApp* App = new CWinApp();
	App = AfxGetApp();
	App->InitInstance();
}

Kommt zwar keine Fehlermeldung, aber App ist leer (Meldung: Schlechtes Pointing), von daher kommen auch keine MFC-Fenster.

2. Versuch
Versuchen AfxGetApp im MFC-Projekt zu bekommen:

Code:
void main()
{
	CWinApp* App = new CWinApp();
	CTabExample1App::GetTheApp(App);
	App->InitInstance();
}

Wobei CTabExample1App mein MFC-Projekt ist.
Innerhalb des MFC Projektes sieht das dann so aus:

Code:
void CTabExample1App::GetTheApp(CWinApp* App)
{
	App = AfxGetApp();
}

Wenn ich nun die Zeile
Code:
App->InitInstance();
ausführen lasse kommt ein Debug Assertion Fehler in appcore.cpp in der Zeile
Code:
ASSERT(AfxGetThread() == NULL);

Kann mir jemand helfen, CWinApp richtig aufzurufen?
Vielen Dank
 
Moment, ich such mal Code...

Also erstens bist du mit main und einem Konsolenprojekt bei MFC falsch.

Mach eine Win32-Anwendung (oder wie es auch immer heißt).

Das generierte main sollte jedenfalls WinMain heißen.

Die Standardmethode zum MFC-Starten sieht dann wie folgt aus:

C++:
ASSERT(hPrevInstance == NULL);

	int nReturnCode = -1;
	CWinThread* pThread = AfxGetThread();
	CWinApp* pApp = AfxGetApp();

	// AFX internal initialization
	if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
		goto InitFailure;

	// App global initializations (rare)
	if (pApp != NULL && !pApp->InitApplication())
		goto InitFailure;

	// Perform specific initializations
	if (!pThread->InitInstance())
	{
		if (pThread->m_pMainWnd != NULL)
		{
			TRACE0("Warning: Destroying non-NULL m_pMainWnd\n");
			pThread->m_pMainWnd->DestroyWindow();
		}
		nReturnCode = pThread->ExitInstance();
		goto InitFailure;
	}
	nReturnCode = pThread->Run();

InitFailure:
#ifdef _DEBUG
	// Check for missing AfxLockTempMap calls
	if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
	{
		TRACE1("Warning: Temp map lock count non-zero (%ld).\n",
			AfxGetModuleThreadState()->m_nTempMapLock);
	}
	AfxLockTempMaps();
	AfxUnlockTempMaps(-1);
#endif

	AfxWinTerm();
	return nReturnCode;
 
Zuletzt bearbeitet:
So, ich hab das jetzt mal nach sheel´s Vorgaben eingebaut, hab aber nur einen Teilerfolg verbuchen können. Meine neu erstellte WinMain sieht jetzt folgendermaßen aus:
Code:
//WinMain
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
   UNREFERENCED_PARAMETER(hPrevInstance);
   UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Hier Code einfügen.

    ASSERT(hPrevInstance == NULL);
 
    int nReturnCode = -1;
    CWinThread* pThread = AfxGetThread();
    CWinApp* pApp = AfxGetApp();
	CTabExample1App::GetTheApp(pApp, pThread);
 
    // AFX internal initialization
    if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
        goto InitFailure;
 
    // App global initializations (rare)
    if (pApp != NULL && !pApp->InitApplication())
        goto InitFailure;
 
    // Perform specific initializations
    if (!pThread->InitInstance())
    {
        if (pThread->m_pMainWnd != NULL)
        {
            TRACE0("Warning: Destroying non-NULL m_pMainWnd\n");
            pThread->m_pMainWnd->DestroyWindow();
        }
        nReturnCode = pThread->ExitInstance();
        goto InitFailure;
    }
    nReturnCode = pThread->Run();
}

//In MFC:
void CTabExample1App::GetTheApp(CWinApp* pApp, CWinThread* pThread)
{
	pThread = AfxGetThread();
	pApp = AfxGetApp();
}
Jetzt habe ich das Problem, dass in Zeile 32 (in der pThread->pMainWnd->DestroyWindow(); aufgerufen wird) folgende Fehlermeldung kommt:
Code:
0xC0000005: Zugriffsverletzung beim Lesen an Position 0xcccccd34.
Kommentiere ich diese Zeile aus, läuft der Compiler durch ohne das MFC-Projekt zu starten. Was mache ich falsch? :(
 
Ungültiger Pointer.

Statt den goto´s solltest du einmal irgendwelche Dinge einbauen, die sich bemerkbar machen, wenn du schon kein InitFailure drin hast. Und dann schauen, wo er sich aufregt.
 
Das InitFailure: hab ich schon drinnen, hab nur vergessen es in den Code meines Post´s mit reinzunehmen :( Sorry!
Die AfxWinInit und die pApp-Prüfungen werden ohne InitFailure-Aufruf durchlaufen, nur mit dem pThread scheint er Probleme zu haben...
Wenn ich an der DestroyWindow() - Zeile anhalte, sieht man folgendes:
Code:
pThread->m_pMainWnd = 0x0012fce4 {CWnd hWnd=0x00000000}
 
Ich bin der Meinung, du solltest den Aufruf nicht selber schreiben, sondern das die MFC machen lassen. Im Grunde sollte es reichen, CWinApp zu instanziieren, dann läuft die Schoße von allein ab.
 
Ok, hab jetzt auch diesen Ansatz ausprobiert, geht aber nicht.
Ich bekomme zwei Assertion-Fehler:
Code:
ASSERT(AfxGetThread() == NULL);
und wenn ich weiterlaufen lasse (also nicht wiederholen) dann kommt noch
Code:
ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please
Von daher kann ich ja gar kein CWinApp - Objekt instanziieren, da die Beschränkung auf ein Objekt besteht.
Desweiteren bin ich jetzt verwirrt, welcher Weg führt denn nun zum Ziel?
Vielleicht hat das schon mal jemand gemacht und kann mir sagen, wie es funktioniert?
Bin für jede Hilfe dankbar.
 
Zurück