Dialog per C&P in ActiveX Control einfügen klappt net!



  • Ahoi!

    Ich versuche, einen Dialog samt zugehöriger Klasse aus einem bestehenden Projekt in eine neu erstelltes ActiveX-Projekt zu kopieren, um ihn da aufrufen zu können.

    Dazu habe ich den Dialog einfach rüberkopiert, Klasse (h+cpp) rüberkopiert und dem neuen Projekt hinzugefügt und ein paar Stellen gestrichen, die in der neuen Umgebung nicht mehr gepasst hätten (aber nix Relevantes), Stringtable-Einträge kopiert, das war's. Die IDs für alle Controls wurden automatisch erzeugt und passten. Das Ding lässt sich zumindest problemlos kompilieren.

    Der Versuch, den Dialog zu erstellen (Create), scheitert aber leider und ich finde den Grund nicht. Ein frisch erzeugter Dialog macht keine Probleme, weswegen ich hoffe, dass ich beim Kopieren irgendetwas Wichtiges übersehen habe.

    Hier erstelle ich den Dialog:

    m_dlg.Create(IDD_SHARPNESSADJUSTMENT,this);
      BOOL b=AfxUnhookWindowCreate();    //wird nie erreicht, da vorher Programmabbruch
      m_dlg.ShowWindow(SW_SHOW);
    

    Diese Stelle in dlgcore.cpp (Z. 314) scheint mir entscheidend zu sein:

    hWnd = ::CreateDialogIndirect(hInst, lpDialogTemplate,
    	pParentWnd->GetSafeHwnd(), AfxDlgProc);
    
    	/* This is a bit tricky.  At this point, 1 of 3 things has happened:
     	 * 1) ::CreateDialogIndirect() created successfully and hWnd != NULL.
     	 * 2) ::CreateDialogIndirect() did create a window and then send the appropiate 
     	 *    creation messages (ie. WM_CREATE).  However, the user handled WM_CREATE and 
     	 *    returned -1.  This causes windows to send WM_DESTROY and WM_NCDESTROY to the
     	 *    newly created window.  Since WM_NCDESTROY has been sent, the destructor of this
     	 *    CWnd object has been called.  And ::CreateDialogIndirect() returns NULL.
     	 * 3) ::CreateDialogIndirect() did NOT create the window (ie. due to error in template)
     	 *    and returns NULL. 
     	 *
     	 * (Note: In 3, this object is still valid; whereas in 2, this object has been deleted).
     	 *
     	 * Adding to the complexity, this function needs to do 2 memory clean up (call 
     	 * pOccManager->PostCreateDialog() and delete occDialogInfo) if the destructor of 
     	 * this object hasn't been called.  If the destructor has been called, the clean up is done
     	 * in the destructor.
     	 *
     	 * We can use the return valid of AfxUnhookWindowCreate() to differentiate between 2 and 3.
     	 *  - If AfxUnhookWindowCreate() returns true and hWnd==NULL, this means that (2) has happened
     	 *    and we don't have to clean up anything. (Cleanup should be done in the destructor).
     	 *  - If AfxUnhookWindowCreate() returns false and hWnd== NULL, this means that (3) has happened
     	 *    and we need to call PostNcDestroy().
     	 *
     	 * Note: hWnd != NULL implies that AfxUnhookWindowCreate() return TRUE.
             *
             * Note2: From this point on, don't access any member variables without checking hWnd.  If 
             *        hWnd == NULL, the object has been destroyed already.
     	 */
    

    Hier wird NULL zurückgegeben. Das Erstellen des Dialogs scheint aber schon geklappt zu haben, da OnCreate aufgerufen wird und auch 0 zurückgibt (nicht -1, wie bei Punkt 2 beschrieben). Danach wird allerdings PostNcDestroy aufgerufen. Irgendwie passt mein Fall zu keiner der 3 Möglichkeiten, es sei denn bei Punkt 3 wird auch WM_CREATE gesendet (ich versteht den Text eigentlich anders).

    Danach hält das Programm übrigens erstmal an. Genauer Wortlaut:

    "Windows hat einen Haltepunkt in tstcon32.exe ausgelöst. Dies kann auf eine Beschädigung des Heaps zurückzuführen sein und weist auf ein Problem in tstcon32.exe oder in einer der geladenen DLLs hin. Weitere Details im Ausgabefenster."

    Im Ausgabefenster findet man dann:

    HEAP[tstcon32.exe]: Invalid Address specified to RtlValidateHeap( 03030000, 0303AD0C )
    

    Möchte man das Programm weiter ausführen, bekommt der Testcontainer nochmal den Focus, es wird eine MessageBox mit einer Debug Assertion angezeigt (dbgheap.c, Z. 1279) und dann tut sich nix mehr. Die Assertion lässt sich nicht wegklicken, der Testcontainer wird nix mehr neu gezeichnet, es hilft nur noch Shift-F5 im VS.

    Ich hoffe, jemand hat schon einen Verdacht, woran es liegen könnte und kann mir helfen.

    Ich bin sicher, es ist etwas ganz Banales. Aber ich leider noch nicht so erfahren im Debuggen des MFC-Codes, das ich behaupten könnte, hier auch nur den geringsten Durchblick zu haben...

    Bei fehlenden Informationen (z.B. Code) einfach Bescheid sagen. Ich liefere das so schnell wie möglich nach.


Anmelden zum Antworten