Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: MFC (Visual C++) ::  Problem mit static_downcast     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
Problemcaster
Unregistrierter




Beitrag Problemcaster Unregistrierter 13:15:59 30.08.2010   Titel:   Problem mit static_downcast            Zitieren

In meinem Mainframe muss ich auf die Dokumentenklasse zugreifen. Ich hab das wie folgt realisiert:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    TRACE(_T("CMainFrame::OnCreate\n"));
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
   
    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
        | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
        !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    {
        TRACE0("Symbolleiste konnte nicht erstellt werden\n");
        return -1;      // Fehler bei Erstellung
    }

    if (!m_wndStatusBar.Create(this) ||
        !m_wndStatusBar.SetIndicators(indicators,
          sizeof(indicators)/sizeof(UINT)))
    {
        TRACE0("Statusleiste konnte nicht erstellt werden\n");
        return -1;      // Fehler bei Erstellung
    }
    // TODO: Löschen Sie diese drei Zeilen, wenn Sie nicht möchten, dass die Systemleiste andockbar ist
    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);

    CMyDoc* pDocument1=STATIC_DOWNCAST(CMyDoc,GetActiveDocument());
    ASSERT(pDocument1);        //->hier knallt's

    return 0;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
TRACE(_T("CMainFrame::OnCreate\n"));
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;

if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Symbolleiste konnte nicht erstellt werden\n");
return -1; // Fehler bei Erstellung
}

if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Statusleiste konnte nicht erstellt werden\n");
return -1; // Fehler bei Erstellung
}
// TODO: Löschen Sie diese drei Zeilen, wenn Sie nicht möchten, dass die Systemleiste andockbar ist
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);

CMyDoc* pDocument1=STATIC_DOWNCAST(CMyDoc,GetActiveDocument());
ASSERT(pDocument1); //->hier knallt's

return 0;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    TRACE(_T("CMainFrame::OnCreate\n"));
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
   
    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
        | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
        !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    {
        TRACE0("Symbolleiste konnte nicht erstellt werden\n");
        return -1;      // Fehler bei Erstellung
    }

    if (!m_wndStatusBar.Create(this) ||
        !m_wndStatusBar.SetIndicators(indicators,
          sizeof(indicators)/sizeof(UINT)))
    {
        TRACE0("Statusleiste konnte nicht erstellt werden\n");
        return -1;      // Fehler bei Erstellung
    }
    // TODO: Löschen Sie diese drei Zeilen, wenn Sie nicht möchten, dass die Systemleiste andockbar ist
    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);

    CMyDoc* pDocument1=STATIC_DOWNCAST(CMyDoc,GetActiveDocument());
    ASSERT(pDocument1);        //->hier knallt's

    return 0;
}


In einem anderen Beispiel geht das irgendwie, nur hier nicht. Was mach ich da falsch?
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13517
Beitrag Martin Richter Moderator 09:04:03 31.08.2010   Titel:              Zitieren

Wenn das Mainframne erzeugt wird ist IMHO noch kein Document vorhanden!
Wieso benötigst Du im MainFRame das Dolument?
Das passt überhaupt nicht in das Doc/View Konzept.

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
Problemcaster
Unregistrierter




Beitrag Problemcaster Unregistrierter 10:18:51 31.08.2010   Titel:              Zitieren

Der Konstruktor des Doc wird vor dem des Mainframes aufgerufen. Im Doc liegen Daten, die in der Statuszeile des Mainframes angezeigt werden sollen. Wieso soll das gegen Doc/View verstoßen? GetActiveDocument liefert ja auch einen Zeiger aufs Doc, nur STATIC_DOWNCAST übergibt NULL
David_pb
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.10.2005
Beiträge: 1999
Beitrag David_pb Mitglied 11:33:56 31.08.2010   Titel:              Zitieren

Problemcaster schrieb:
Der Konstruktor des Doc wird vor dem des Mainframes aufgerufen. Im Doc liegen Daten, die in der Statuszeile des Mainframes angezeigt werden sollen. Wieso soll das gegen Doc/View verstoßen? GetActiveDocument liefert ja auch einen Zeiger aufs Doc, nur STATIC_DOWNCAST übergibt NULL


