Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » IMPLEMENT_DYNAMIC bei Subklassen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
14.11.2005, 11:51 Uhr
Schnuckel



Hallo Leute,

ich habe mit oben genannten Makro ein Problem.
Zur Verdeutlichung:

Meine Klasse ist wie folgt deklariert:

/////////////////////////////////////////////////////////////////////////////
// Dialogfeld CMeinDlg
//

class CMeinDlg : public CDialog
{
DECLARE_DYNAMIC ( CMeinDlg )

/////////////////////////////////////////////////////////////////////////////
// Subklasse Dialogfeld CTabDlg
//
class CTabDlg : public CDialog
{
DECLARE_DYNAMIC ( CTabDlg )

// Konstruktion
public:
CTabDlg ( CWnd* pParent = NULL ); // Standardkonstruktor

...
};

public:
// Standardkonstruktor
CMeinDlg ( CWnd* pParentWnd = NULL );
~CMeinDlg();

...
};

Wenn ich nun in der Implementierung das IMPLEMENT_DYNAMIC-Makro einsetze:

IMPLEMENT_DYNAMIC ( CMeinDlg::CTabDlg, CDialog )

dann kommt die Fehlermeldung:

error C2039: 'classCMeinDlg' : Ist kein Element von 'CTabDlg'

Der Inhalt der Fehlermeldung ist ja richtig, aber völlig unsinnig.

Hat jemand darauf eine Antwort oder sogar eine Lösung parat?
Ich habe schon im Internet gesucht, bin aber niergends fündig geworden. Das mag auch daran liegen, dass sehr wenige Leute offensichtlich die Technik mit den Subklassen einzusetzen scheinen. Ich dagegen finde das sehr praktisch, gerade wie in meinem Fall mit Dialogen, die Tab-Dialoge in einem TabControl sitzen haben.

Danke für Eure Hilfe im Voraus!


Gruß

Schnuckel
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
14.11.2005, 12:22 Uhr
Tommix



Hallo Schnuckel
Das ist das tolle an Makros, sie debuggen sich so schön. DECLARE_DYNAMIC erzeugt ein CRuntimeClass-Objekt, dessen Name sich aus dem übergebenen Klassenname herleitet:

C++:
public: static const  CRuntimeClass classCTabDlg;
virtual CRuntimeClass* GetRuntimeClass() const;


IMPLEMENT_DYNAMIC arbeitet genau so. Der Text, der als Klassenname übergeben wird, muß also exakt der gleiche sein, was in Deinem Fall aber nicht geht:

C++:
const  CRuntimeClass CMeinDlg::CTabDlg::classCMeinDlg::CTabDlg = {
"CMeinDlg::CTabDlg", sizeof(class CMeinDlg::CTabDlg), 0xFFFF, 0,
((CRuntimeClass*)(&CDialog::classCDialog)), 0 };
CRuntimeClass* CMeinDlg::CTabDlg::GetRuntimeClass() const
{ return ((CRuntimeClass*)(&CMeinDlg::CTabDlg::classCMeinDlg::CTabDlg)); }


Du müßtest also, falls Du Dir das antun willst, die Implementierung selbst schreiben (mit classCTabDlg anstelle von classCMeinDlg::CTabDlg).
Den obigen Präprozessor-Output bekommst Du übrigens mit

Code:
cl MeinDlg.cpp /P /EP



Gruß, Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
14.11.2005, 15:13 Uhr
Schnuckel



Danke Tommix,

das hat mir insofern geholfen, als dass ich nun weiß, woran es scheitert.
Ohne Dir da jetzt nahe treten zu wollen; aber eine Lösung ist das natürlich nicht, denn die wäre nach Deiner Ausführung ja nur, die Strukturierung mit der Subklasse aufzulösen. Oder?
Eine eigene Implemetierung dieses Makros übersteigt meinen Kenntnisstand. Wahrscheinlich müsste man sich ein Makro in der Art IMPLEMENT_DYNAMIC_SUBCLASS ( main_class_name, sub_class_name, base_class_name ) schreiben, richtig?

Gruß

Schnuckel
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
14.11.2005, 16:00 Uhr
Tommix



Eigentlich meinte ich, daß Du das Makro wegläßt und den entsprechenden Code selbst hinschreibst:

C++:
const  CRuntimeClass CMeinDlg::CTabDlg::classCTabDlg = {
"CMeinDlg::CTabDlg", sizeof(class CMeinDlg::CTabDlg), 0xFFFF, 0,
((CRuntimeClass*)(&CDialog::classCDialog)), 0 };
CRuntimeClass* CMeinDlg::CTabDlg::GetRuntimeClass() const
{ return ((CRuntimeClass*)(&CMeinDlg::CTabDlg::classCTabDlg)); }


Aber irgendwie funzt das nicht, auch nicht wenn man ein funktionierendes IMPLEMENT_DYNAMIC so ersetzt. Vielleicht kann noch mal ein anderer ein Auge drauf werfen, ich bekomme ein

