Wert aus CEdit bekommen
-
Hallo Leute,
ich habe ein Dialog OHNE den Anwendungsassistenten erstellt da ich ziemlich häufig ein CEdit Element benötige und ich mir dachte, mit ein paar for Schleifen ist das schnell erledigt. Daher Habe ich dem Dialog eine Membervariable für ein CEdit-Array verpast und im Konstruktor erzeuge ich Sie dann dynamischDialogEingabeDynamisch::DialogEingabeDynamisch(CWnd* pParent /*=NULL*/) : CDialog(DialogEingabeDynamisch::IDD, pParent) { int i; for ( i = 0; i < ANZAHL; i++ ) this->m_pEditArray[i] = new CEdit; }In der OnInitDialog()-Methode rufe ich dann Create auf um die Objekte zu erzeugen. Das funktioniert auch wunderbar. Nun möchte ich aber mal zu Testzwecken on der OnOK-Mezhode sehen ob überhaupt die Werte enthalten sind die ich eingegeben habe. Dafür habe ich zwei Varianten gefunden
1.:
for (int i = 0; i < ANZAHL; i++ ) nEingegbenenerWert = this->m_pEditArray[i]->GetDlgItemInt(i+MYDEFINE);Es wird aber immer nur 0 zurückgegeben obwohl ich nicht 0 eingegeben habe.
2.:
LPTSTR str; this->m_pEditArray[i]->GetLine(0, str);Da gibt es zur Laufzeit einen Fahler
Unbehandelte Ausnahme bei 0x77d33523 in MeinProg.exe: 0xC0000005: Zugriffsverletzung-Schreibposition 0x00426230.Der hängt wohl mit dem LPTSTR str zusammen, aber ich weiss nicht warum.
Kann mir jemand einen Tipp geben wie ich nun die Werte aus meinen Editfeldern bekomme?
Danke im Voraus!
-
int nValue; CString strText; for(int i = 0; i < ANZAHL; ++i) { m_pEditArray[i]->GetWindowText(strText); // Holt den Text. nValue = atoi(strText); // Verwandelt den Text in Integer. // Weitere Verwendung von nValue. }Gäbe aber gerade für die OnOk Methode noch eine besser Lösung, wodurch du auch nicht atoi aufrufen musst, um den Text in Integer umzuwandeln.
CMyDialog : public CDialog { // ... private: int* m_pEditIntegers; // ... } CMyDialog::CMyDialog(CWnd* pParent /*=NULL*/) : CDialog(CMyDialog::IDD, pParent) { m_pEditIntegers = new int[ANZAHL]; } CMyDialog::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExChange(pDX); // Zu beachten ist, dass deine Edits die IDs hintereinander haben. Also zum Beispiel: // Deine Edit IDs sind von 100 bis 100 + ANZAHL. for(int i = 0; i < ANZAHL; ++i) { DDX_Text(pDX, IDC_EDITONE + i, m_pEditIntegers[i]); } } CMyDialog::OnOK() { CDialog::OnOK(); // Da in CDialog::OnOK() UpdateData(TRUE) ausgeführt wird, hast du hier bereits alle Integer im Array. }Grüssli
-
Danke Dravere,
aber leider funktioniert dein 1. Vorschlag nicht. atoi gibt immer 0 zurück. Habs mit und ohne UpdateData(...) versucht. Bringt nichts
Dein 2. Vorschlag schein interessant zu sein. Allerdings weiss ich nicht genau wie ich die Steuerelemente registrieren soll.
Ist DDX_TEXT da überhaupt das richtige Makro? Handelt sich doch um ints.
-
naja wenn atoi immer null zurück gibt dann erreichst du den test im Editfeld nicht.
du könntest es mal mit GetDlgItemText versuchen sofern ich dich richtig versteh und m_pEditArray ne ansamlung von IDC_EDITS beherbergt.
for(int i = 0; i < ANZAHL; ++i) { GetDlgItemText(m_pEditArray[i],strText); nValue = atoi(strText); }mfg
LowFly
-
Hmm steht das Edit auf Number? Guck ob das Edit existiert... sonnst kackt die Anwendung ab. Usw usf...
-
jeanfischer schrieb:
Danke Dravere,
aber leider funktioniert dein 1. Vorschlag nicht. atoi gibt immer 0 zurück.Wenn atoi 0 zurückgibt, dann ist entweder die Zahl 0 oder ein Fehler im String. z.b. a043 ergibt 0. Während 045a 45 ergibt. Auch ist zu beachten, dass atoi nur ganze Zahlen umwandeln kann. Für Kommastellen sollte man eher atof nehmen. Wobei dann zu beachten ist, dass man den Punkt '.' für das Trennzeichen nimmt und nicht das Komma ','.
jeanfischer schrieb:
Habs mit und ohne UpdateData(...) versucht. Bringt nichts

Bei GetWindowText muss man kein UpdateData aufrufen. Da greift man direkt drauf zu.
jeanfischer schrieb:
Dein 2. Vorschlag scheint interessant zu sein. Allerdings weiss ich nicht genau wie ich die Steuerelemente registrieren soll.
CEdit::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)Mit der Zahl bei nID. In deinen Resourcen kannst du IDs registrieren. Die kannst du bei nID dann setzen. Um eine ID zu registrieren gehst du (Bei VS2003) auf die Resourcen und rechtsklickst den Ordner mit dem Namen deines Projekts. Dort steht dann irgendwo ein ID= und daneben Resource Symbols. Draufklicken. Und dort kannst du mit New neue IDs registrieren. Diese sollten dann eben hintereinander liegen, um das zweite Beispiel Funktionstüchtig zu machen.
jeanfischer schrieb:
Ist DDX_TEXT da überhaupt das richtige Makro? Handelt sich doch um ints.
Nein ... DDX_Text ist das richtige ^^
Mit DDX_Text kannst du alles holen. Von Ints über Strings bis zu COleDateTime's. Schau dir es mal in der MSDN an
Grüssli
-
Hey Leute, danke für Eure Antworten, funktionieren tut das Ganze aber noch immer NICHT!
for(int i = 0; i < ANZAHL; ++i) { GetDlgItemText(m_pEditArray[i],strText); nValue = atoi(strText); }bringt nichts. Die Werte in den Feldern sind eingegeben und der String ist immer "", so kann atoi auch keinen Wert heraus ziehen.
Ich glaube ich habe das Problem falsch beschrieben. Daher probiere ich es noch einmal genauer zu formulieren.
- Ich habe der Header-Datei eine Private Membervariable hinzugefügt mit der Bezeichnung *CEdit m_pEditArray[ANZAHL];
- Im Konstruktor habe ich den CEdit-Pointer wie folgt initialisiert
for ( int i = 0; i < ANZAHL; i++ ) this->m_pEditArray[i] = new CEdit;- In OnInitDialog() habe ich alle mit new erzeugten CEdit Objekte mit [n]Create[/b] initialisiert
for ( int i= 0; i < ANZAHL; i++ ) this->m_pEditArray[i]->Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER, CRect(nLocHor*60+nGlobHor*200+10,nLocVert*15+nGlobVert*65+10, 50,10), this, i+ID_STARTPUNKT);- Nun bin ich der Meinung sind die CEdit Objekte bereit verwendet zu werden. D.H. Meiner Meinung nach kann ich jetzt in der OnOK-Methode die Werte Abfragen, aber nix passiert.
Langsam habe ich das Gefühl das ich irgend einen Wichtigen Schritt vergessen habe um mit den Steuerelemnten arbeiten zu können. Aber ich habe genau den Weg der da oben steht beschritten und alle Methoden die eigentlich den Text aus den Felder bekommen sollten scheitern. Muss man noch irgend etwas beachten wenn man Steuerelemente OHNE Assistenten erstellen möchte