Wann welcher Konstruktor aufgerufen wird ist vollkommen egal. Solang keine View aktiv gesetzt wurde, für deinen Frame, bekommst du von GetActiveDocument() immer NULL geliefert.
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13517
Beitrag Martin Richter Moderator 12:14:57 31.08.2010   Titel:              Zitieren

Problemcaster schrieb:
Wieso soll das gegen Doc/View verstoßen?

Ein Frame braucht von einem Doc nichts zu wissen!
Da ist der Bruch! Warum sollte das Frame überhaupt etwas mit dem Doc zu tun haben sollen?

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
Problemcaster
Unregistrierter




Beitrag Problemcaster Unregistrierter 16:11:53 31.08.2010   Titel:              Zitieren

David_pb schrieb:
Wann welcher Konstruktor aufgerufen wird ist vollkommen egal. Solang keine View aktiv gesetzt wurde, für deinen Frame, bekommst du von GetActiveDocument() immer NULL geliefert.


Eben nicht. GetActiveDocument gibt ja was ungleich NULL zurück, das Problem besteht beim Ausführen von STATIC_DOWNCAST. Das ist das, was ich nicht verstehe.

Martin Richter schrieb:
Ein Frame braucht von einem Doc nichts zu wissen!
Da ist der Bruch! Warum sollte das Frame überhaupt etwas mit dem Doc zu tun haben sollen?


Ich erstelle eine Messsoftware. Der Wert zweier Messeingänge werden über einen Workerthread abgerufen und in einer Variablen im Doc gespeichert. Jetzt soll in der Statuszeile, die meines Wissens ja Bestandteil vom Mainframe ist, dieser Wert angezeigt werden. Dazu soll der Wert der Variablen aus dem Dco gelesen und dort reingeschrieben werden. Das Konstrukt gibts schon, da ja dort auch die Threadsynchronisation realisiert wird. Wenn der Thread mit Schreiben fertig ist bekommt das Mainframe eine Nachricht, damit es die Werte aktualisieren soll. Hast du einen Vorschlag wie ich es anders machen soll?
David_pb
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.10.2005
Beiträge: 1999
Beitrag David_pb Mitglied 16:26:59 31.08.2010   Titel:              Zitieren

Was liefert denn GetActiveDocument()? Ggf kannst du ja mal die Runtimeclass bestimmen.
Problemcaster
Unregistrierter




Beitrag Problemcaster Unregistrierter 17:22:39 31.08.2010   Titel:              Zitieren

GetActiveDocument liefert mir eine Speicheradresse. Aber beim Aufruf von GetActiveDocument()->IsKindOf(RUNTIME_CLASS( CMyDoc )) kracht er auch an die Wand.
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13517
Beitrag Martin Richter Moderator 17:54:35 31.08.2010   Titel:              Zitieren

Lass das Doc eine Nachricht an AfxGetMainWnd senden...
Ich seheda kein Problem. Keine Klasse muss in diesem Fall was voneinander wissen...

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
Problemcaster
Unregistrierter




Beitrag Problemcaster Unregistrierter 08:17:02 01.09.2010   Titel:              Zitieren

Martin Richter schrieb:
Lass das Doc eine Nachricht an AfxGetMainWnd senden...
Ich seheda kein Problem. Keine Klasse muss in diesem Fall was voneinander wissen...


Du meinst also mit Sendmessage/Postmessage das Mainframe informieren und als Parameter den Messwert übergeben?
David_pb
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.10.2005
Beiträge: 1999
Beitrag David_pb Mitglied 08:36:44 01.09.2010   Titel:              Zitieren

Problemcaster schrieb:
GetActiveDocument liefert mir eine Speicheradresse. Aber beim Aufruf von GetActiveDocument()->IsKindOf(RUNTIME_CLASS( CMyDoc )) kracht er auch an die Wand.


Was meinst du mit "kracht an die Wand". Schlägt ne Assertion zu oder was? Gibts keine Detailiertere Fehlerbeschreibung?
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13517
Beitrag Martin Richter Moderator 08:58:50 01.09.2010   Titel:              Zitieren

