Ein Kombinationsfeld mit Werten füllen!



  • CUserDlg::OnConnect() line 84
    CUserDlg::CUserDlg(CWnd * 0x00000000 {CWnd hWnd=???}) line 32
    CUserInfoDlg::OnConnect() line 295 + 13 bytes
    

    Sorry, das war jetzt viel Text, ich hoffe Du kannst was damit anfangen...

    Also, eines macht mich stutzig:

    CUserDlg::CUserDlg(CWnd * 0x00000000 {CWnd hWnd=???}) line 32
    

    Du befindest dich im Konstruktor des Dialoges. Zu dem Zeitpunkt existieren die Fenster noch nicht.
    Erstell bitte eine Nachrichtenbehandlungsroute im Dialog für WM_INITDIALOG und füge dort den Aufruf für OnConnect ein. Nach dem Aufruf der Basisklasse.

    ...Die Fehlermeldung während der Laufzeit ist folgende:

    Debug Assertion Failed!

    Programm:c:\...\UserInfo.exe
    File:afxwin2.inl
    Line:735

    [/quote]
    Das ist keine Fehlermeldung sondern eine Hilfe für dich. Drück mal Wiederholen. Dann solltest du eine Begründung für das Problem finden - eine Zeile mit ASSERT.

    So, ich hab Feierabend und muss los, kannst also erst morgen wieder mit antworten rechnen.



  • Danke schon mal, ich guck mir das mal an!



  • So, nun habe ich wieder etwas mehr Ruhe als gestern. 🙂

    Du hast die Membervariable mit dem Klassenassistenten erstellt und so der Combobox zugeordnet? (Der erste Beitrag klingt etwas anders...)

    Und noch zur Erklärung:
    Alle Aktionen, für die das Control existieren muss, müssen NACH CDialog::OnInitDialog stattfinden. Dafür überschreibst du die Funktion in deinem Dialog und ruft die Basisklasse auf. (In Views gilt das analog dazu.)

    AddString, EnableWindow und sowas sind solche Aktionen. Mit fällt momentan nichts ein, wo das bei Controlsvariablen nicht der Fall ist.

    Der Konstruktor ist für diese Aktionen also der falsche Platz. ⚠



  • Vielen Dank!

    Ich hab es gestern so gemacht und es hat funktioniert...bin halt noch nicht so fit auf dem Gebiet...hab erst mit der C++-Programmierung angefangen...
    🙂
    Gruss,

    chullain



  • Sags nächstes Mal dazu, Anfängerfehler hat man selbst mal gemacht. 😃
    Dann geht das Finden schneller. 😉



  • Hallo,

    ich habe ein sehr änliches Problem wie "chullain".
    Komme aber leider mit der Erklärung von
    "estartu" für die Windowsnachricht nicht ganz klar.
    Kann mir jemand das etwas genauer erkären?

    Gruss,

    Umleag



  • Hast du OnInitDialog denn schon gefunden/erstellt?
    Es würde sicherlich helfen, wenn du
    1. zeigst, was du versuchst
    2. sagst, wo genau dein Problem ist (Absturz, Fehlermeldung?)
    🙂



  • Hallo,

    und schon einmal danke für die schnelle Antwort.
    Hier erst einmal mein C++ Code:

    BOOL CMainDialog::OnAdd() 
    {
    	// Variablen Deklarationen
    	int nIndex = pDoc->m_oaClearance.GetUpperBound();
    	CClearance* pPointer = NULL;
    	CString strClearanceCombo;
    
    	// Listeneinträge in ComboBox füllen
    	for (int i=0; i<=nIndex; i++)
    	{
    		pPointer = (CClearance*)pDoc->m_oaClearance.GetAt(i);
    		strClearanceCombo.Format("%d",pPointer->m_nClearance);
    		m_AddDlg.ClearanceCombo.AddString(strClearanceCombo);
    	} 
    
    	// Dialog anzeigen
    	m_AddDlg.DoModal();
    
    	CString strHelp;
    
    	for (i=0; i<=nIndex; i++)
    	{
    		pPointer = (CClearance*)pDoc->m_oaClearance.GetAt(i);
    
    		strHelp.Format("%d",pPointer->m_nClearance);
    		if ( m_AddDlg.m_strClearanceCombo == strHelp)
    		{
    			pDoc->m_pWorkPosition = pPointer;
    			return TRUE;
    		}
    	}
    	return FALSE;
    }
    

    Wenn ich das Problem richtig vestanden habe muß ich vor dem Aufruf von m_AddDlg erst einmal InitDialog ausführen, dazu habe ich eine WM_INITDIALOG Nachricht in die aufzurufende Klasse eingefügt leider ohne großen Erfolg. Ich fürhcte ich das irgendwie falsch verstanden.

    Das Programm stürzt während der Laufzeit mit volgender Meldung ab:

    Debug Assertion Failed!
    Programm:c:\...\UserInfo.exe File:afxwin2.inl
    Line:735

    Ich bin leider ein blutiger Anfänger ich hoffe Du kannst mir da etwas helfen.

    Gruß

    Umleag

    PS: Habe mich angemeldet und knnte mich jetzt nicht richtig einloggen
    😞



  • Also, du darfst so eine Combobox nicht von außen füllen (jedenfalls nicht bei modalen Dialogen).

    m_AddDlg.ClearanceCombo.AddString
    

    sowas geht nicht!

    Gib dem Dialog doch die Liste (bzw. das Doc) und lass ihn die in SEINER OnInitDialog füllen.
    Also diese Schleife (mit allem was nötig ist) umsiedeln:

    // Variablen Deklarationen
        int nIndex = pDoc->m_oaClearance.GetUpperBound();
        CClearance* pPointer = NULL;
        CString strClearanceCombo;
    
        // Listeneinträge in ComboBox füllen
        for (int i=0; i<=nIndex; i++)
        {
            pPointer = (CClearance*)pDoc->m_oaClearance.GetAt(i);
            strClearanceCombo.Format("%d",pPointer->m_nClearance);
            m_AddDlg.ClearanceCombo.AddString(strClearanceCombo);
        }
    

    Das Doc kannst du dir auch vom Dialog aus holen (siehe mein Artikel (Klassen einer SDI) im Magazin). 🙂
    Aber einfacher ist sicherlich eine public Variable vom Typ CDeinDoc* (bitte anpassen) und der gibst du vor DoModal pDoc.

    Okay?

    Wegen der Anmeldung guck mal nach einer Freischaltmail oder frag Marcus. 🙂



  • Hallo,

    ich hab den Dialog wie du mir beschrieben hast umgebaut, leider stürzt das
    Programm immernoch ab.

    Hier zunähst einmal der neue Code:

    Hier die aufrufende Funktion:

    BOOL CMainDialog::OnAdd() 
    {
    	// Variablen Deklarationen
    	CAddDialog AddDlg;
    	CString strHelp;
    	int nIndex = pDoc->m_oaClearance.GetUpperBound();
    	CClearance* pPointer = NULL;
    
    	// Dialog initalisieren
    	AddDlg.OnInitDialog(pDoc);
    
    	// Dialog aufrufen
    	AddDlg.DoModal();
    
    	for (int i=0; i<=nIndex; i++)
    	{
    		pPointer = (CClearance*)pDoc->m_oaClearance.GetAt(i);
    
    		strHelp.Format("%d",pPointer->m_nClearance);
    		if ( AddDlg.m_strClearanceCombo == strHelp)
    		{
    			pDoc->m_pWorkPosition = pPointer;
    			return TRUE;
    		}
    	}
    	return FALSE;
    }
    

    Die OnInitDialog Funktion inerhalb meines Dialogfedes

    // Füllt das Kombinationsfeld
    BOOL CAddDialog::OnInitDialog(CImpulseVoltageDoc* pDoc) 
    {
    	CDialog::OnInitDialog();
    
    	// Variablen Deklarationen
        int nIndex = pDoc->m_oaClearance.GetUpperBound();
        CClearance* pPointer = NULL;
        CString strClearanceCombo;
    
        // Listeneinträge in ComboBox füllen
        for (int i=0; i<=nIndex; i++)
        {
            pPointer = (CClearance*)pDoc->m_oaClearance.GetAt(i);
            strClearanceCombo.Format("%d",pPointer->m_nClearance);
            ClearanceCombo.AddString(strClearanceCombo);
        }
    
    	return TRUE;  // return TRUE unless you set the focus to a control
    	              // EXCEPTION: OCX-Eigenschaftenseiten sollten FALSE zurückgeben
    }
    

    Ich habe versucht der Ursche auf die schliche zu kommen konnte aber den
    Grund nicht finden: 😞

    Übrigens vielen dank für die schnelle und herzhafte Antwort und sorry das ich
    so langsam bin.

    Gruß

    Umleag

    PS: Immerhin konnte ich das Problem mit meiner Registrierung lösen 🙂
    immerhin etwas,; Peinlich 😕



  • Hmm, der Ansatz ist ja gar nicht schlecht - nur leider hat sich Microsoft das anders gedacht. 😉

    Also: Die OnInitDialog des Dialoges musst du mit dem Klassenassistenten (hast du VC6?) erzeugen und so lassen (!), die hat keinen Parameter und wird automatisch aufgerufen. Du darfst sie glaubich nichtmal selbst aufrufen.

    Also kannst du die Liste nicht von außen füllen, auch nicht per Funktionsaufruf.
    Aber, du kannst das Doc bekanntgeben.
    In der AddDialog.h

    public:
    CImpulseVoltageDoc* m_pDoc;
    

    In der AddDialog.cpp

    // im Konstruktor m_pDoc = NULL; (wichtig!)
    
    // Füllt das Kombinationsfeld
    BOOL CAddDialog::OnInitDialog(/*Parameter bitte hier und im Header löschen!*/) 
    {
        CDialog::OnInitDialog();
    
        // Variablen Deklarationen
        int nIndex = m_pDoc->m_oaClearance.GetUpperBound();
        CClearance* pPointer = NULL;
        CString strClearanceCombo;
    
        // Listeneinträge in ComboBox füllen
        for (int i=0; i<=nIndex; i++)
        {
            pPointer = (CClearance*)m_pDoc->m_oaClearance.GetAt(i);
            strClearanceCombo.Format("%d",pPointer->m_nClearance);
            ClearanceCombo.AddString(strClearanceCombo);
        }
    
        return TRUE;  // return TRUE unless you set the focus to a control
                      // EXCEPTION: OCX-Eigenschaftenseiten sollten FALSE zurückgeben
    }
    

    Und den Aufruf musst du so abändern:

    BOOL CMainDialog::OnAdd() 
    {
        // Variablen Deklarationen
        CAddDialog AddDlg;
        CString strHelp;
        int nIndex = pDoc->m_oaClearance.GetUpperBound();
        CClearance* pPointer = NULL;
    
        // Dialog initalisieren
        AddDlg.m_pDoc = pDoc;
    
        // Dialog aufrufen
        AddDlg.DoModal();
    
        for (int i=0; i<=nIndex; i++)
        {
            pPointer = (CClearance*)pDoc->m_oaClearance.GetAt(i);
    
            strHelp.Format("%d",pPointer->m_nClearance);
            if ( AddDlg.m_strClearanceCombo == strHelp)
            {
                pDoc->m_pWorkPosition = pPointer;
                return TRUE;
            }
        }
        return FALSE;
    }
    

    Ich hoffe, ich habe nichts vergessen. 🙂

    So, jetzt noch die Erklärung, wieso das mit dem Zusatzparameter nicht klappt:
    Microsoft hat dir in der MFC so einiges vorgefertigt. u.a. den Mechanismus, dass OnInitDialog (durch die Nachricht WM_INITDIALOG) zu dem Zeitpunkt aufgerufen wird, wo du dann alle Controls initialisieren kannst.
    Allerdings MUSS die Funktion so aussehen, wie die sich das ausgedacht haben.

    Daher musst du einem Dialog auf andere Art und Weise die Daten geben, die du anzeigen lassen willst.
    Eine wesentlich elegantere Methode wäre, den Konstruktor das Doc als Parameter mitzugeben. Dann muss die Variable auch nicht public sein (was man ja auch nicht machen soll).
    Aber erstmal muss es so laufen, dann kann man es verfeinern. 😉

    Wenn du mit dem Antworten langsam bist, kanns dir maximal passieren, dass ich im Feierabend bin. :p



  • Hallo,

    vielen Dank für den Tipp, das hat jetzt auch endlich geklappt :). Du hast mir
    wirklich sehr geholfen, an diesem Problem bin ich schon seit zwei Tagen festgehangen!

    Gruß

    Umleag

    PS: Wenn du etwas Zeit hast würde mich die feinere Variante über den Kostruktor auch sehr interessieren 😋. Ich habe leider noch nicht viel Erfahrungen mit den MFC und C++, nur mein Schulwissen 😞 .



  • Dann zeig doch mal den Konstruktor des Dialoges.
    Und dann bau ihm mal den Zeiger auf das Doc als Parameter ein.

    Ist eigentlich ganz einfach. 🙂



  • Hallo,

    ersteinmal mein Kostruktor:

    CAddDialog::CAddDialog(CWnd* pParent /*=NULL*/)
    : CDialog(CAddDialog::IDD, pParent)
    {
    	//{{AFX_DATA_INIT(CAddDialog)
    	m_strClearanceCombo = _T("");
    	//}}AFX_DATA_INIT
    }
    

    und nebenbei noch eine Frage (ohje nur Fragen 😕 ). Ich habe die Dialogklasse Vorwärtsdeklarieren müssen,
    da ich sonst eine menge Fehlermeldungen vom Kompiler erhalten habe. Muß ich das an dieser Stelle machen? Gibts da eine andere möglichkeit sowas zu machen?
    Oder ist vielleicht meine #include Anweisung falsch gesetzt(was ich vermute)?

    Hier noch der Kopf meiner AddDialog.h:

    if !defined(AFX_ADDDIALOG_H__C1C356DE_C13B_4196_AFAC_02796E4CFCB8__INCLUDED_)
    #define AFX_ADDDIALOG_H__C1C356DE_C13B_4196_AFAC_02796E4CFCB8__INCLUDED_
    
    #include "Impulse Voltage.h"
    #include "Impulse VoltageDoc.h"
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // AddDialog.h : Header-Datei
    //
    
    class CImpulseVoltageDoc; //Vorwärtsdeklaration
    
    /////////////////////////////////////////////////////////////////////////////
    // Dialogfeld CAddDialog 
    
    class CAddDialog : public CDialog
    {
    // Konstruktion
    public:
    	CAddDialog(CWnd* pParent = NULL);   // Standardkonstruktor
    
    // Dialogfelddaten
    	//{{AFX_DATA(CAddDialog)
    	enum { IDD = IDD_ADDDIALOG };
    	CComboBox	ClearanceCombo;
    	CString	m_strClearanceCombo;
    	//}}AFX_DATA
    

    Gruß
    Umleag



  • Also, erstmal zum Konstruktor:

    CAddDialog::CAddDialog(CImpulseVoltageDoc* pDoc, CWnd* pParent /*=NULL*/)
    : CDialog(CAddDialog::IDD, pParent)
    , m_pDoc(pDoc)
    {
        //{{AFX_DATA_INIT(CAddDialog)
        m_strClearanceCombo = _T("");
        //}}AFX_DATA_INIT
    // es geht auch hier ein
    // m_pDoc = pDoc;
    // such dir eines aus :)
    }
    

    Vergiß nicht, das auch im Header zu ändern.
    Nun compilier mal und dann versuch mal die Fehler mit etwas Überlegen zu beheben. 🙂
    Ist nur eine Zeile in dem Code von gestern Abend.
    Und sag noch, welche Zeile du nun weglassen kannst.

    Wegen der Includerei:
    Die Forwarddeklaration kann hier schon nötig sein, weil es sonst einen Ringinclude geben dürfte.
    Lass es ruhig so, wenn ein normales Include nur Fehler gibt.



  • Danke 🙂

    Hier noch der veränderte Aufruf des Konstruktors von CAddDlg:

    BOOL CMainDialog::OnAdd() 
    {
        // Variablen Deklarationen
        CAddDialog AddDlg(pDoc);
        CString strHelp;
        int nIndex = pDoc->m_oaClearance.GetUpperBound();
        CClearance* pPointer = NULL;
    
        // Dialog aufrufen
        AddDlg.DoModal();
    }
    

    Super! 🙂



  • 👍

    Drei kleine Fragen:
    1. Wozu sind die drei Zeilen?

    CString strHelp;
        int nIndex = pDoc->m_oaClearance.GetUpperBound();
        CClearance* pPointer = NULL;
    

    2. Wieso habe ich dich keinen weiteren Konstruktor anlegen lassen?
    3. Wieso habe ich wohl diese Parameterreihenfolge gewählt? (Hätte ja auch das Doc hinter den Parent packen können.)
    😉



  • Zu 1.)

    Ich glaube ich weiß worauf du hinaus möchtest hab auch schon nIndex als Variable
    eingespart. Leider kenne ich für den String "strHelp" keine Möglichkeit, um diesen direkt in die Schleife einbauen zu können.
    Den Pointer "pPointer" brauche ich um auf die Elemente in meinem Array zugreifen zu können.

    void CMainDialog::OnAdd() 
    {
        // Variablen Deklarationen
        CAddDialog AddDlg(pDoc);
        CString strHelp;
        CClearance* pPointer = NULL;
    
        // Dialog aufrufen
        AddDlg.DoModal();
    
        for (int i=0; i <= pDoc->m_oaClearance.GetUpperBound(); i++)
        {
            pPointer = (CClearance*)pDoc->m_oaClearance.GetAt(i);
            strHelp.Format("%d",pPointer->m_nClearance);
            if ( AddDlg.m_strClearanceCombo == FormatstrHelp)
                pDoc->m_pWorkPosition = pPointer;
        }
    	// Bringt das Steuerfenster wieder in den Vordergrund
    	pDoc->m_pMainDialog->BringWindowToTop();
    }
    

    Zu 2.)

    Da bin ich mir leider nicht sicher wieso. 😕
    Für gewöhlich kann man ja Konstruktoren beliebig überladen, also müßte das Ergebnis doch das gleiche sein.

    Zu 3.)

    Ich hab beide Varianten ausprobier, sie funktionieren beide. Hier reichten leide mein Wissen und meine Erfahrung nicht mehr aus. 😕

    Wäre aber schön, wenn du mir trotzdem hier etwas beibringen könntest.
    Mein Wissenshunger ist hier recht groß 😋 , nur die Zeit ist knapp.

    Gruß
    Umleag



  • zu 1: Ahh, die Schleife hattest du vorhin weggelassen, ich hab nix gesagt... 😉

    zu 2: So zwingst du den Benutzer (deines Codes), einen Zeiger auf das doc mitzugeben.
    Ohne könnte dein Dialog nicht richtig arbeiten, also sollte man verhindern, dass das Doc nicht mitgegeben wird.

    zu 3: Eigentlich hätte der Compiler meckern müssen, dass Parameter mit Defaultwert immer die letzten sein müssen.
    Oder hast du dem Doc auch NULL als Defaultwert gegeben? (Dann mach das bitte weg, siehe 2).

    🙂



  • Das mit dem Konstruktor(zu 2.))leuchtet mir ein, ist klar 💡 .

    Das mit pDoc hinter dem Parent ist jetzt auch klar, da hab ich dich falsch verstanden:

    BAD: 👎

    CAddDialog::CAddDialog(CImpulseVoltageDoc* pDoc, CWnd* pParent /*=NULL*/)
    : CDialog(CAddDialog::IDD, pParent,m_pDoc(pDoc))
    {
    	//{{AFX_DATA_INIT(CAddDialog)
    	m_strClearanceCombo = _T("");
    	//}}AFX_DATA_INIT
    }
    

    GOOD: 👍

    CAddDialog::CAddDialog(CImpulseVoltageDoc* pDoc, CWnd* pParent /*=NULL*/)
    : CDialog(CAddDialog::IDD, pParent),m_pDoc(pDoc)
    {
    	//{{AFX_DATA_INIT(CAddDialog)
    	m_strClearanceCombo = _T("");
    	//}}AFX_DATA_INIT
    }
    

    Gruß
    Umleag


Anmelden zum Antworten