PS: muss ich eigentlich die CEdit Objekte im Destruktor oder in OnDestroy mir delete löschen? Und worin liegt der Unterschied?
-
jeanfischer schrieb:
Hey Leute, danke für Eure Antworten, funktionieren tut das Ganze aber noch immer NICHT!
for(int i = 0; i < ANZAHL; ++i) { GetDlgItemText(m_pEditArray[i],strText); nValue = atoi(strText); }Der Code ist ja auch falsch. Das der überhaupt funktioniert erstaunt mich, bzw. das da keine Warnmeldung kommt.
Probiers mal so:for(int i = 0; i < ANZAHL; ++i) { m_pEditArray[i]->GetWindowText(strText); nValue = atoi(strText); }jeanfischer schrieb:
PS: muss ich eigentlich die CEdit Objekte im Destruktor oder in OnDestroy mir delete löschen? Und worin liegt der Unterschied?
Jo im D'tor solltest du die CEdits schon mit delete löschen. Mit new reservierst du dir ja Speicher auf dem Heap für die CEdits. Die muss man in C++ selber wieder freigeben, sonst entstehen speicherlecks.
Also:// Im Destruktor for(int i = 0; i < ANZAHL; ++i) { delete m_pEditArray[i]; }Grüssli
-
@Dravere
naja der code ist nicht unbedingt falsch denn wenn du mal meine annahme list, so sagte ichLowFly schrieb:
sofern ich dich richtig versteh und m_pEditArray ne ansamlung von IDC_EDITS beherbergt
ist der code VOLLKOMMEN RICHTIG denn so verwende ich ihn auch zwar in einem anderen zusammenhang aber das spielt keine rolle