Problemcaster schrieb:
Martin Richter schrieb:
Lass das Doc eine Nachricht an AfxGetMainWnd senden...
Ich seheda kein Problem. Keine Klasse muss in diesem Fall was voneinander wissen...


Du meinst also mit Sendmessage/Postmessage das Mainframe informieren und als Parameter den Messwert übergeben?


Ja! Es gibt auch Tausend andere Möglichkeiten:
Dein Thread sendet dem Mainframe eine Nachricht und gibt einen Interface zeiger zurück mit dem Du die Statuszeile bearbeitest.

Zumindest gibt es x-Möglichkeiten in dem nicht die eine Klasse alles von der anderen wissen muss und Abhängigkeiten geschafen werden, die nicht sein müssen...

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13517
Beitrag Martin Richter Moderator 08:59:41 01.09.2010   Titel:              Zitieren

David_pb schrieb:
Problemcaster schrieb:
GetActiveDocument liefert mir eine Speicheradresse. Aber beim Aufruf von GetActiveDocument()->IsKindOf(RUNTIME_CLASS( CMyDoc )) kracht er auch an die Wand.


Was meinst du mit "kracht an die Wand". Schlägt ne Assertion zu oder was? Gibts keine Detailiertere Fehlerbeschreibung?


Wenn GetActiveDocument() NULL liefert, dann muss Dein Code auch zu einem Crash führen... und das ist hier das Problem. GetActiveDocument liefert NULL!

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
David_pb
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.10.2005
Beiträge: 1999
Beitrag David_pb Mitglied 09:00:51 01.09.2010   Titel:              Zitieren

Martin Richter schrieb:
David_pb schrieb:
Problemcaster schrieb:
GetActiveDocument liefert mir eine Speicheradresse. Aber beim Aufruf von GetActiveDocument()->IsKindOf(RUNTIME_CLASS( CMyDoc )) kracht er auch an die Wand.


Was meinst du mit "kracht an die Wand". Schlägt ne Assertion zu oder was? Gibts keine Detailiertere Fehlerbeschreibung?


Wenn GetActiveDocument() NULL liefert, dann muss Dein Code auch zu einem Crash führen... und das ist hier das Problem. GetActiveDocument liefert NULL!


Das bestreitet Problemcaster ja permanent.
Problemcaster
Unregistrierter




Beitrag Problemcaster Unregistrierter 09:24:54 01.09.2010   Titel:              Zitieren

Martin Richter schrieb:
Wenn GetActiveDocument() NULL liefert, dann muss Dein Code auch zu einem Crash führen... und das ist hier das Problem. GetActiveDocument liefert NULL!


Ja eben nicht. GetActiveDocument liefert 0x00411479. Blöd ist, dass das eben nicht die gleiche Adresse ist die GetDocument im CView zurück gibt.

David_pb schrieb:
Was meinst du mit "kracht an die Wand". Schlägt ne Assertion zu oder was? Gibts keine Detailiertere Fehlerbeschreibung?


Ja, es gibt einen Assert.
David_pb
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.10.2005
Beiträge: 1999
Beitrag David_pb Mitglied 10:00:03 01.09.2010   Titel:              Zitieren

Was für eins? Die Dinger sind dazu da das man Informationen aus ihnen ziehen kann...
Problemcaster
Unregistrierter




Beitrag Problemcaster Unregistrierter 10:21:07 01.09.2010   Titel:              Zitieren

David_pb schrieb:
Was für eins? Die Dinger sind dazu da das man Informationen aus ihnen ziehen kann...


Das ist nicht das Problem. Ich möchte eigentlich eine Erklärung, warum STATIC_DOWNCAST einen NULL-Zeiger zurückgibt. Laut Beschreibung müsste in der Debug-Version ein ASSERT kommen, wenn er es nicht umwandeln kann.
David_pb
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.10.2005
Beiträge: 1999
Beitrag David_pb Mitglied 12:36:58 01.09.2010   Titel:              Zitieren

Dann step eben mal durch, da wirst du sehen wo's hakt.
C/C++ Forum :: MFC (Visual C++) ::  Problem mit static_downcast   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.