Zitat von Compiler:

error C2440: 'initializing' : 'struct CRuntimeClass *' kann nicht in 'struct CRuntimeClass *(__stdcall *)(void)' konvertiert werden


Dabei sollte der Compiler den Output seines eigenen Präprozessors doch eigentlich verstehen können ??

- Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
14.11.2005, 19:34 Uhr
Spacelord
Hoffnungsloser Fall


Hi,
ist schon komisch.
Die Expandierung des Makros da oben wäre richtig wenn die MFC statisch gelinkt würden(zumindest habe ich die Doku so verstanden).Der Fehlermeldung nach erwartet der Compiler aber die Variante für dynamisches Linken der MFC.Diese erwartet als Argument nen Zeiger auf ne Funktion die die RuntimeClass der Basisklasse liefert.
Warum aber wird die statische Variante eingesetzt und später ne dynamische erwartet?


Naja,folgendes kompiliert zwar aber ob es wirklich macht was es soll.....
Das wäre mal ne Frage für Paul DiLascia vom MSDN Magazine.
Das ist der MFC Guru schlechthin .

C++:
CRuntimeClass* __stdcall CMeinDlg::CTabDlg::_GetBaseClass()
{
    return RUNTIME_CLASS(CDialog);
}
const  CRuntimeClass CMeinDlg::CTabDlg::classCTabDlg = {
"CMeinDlg::CTabDlg", sizeof(class CMeinDlg::CTabDlg), 0xFFFF, 0,
&CMeinDlg::CTabDlg::_GetBaseClass, 0 };

CRuntimeClass* CMeinDlg::CTabDlg::GetRuntimeClass() const
{
    return ((CRuntimeClass*)(&CMeinDlg::CTabDlg::classCTabDlg));
}



@Schnuckel:
Warum muss es denn unbedingt ne innere Klasse sein?
Vielleicht würdest du einigen Problemen aus dem Weg gehen wenn du ne eigenständige Klasse daraus machst und im Zweifelsfall nen friend von CMeinDlg daraus machst?

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
15.11.2005, 06:08 Uhr
Spacelord
Hoffnungsloser Fall


Moin,
heute morgen ist der Groschen gefallen.
Tommix hatte ja nur die eine Datei durch den Präprozessor gejagt und in dieser ist _AFXDLL ja nicht definiert.
Deshalb wurde das Makro zum statischen Linken expandiert .

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
15.11.2005, 07:22 Uhr
Tommix



'Morgen,
@Spacelord: Ja, so ergibt es doch noch einen Sinn. In die Richtung hatte ich überhaupt nicht gedacht.

- Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
15.11.2005, 16:37 Uhr
Schnuckel



Vielen Dank für Eure Hilfe!

@Spacelord:
Es sollte deshalb mit Subklassen funzen, weil ich intensiv damit arbeite ;-) Ich finde es ungeheuer praktisch, wenn auf diese Weise eine auch im Klassenbrowser sichtbare Kapselung des Programmcodes entsteht.

Schade finde ich hierbei nur, dass dieses Makro an dieser Stelle versagt. Mir ist natürlich der Grund nun klar. Schön wäre, wenn es ein Spezial-Makro dafür gäbe, wie ich es oben schon einmal genannt habe. Ich habe auch schon Versuche gestartet, die aber alle kläglich scheiterten.
Ich könnte natürlich nun Euren Vorschlag umsetzen und den Code in Euren Antworten einsetzen. Bedauerlich ist nur, dass ich dieses Subklassen-Konstrukt nicht nur an einer Stelle in meinem Projekt einsetze und der Aufwand damit nicht unerheblich wäre.

Trotzdem nochmal vielen Dank!

Gruß

Schnuckel
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
15.11.2005, 19:16 Uhr
Spacelord
Hoffnungsloser Fall


Hallo,
ich hatte das ganze mal getestet.Innerhalb von CMeinDlg,wo die innere Klasse direkt ansprechbar ist,scheint obige Makroersetzung seinen Zweck zu tun.
Ein RUNTIME_CLASS(CTabDlg) liefert den gewünschten CRuntimeClass Zeiger.
Ausserhalb von CMeinDlg,wo CTabDlg mit CMeinDlg qualifiziert werden muss versagt das nächste Makro. Diesmal RUNTIME_CLASS.
Insgesamt ist dieses Gepfusche mit den Makros also nicht sonderlich empfehlenswert.
Da wirst du dich wohl entweder in die Grenzen des Frameworks einfügen müssen oder erstmal in die Tiefen der MFC abtauchen um eine Alterntive zu entwickeln die garantiert zuverlässig arbeitet.
Oder du fragst halt wirklich mal in der Q&A Kolumne vom MSDN Magazine?
Vorausgesetzt dass deine Frage seinen Weg ins Magazin findet sagt der dir entweder
"geht nicht"(und eine detailierte Erklärung wieso) oder er liefert dir eine Lösung mit detailierter Erklärung.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: