[VS-6][MFC] Probleme mit einem UI-Thread in einer DLL

Daniel Toplak

Erfahrenes Mitglied
Also zunächst zur Erklärung was ich habe:
Ich habe eine DLL, die bestimmte Funktionen exportiert. Diese DLL beinhaltet auch Resourcen (Dialoge).
So jetzt wird in dieser DLL irgendwann, ein UI-Thread aufgemacht, (Abgeleitete Klasse von CWinThread). In dessen InitInstance() Methode (ist überschrieben) wird ein nicht-modaler Dialog erstellt. Und zwar ungefähr so:
Code:
UINT CMyThread::InitInstance()
{
 ...
  _pMyDlg = new CMyDlg()
  _pMyDlg->Create(MYRES_ID, NULL);
  ...
  ...
}
Das Problem ist, daß der Aufruf von Create fehl schlägt und ich keine Ahnung hab warum.

Das ganze Project ist in diesem Zustand (als DLL) leider nicht debugfähig, deshalb Kann man das Projekt als .EXE erstellen um zu debuggen (dabei ist das dann eine Standaloneanwendung).
Wenn ich das tue, funktioniert der Thread wunderbar, wenn ich den Thread weglasse, funktioniert die Erstellung des Dialogs auch wunderbar (allerdings hängt er, wegen anderer bearbeitung, deshalb THREAD!)

So ich hoffe mir kann da jemand helfen.

Gruß Homer
 
Versuch anstatt Create die CreateIndirect-Funktion mit dem HINSTANCE-Parameter aufzurufen. Als HINSTANCE musst du dort die Instance der DLL angeben.

Daran scheitert es auch. Die DLL hat eine eigene Instance und das Standard-Create sucht die Ressource wohl in dem aufrufenden Programm (das Programm, das die DLL geladen hat).
 
In dieser Richtung stell ich mir das auch vor. Allerdings muss es an dem Thread liegen, weil wenn ich den Dialog auserhalb des Threads mit CDialog::Create() erstelle funktioniert es ohne Probleme.
Außerdem hab ich es mit AFX_MANAGE_STATE(AfxGetStaticModuleState()) inerhalb von InitInstance des Threads schon versucht und das setzt ja den internen Resourcezeiger angeblich richtig.
Versuch anstatt Create die CreateIndirect-Funktion mit dem HINSTANCE-Parameter aufzurufen. Als HINSTANCE musst du dort die Instance der DLL angeben.
Die CreateIndirect() erwartet allerdings keinen HINSTANCE Parameter, das wäre die interne in "DLGCORE.CPP" der MFC und die is Proctected.

Gruß Homer
 
So nach mehrstündigen Debugorgien, bin ich dem Problem etwas näher gekommen. Eine Lösung ist allerdings immer noch nicht in Sicht.
Also der Dialog bei dem das Erstellen schief geht enthält ein externes OCX-Control, entferne ich diese Control und ersetztes durch ein z.B. Static-Control funktioniert die ganze Sache ohne Probleme.
So ich hoffe das hilft euch ein wenig weiter.

Gruß Homer
 
Uhje, einer der Gründe warum ich OCXe überhaupt nicht verwenden will.

Wäre es denn annehmbar, das OCX per Hand in den Dialog einzubauen? Im Moment macht Windows das ja anhand der Dialog-Template.

Ich kenne dasselbe Problem mit OCXen nur bei einfachen Anwendungen, wo das OCX nicht erstellt werden kann, weil es nicht registriert ist.

Wenn es aber als Anwendung klappt und als DLL nicht, dann würde ich den direkten Fehler beim Hersteller davon suchen (bzw. anfragen). Ich vermute mal einfach, dass der OCX-Hersteller da evtl. mit der Instance nicht aufgepasst hat?
 
Also ich mache sowas ähnliches mit erfolg (jedoch ohne Thread !)

Du kannst mit LoadLibrary das ocx laden und dann während diee DLL eingebunden ist das OCX registrieren (Die entsprechende Funktion aufrufen). Du musst dann jedoch die ocx mit der DLL ausliefern.

Ausserdem muss du dafür sorgen dass innerhalb der DLL immer das richtige Resourcehandle verwendet wird !
 
Wäre es denn annehmbar, das OCX per Hand in den Dialog einzubauen? Im Moment macht Windows das ja anhand der Dialog-Template.
Wie meinst du das genau? "Per Hand einbauen"?
Wenn es aber als Anwendung klappt und als DLL nicht, dann würde ich den direkten Fehler beim Hersteller davon suchen (bzw. anfragen). Ich vermute mal einfach, dass der OCX-Hersteller da evtl. mit der Instance nicht aufgepasst hat?
Es klappt auch in der DLL, aber nicht wenn es in einem seperaten Thread läuft.
Du kannst mit LoadLibrary das ocx laden und dann während diee DLL eingebunden ist das OCX registrieren (Die entsprechende Funktion aufrufen). Du musst dann jedoch die ocx mit der DLL ausliefern.
.
Das geht nicht, da das OCX bereits auf dem Zielrechner registriert sein kenn und wenn nicht, dann wird es über eine kl. seperate Installation installiert und registriert, alles andere ist aus Lizenztechnischen Gründen nicht möglich.

Achja nur mal zur Vollständikeit:
Das OCX Control ist von Macromedia, ich möchte es benutzen um einen Flash-Film abzuspielen.

Ausserdem muss du dafür sorgen dass innerhalb der DLL immer das richtige Resourcehandle verwendet wird !
Ich befürchte das ist der Springende Punkt.

Obwohl es noch keine Lösung gibt, danke ich euch schon mal jetzt.

Gruß Homer
 
Mit Per-Hand-Erstellen meine ich, dass die Control nicht im Dialog-Editor eingesetzt wird, sondern in OnInitDialog selbst mit CWnd::CreateControl erstellt wird.

Dort könnte man dann auch auf Fehler eingehen ohne dass der Hauptdialog verschwindet.
 
Beim Einsprung in die DLL erhälst du das ResourceHandle für die DLL .. in jeder Methode der DLL solltest du bei Zugriff auf Resourcen das jetzige ResourceHandle zwischenspeichern und dazwischen das Handle der DLL Laden.
 

Neue Beiträge

Zurück