Dialog im Dialog initialisieren

Cappaja

Erfahrenes Mitglied
hallo,

wie kann ich innerhalb einer dialogbasierenden anwendung einen weiteren dialog initialisieren? mittels der nachricht WM_INITDIALOG in der untergeordneten dialogklasse ist es nicht möglich die werte für die kontrollelemente zu initialisieren (der TRACE wird nie ausgeführt). stattdessen wird direkt die methode ausgeführt. an der rotmarkierten Stelle steigt das Programm dann aus, da es versucht einen leeren CString in ein INT zu transformieren.

was gibt es denn für möglichkeiten, anderweitig einen dialog innerhalb einer dialogbasierenden anwendung zu initialisieren?

Code:
BOOL CDisplayControl::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Zusätzliche Initialisierung hier einfügen
	m_ctrlDecim. SetRange(1, 40);
	m_ctrlDecim. SetPos(1);
	m_ctrlScale. SetRange(0, 50);
	m_ctrlScale. SetPos(0);
	m_ctrlOffset.SetRange(0, 100);
	m_ctrlOffset.SetPos(0);

	TRACE("\n\n#############################################\n\n");
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX-Eigenschaftenseiten sollten FALSE zurückgeben
}

void CDisplayControl::OnChangeDecimation() 
{
	CWiwoDlg* WinWout;
	WinWout = NULL;
	CString sDecim;
	m_ctrlDecim.GetWindowText(sDecim);
	int NewValue = atoi(sDecim);

	if(NewValue > 40)
	{
		WinWout->pDP.d_dec = 40;
		return;
	}
	if(NewValue < 1)
	{
		WinWout->pDP.d_dec = 1;
		return;
	}

	WinWout->pDP.d_dec = NewValue;
}

gruß cappaja
 
Zuletzt bearbeitet:

MCoder

Erfahrenes Mitglied
Hallo,

OnInitDialog() wird einmalig automatisch bei der Erstellung des Dialogs aufgerufen. Wie erzeugst du den Dialog und welche Message hängt hinter OnChangeDecimation? Ich vermute mal, m_ctrlDecim ist ein CSpinButtonCtrl. Um dessen Wert abzufragen gibt es die Methode GetPos(). Da brauchst du nichts zu konvertieren.

Gruß
MCoder
 

Cappaja

Erfahrenes Mitglied
Hallo,

OnInitDialog() wird einmalig automatisch bei der Erstellung des Dialogs aufgerufen. Wie erzeugst du den Dialog und welche Message hängt hinter OnChangeDecimation? Ich vermute mal, m_ctrlDecim ist ein CSpinButtonCtrl. Um dessen Wert abzufragen gibt es die Methode GetPos(). Da brauchst du nichts zu konvertieren.

Gruß
MCoder

den dialog erzeuge ich mit einem doppelklick event innerhalb eines gültigen Graphen:
Code:
void CWiwoDlg::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	CRect rect = m_pGraph->CalcDataArea();
	BOOL bFlag = CheckRect(point, rect);

	if(bFlag == TRUE)
	{
		// Falls Dialog noch nicht erstellt ist
		if (m_pDisplayControl == NULL)
		{
			// Dialog-Objekt erstellen
			m_pDisplayControl = new CDisplayControl(this);
			// Dialog erstellen und anzeigen
			m_pDisplayControl->Create(CDisplayControl::IDD);
			m_pDisplayControl->ShowWindow(SW_NORMAL);
		}
	}	
	
	CDialog::OnLButtonDblClk(nFlags, point);
}

hinter OnChangeDecimation() steckt eine EN_CHANGE message. m_ctrlDecim ist ein CSpinCtrlButton, das stimmt. Das mit dem cast leuchtet mir ein, habs durch
Code:
int NewValue = m_ctrlDecim.GetPos();
ersetzt. allerdings stürzt die anwendung weiterhin bei dieser zeile ab, da oninitdialog() bei mir noch nicht ausgeführt wurde und kein gültiger wert drin steht.
 

MCoder

Erfahrenes Mitglied
Hallo,

