Zeiger auf Dialog löschen
-
Mit Callstack meinst du die Aufrufliste. (Armes Deutschland)
Ok und darin sehe ich dass PostNCDestroy von der Funktion CWnd::OnNcDestroy() aus wincore.cpp aufgerufen wird und diese wiederum von CWnd::OnWndMsg(...) und nun. Das sagt mir leider immer noch nichts.
Wie kann ich den mein mini beispiel hochladen. Muss ich mich registrieren?
-
Zeigt der Callstack nicht mehr?
Komisch. Vermutlich lädst Du nicht alle Debug Infos für die Systemdateien.
Lade es irgendwohin und gib mir den Link!
-
Ok. Konnte jetzt erst antworten da ich in meiner Firma nicht uploaden darf.
Also hier der Link. Projekt für Visual Studio 2008.http://www.file-upload.net/download-2146695/Dialogtest.zip.html
-
Das ist doch Unfug was Du machst. Wenn Dein Prozess terminiert, dann muss Dir doch klar sein, dass alle Fenster aufgeräumt werden. Und das macht Windows bevor die DLLs alle entladen werden.
Das zeigt auch der Stacktrace:
> DialogDll.dll!CDialogDllApp::ExitInstance() Line 76 C++ DialogDll.dll!InternalDllMain(HINSTANCE__ * hInstance=0x665d0000, unsigned long dwReason=0, void * __formal=0x00000001) Line 155 C++ DialogDll.dll!DllMain(HINSTANCE__ * hInstance=0x665d0000, unsigned long dwReason=0, void * lpReserved=0x00000001) Line 272 C++ DialogDll.dll!__DllMainCRTStartup(void * hDllHandle=0x665d0000, unsigned long dwReason=0, void * lpreserved=0x00000001) Line 546 + 0x11 bytes C DialogDll.dll!_DllMainCRTStartup(void * hDllHandle=0x665d0000, unsigned long dwReason=0, void * lpreserved=0x00000001) Line 510 + 0x11 bytes C ntdll.dll!_LdrpCallInitRoutine@16() + 0x14 bytes ntdll.dll!_LdrShutdownProcess@0() - 0x96 bytes ntdll.dll!_RtlExitUserProcess@4() + 0x74 bytes kernel32.dll!75952ae4() msvcr90d.dll!__crtExitProcess(int status=0) Line 732 C msvcr90d.dll!doexit(int code=0, int quick=0, int retcaller=0) Line 644 + 0x9 bytes C msvcr90d.dll!exit(int code=0) Line 412 + 0xd bytes C Dialogtest.exe!__tmainCRTStartup() Line 599 C Dialogtest.exe!WinMainCRTStartup() Line 403 C kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
-
Das ist doch Unfug was Du machst.
Ok, danke für deine klare Aussage. Ja soory Profi in MFC darf ich mich leider noch nicht nennen.
Welche Zeile sagt mir das genau im StacktraceAber was eigentlich noch viel wichtiger ist. Wie löse ich das Problem nun?
-
Du kannst hier dirrekt auf den CRT Sartup Code springen und sieht dort, dass hier das Programm beendet wird.
msvcr90d.dll!exit(int code=0) Line 412 + 0xd bytes C Dialogtest.exe!__tmainCRTStartup() Line 599 C
Dein Fehler ist es, dass Du aufräumst, wenn die DLL entladen wird.
Da das entladen zudem noch aus jedem beliebigen Thread erfolgen kann, vergrößert das Problem noch.Bau eine explizite Funktion für die DLL die aufräumt (Code hast Du ja schon in ExitInstance). Diese musst Du dann aus der EXE aufrufen.
ExitInstance und InitInstance in einer DLL werden direkt aus DllMain aufgerufen. Daduch gibt es alle relevanten Einschränkungen die eben auch für DllMain gelten.
-
Also erst mal danke für deine Hilfe.
Bau eine explizite Funktion für die DLL die aufräumt (Code hast Du ja schon in ExitInstance). Diese musst Du dann aus der EXE aufrufen.
Genau hier liegt noch ein Problem. Und zwar wird diese DLL nicht von einer exe verwendet sondern von einem anderen System. System nennt sich WinCC von Siemens. Ein Tool für die Visualisierung in der Automatisierung. Wenn nun die erstellte Benutzeroberfläche z.B. über einen Button beendet wird kann sehr wohl eine Funktion aufgerufen werden um die DLL zu entladen. Allerdings wenn das System über den Stop Button des Entwicklungs- und Startexplorer heruntergefahren wird, ist es nicht mehr möglich eine Funktion auszuführen. Das System wird einfach beendet und die DLL entladen.
-
Also jetzt habe ich die Funktionalität mal in eine Exportfunktion der DLL gepackt:
extern "C" __declspec(dllexport) void DeleteDialogs() { SendMessage(theApp.m_myDialog1->m_hWnd,WM_APPDLG,NULL,NULL); SendMessage(theApp.m_myDialog2->m_hWnd,WM_APPDLG,NULL,NULL); SendMessage(theApp.m_myDialog3->m_hWnd,WM_APPDLG,NULL,NULL); }
und die Funktion von ExitInstance aus meinem Testprogramm aufgerufen.
int CDialogtestApp::ExitInstance() { DeleteDialogs(); return CWinAppEx::ExitInstance(); }
Dann tritt genau das selbe Problem auf.
-
Man. So ein Mist. Wie bekomme ich den das Problem gelöst? Hilffeee!
-
Vieleicht hat ja irgenwann ja doch wieder Lust mir zu antworten. Wieso darf ich in ExitInstance der DLL einen Dialog so beenden:
m_myDialog->DestroyWindow(); delete m_myDialog;
Dort sollte ich doch dann genau das selbe Problem haben. Wenn nicht, wieso?