leider hab ich ihn falsch verstanden und es kann so sicher nicht funzen

aber nix für ungut
mfg
LowFly
-
Hallo Dravere,
der Codefor(int i = 0; i < ANZAHL; ++i) { m_pEditArray[i]->GetWindowText(strText); nValue = atoi(strText); }läuft zwar durch, aber er gibt mir nicht den Inhalt der Editfelder zurück. Es wird immer "" zurückgegeben. Wenn du schon mal soetwas ähnliches gemacht hast, kannst du davon den Code posten (Natürlich dürfen andere auch
)?Danke!
PS: ich habe jetzt mal etwas anderes versucht. Nachdem ich die Felder in der OnInitDialog-Methode erzeugt habe, habe ich versucht mit SetWindowText mit text zu füllen. Aber die Felder sind leer geblieben! Also ich denke noch immer ich mache etwas grundlegendes falsch!
-
Also ich hab mal schnell was nachgebaut und bei mir funktioniert es. Ich schreib mal den Code hier rein.
// TestDlg.h // #pragma once // CTestDlg dialog class CTestDlg : public CDialog { DECLARE_DYNAMIC(CTestDlg) public: CTestDlg(CWnd* pParent = NULL); // standard constructor virtual ~CTestDlg(); // Dialog Data enum { IDD = IDD_DIALOG1 }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support DECLARE_MESSAGE_MAP() private: CEdit* m_EditArray; public: virtual BOOL OnInitDialog(); afx_msg void OnBnClickedOk(); };// TestDlg.cpp : implementation file // #include "stdafx.h" #include "TestDlg.h" // CTestDlg dialog IMPLEMENT_DYNAMIC(CTestDlg, CDialog) CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/) : CDialog(CTestDlg::IDD, pParent) { m_EditArray = new CEdit[81]; } CTestDlg::~CTestDlg() { for(int i = 0; i < 81; ++i) { delete m_EditArray[i]; } } void CTestDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CTestDlg, CDialog) ON_BN_CLICKED(IDOK, OnBnClickedOk) END_MESSAGE_MAP() // CTestDlg message handlers BOOL CTestDlg::OnInitDialog() { CDialog::OnInitDialog(); CRect rect(30, 30, 60, 60); int nWidth = rect.Width(); int nHeight = rect.Height(); for(int i = 0; i < 81; ++i) { if(!(i % 9) && i != 0) { rect.left -= 8 * nWidth; rect.right -= 8 * nWidth; rect.top += nHeight; rect.bottom += nHeight; } else { rect.left += nWidth; rect.right += nWidth; } m_EditArray[i].Create(ES_LEFT | WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP, rect, this, IDC_EDIT_START + i); } return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CTestDlg::OnBnClickedOk() { CString strText[81]; for(int i = 0; i < 81; ++i) { m_EditArray[i].GetWindowText(strText[i]); } for(int i = 0; i < 81; ++i) { AfxMessageBox(strText[i], MB_OK, 0); } OnOK(); }Das ganze ist jetzt nur so dahin gepfuscht, vor allem z.b bei !(i % 9). ^^
Aber es funktioniert. Man kann schön die Quadrate mit dem Tabulator durchlaufen und eines nach dem anderen füllen. Und am Ende, wenn man auf OK drückt, bekommt man 81 Messageboxen, mit dem jeweiligen Inhalt des Edits.Das ist nun die Version mit den Ctrls. Also mit CEdits. Und sogar selber erstellt. Ich habe hier noch ein Beispiel mit den Value-Variablen und nicht selbst erstellten Edits. Bzw. per Dialog-Editor erstellt. Also einfach nicht mit Create ^^
// SLDKDlg.h : Headerdatei // #pragma once // CSLDKDlg Dialogfeld class CSLDKDlg : public CDialog { // Konstruktion public: CSLDKDlg(CWnd* pParent = NULL); // Standardkonstruktor DECLARE_DYNAMIC(CSLDKDlg); // Dialogfelddaten enum { IDD = IDD_SOLUDOKU_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV-Unterstützung // Attribute // public: static const int nEDITCOUNT = 81; static const int nROWCOLCOUNT = 9; // Implementierung protected: HICON m_hIcon; // Generierte Funktionen für die Meldungstabellen virtual BOOL OnInitDialog(); DECLARE_MESSAGE_MAP() private: CString m_strEdit[nROWCOLCOUNT][nROWCOLCOUNT]; CEdit m_ctrlEdit[nROWCOLCOUNT][nROWCOLCOUNT]; };// SLDKDlg.cpp : Implementierungsdatei // #include "stdafx.h" #include "SLDKDlg.h" // CSLDKDlg Dialogfeld IMPLEMENT_DYNAMIC(CSLDKDlg, CDialog) CSLDKDlg::CSLDKDlg(CWnd* pParent /*=NULL*/) : CDialog(CSLDKDlg::IDD, pParent) { for(int c = 0; c < nROWCOLCOUNT; c++) { for(int r = 0; r < nROWCOLCOUNT; r++) { m_strEdit[r][c] = _T(""); m_strTempEdit[r][c] = _T(""); } } } void CSLDKDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); for(int c = 0; c < nROWCOLCOUNT; c++) { for(int r = 0; r < nROWCOLCOUNT; r++) { DDX_Text(pDX, (IDC_EDIT1 + ((c * nROWCOLCOUNT) + r)), m_strEdit[r][c]); DDX_Control(pDX, (IDC_EDIT1 + ((c * nROWCOLCOUNT) + r)), m_ctrlEdit[r][c]); } } } BEGIN_MESSAGE_MAP(CSLDKDlg, CDialog) END_MESSAGE_MAP()Das ist ein altes Projekt von mir. Daher habe ich einiges rausgekürzt und nur das allerwichtigste da gelassen. Wenn man in diesem Dialog nun UpdateData(TRUE), bwz. FALSE, aufruft, dann werden alle Daten aus den Edits in das 2D Array m_strEdit gespeichert oder geladen.
Das ist wie gesagt mit Edits gemacht, welche ich im Dialog-Editor dazufgefügt habe. IDC_EDIT1 bis IDC_EDIT81 sind als Nummern auch wirklich hintereinander, dafür habe ich gesorgt. IDC_EDIT1 ist in dem Fall 1000 und IDC_EDIT81 1080.So ich hoffe, dass dies dir nun weiterhelfen wird.
Grüssli
-
DANKE!!!

Der einzige Unterschied zwischen deinem und meinem Code ist das du im Create Aufruf nuch ein ES_LEFT | drin hast!
Aber nun Funzt es!
Also noch mal einen herzlichen Dank!!!