Die Initialisierung sollte nach dem Aufruf von Create erfolgen. Wird die EN_CHANGE Message vom Spin-Button ausgelöst? Das würde bedeuten, dass das Control existiert, aber die Variable nicht korrekt initialisiert wurde. Kontrolliere noch mal die Stellen, an denen die Variable angelegt bzw. initialisiert wird.

Ich kann übrigens immer noch nicht glauben, dass OnInitDialog nicht aufgrerufen wird. Setze doch mal einen Debugger-Breakpoint direkt auf die erste Zeile in dieser Methode.

Gruß
MCoder
 

Cappaja

Erfahrenes Mitglied
Die Membervariable m_ctrlDecim gehört zum Spin-Button wo auch EN_CHANGE ausgelöst wird. Das Programm läuft schon in die OnInitDialog() allerdings wirklich erst nachdem er in OnDecimationChange() war. Ich bin die Reihenfolge sorgfältig mit dem Debugger durchgegangen, deswegen bin ich ja so irritiert.

Code:
void CDisplayControl::OnChangeDecimation() 
{
	CWiwoDlg* WinWout;
	WinWout = NULL;

	int NewValue = 5;  //m_ctrlDecim.GetPos();

	if(NewValue > 40)
	{
		WinWout->pDP.d_dec = 40;
		return;
	}
	if(NewValue < 1)
	{
		WinWout->pDP.d_dec = 1;
		return;
	}

	WinWout->pDP.d_dec = NewValue;
}

wenn ich wie hier im Beispiel einen festen Wert eingebe wie 5 dann läuft er bis zur rotmarkierten Stelle wo er wieder komplett aussteigt. Dort übergebe ich nur den Wert an mein struct. So Probleme hatte ich zuvor noch nicht, kann es wirklich nicht mit der Dialoginitialisierung zusammen hängen?
 

MCoder

Erfahrenes Mitglied
Hallo,

zu deinen letzen Codeabschnitt:
Dass das Programm hier abstürzt ist logisch, da "WinWout" nicht initialisiert (NULL) ist.

Das andere Problem:
Ersetze mal die Zeile
C++:
int NewValue = m_ctrlDecim.GetPos();
durch
C++:
int NewValue = ((CSpinButtonCtrl)GetDlgItem(SPIN_BUTTON_ID)).GetPos();
"SPIN_BUTTON_ID" musst du durch die ID deines Spinbuttons ersetzen. Ich vermute, dass mit "m_ctrlDecim" irgendwas nicht stimmt und so kannst du ohne die Member-Variable auf das Control zugreifen. Mich würde mal interessieren, ob das funktioniert.

Gruß
MCoder
 

Cappaja

Erfahrenes Mitglied
hi mcoder,

dein ansatz war fast richtig, so hats dann aber funktioniert:
Code:
int NewValue = ((CSpinButtonCtrl*)GetDlgItem(IDC_SPIN_DECIM))->GetPos();

WinWout wird nun ausserhalb initialisiert, da sie global definiert wurde. ich hatte zuvor einen Klassenkonflikt, weswegen ich sie lokal anlegte. Allerdings kann ich meiner struktur nach wie vor keinen wert zuweisen. ich denke aber das ich das noch hinbekomme, wichtig war mir die initialisierung der kontrollelemente. hierfür nochmals danke!

übirgens erhalte ich jetzt mit GetPos() den Startwert 0, in OnInitDialog wird er mit SetPos(1) initialisiert, das zeigt nochmals das er doch erst in OnChangeDecimation() springt bevor er wie eigentlich geplant OnInitDialog() ausführt.
 
Zuletzt bearbeitet:

MCoder

Erfahrenes Mitglied
dein ansatz war fast richtig, so hats dann aber funktioniert:
Code:
int NewValue = ((CSpinButtonCtrl*)GetDlgItem(IDC_SPIN_DECIM))->GetPos();
War wohl gestern abend noch zu heiss :)

Die Initialisierung könntest du auch nach/bei Create ausführen. Entweder in einer speziellen Methode oder du erzeugst einen Handler für WM_CREATE.

Gruß
MCoder
 

Cappaja

Erfahrenes Mitglied
falls ich noch irgendwo schwierigkeiten mit der initialisierung bekommen sollte werde ich deinen rat mit dem WM_CREATE mal befolgen. soweit aber mal danke und gestern wars wirklich heiss ;)