MFC Anwendung programmieren, Kleiner Einheiten Umrechner - diverse Fragen eines Anfängers



  • Wie genau funktioniert das mit wchar_t ? einfach bei der variablendeklaration wchar_t anstatt char hinschreiben ? oder in der klammer (wchar_t str[10]) erzeugen ?
    Sry steh grad aufm Schlauch 😉

    @ Decimad, die UpdateData variante würd ich mir gern mal genauer ansehen – die ersten Google Ergebnisse dazu waren nicht so toll – hast du da nen passenden Link ?
    Ich werd mir das Montag noch mal genauer angucken, erstmal Wochenende ^^

    Achja den Einstieg habe ich mir nicht freiwillig ausgesucht.
    C++ muss ich machen da wir das in der Berufsschule lernen (wobei ich mich da auch Frage wieso man da nicht mit C# einsteigt, denn ich habe schön öfter gehört das es als Einstieg einfacher ist und man sich schneller an Objektorientierte Programmierung gewöhnt)

    Gruß, Philipp



  • Ich versteh nicht warum hier mit char und wchar_t und was weiss ich rumgealbert wird wenn es in der MFC doch die Klasse CString gibt und der das beim schreiben erstmal egal ist ob Unicode oder net.

    Mal dein Problem auf den Punkt gebracht, is nur ein 4 Zeiler:

    void CUmrechnerMFCv2Dlg::OnBnClickedkminm() 
    {
    	CString Tmp; //temp buffer für ein und ausgabe
    
    	eingabeSTR.GetWindowText(Tmp);//Eingabe abholen
    
    	Tmp.Format(L"%f",atof(Tmp)/1.609344);//Umrechnen und Formatieren für Ausgabe
    
    	ausgabeSTR.SetWindowText(Tmp);//Ausgabewert setzen
    
    }
    

    Wenn Du CStrings als Membervariablen deiner Edit-Felder vbenutzt, dann wird das zum 3 Zeiler (2x UpdateData und die zeiler der Formatierung Berechnung).

    Und wenn das immer noch zu viel ist, dann leg doch einfach die Membervariable deiner Edit-Felder als double an, dann konvertiert das Framework dir die Zahlen und du brauchst wirklich nur noch die UpdateData´s und die eigentliche Berechnung, hat aber den Nachteil, das du die ausgabe nicht mehr Formatieren kannst (also du kannst die Nachkommastelle nicht begrenzen auf zb: 3 stellen)

    So viel von mir zu dem Thema, hoffe das es dir weiter Hilft zu verstehen wie die MFC Funktioniert.

    Sorry das mit dem L hatte ich Vergessen, da mein Testprojekt was ich benutze für sachen zum ausprobieren eben nicht Unicode ist. Also Entschuldige ich mich noch mal an der Stelle in aller Öffendlichkeit für meinen fatalen Fehler 😉



  • Ja, das war recht übersichtlich - dankeschön.

    Ich mach jetzt allerdings erstmal Schluss und Montag weiter, melde mich dann 😉

    Schönes Wochenende!



  • CTecS schrieb:

    Ich versteh nicht warum hier mit char und wchar_t und was weiss ich rumgealbert wird wenn es in der MFC doch die Klasse CString gibt und der das beim schreiben erstmal egal ist ob Unicode oder net.

    Na ja, beim deklarieren eines CString ist es egal, da abhängig von _UNICODE CStringA oder CStringW verwendet wird (es wird also sehr wohl unterschieden). Aber spätestens hier ist es überhaupt nicht mehr egal:

    CTecS schrieb:

    Tmp.Format("%f",atof(Tmp)/1.609344);//Umrechnen und Formatieren für Ausgabe
    

    Hier kriegst du einen Compiler-Error, da du einen const char* übergibst, aber ein const wchar_t* erwartet wird (eben da CStringW). Das muss dann natürlich so aussehen:

    Tmp.Format(L"%f",atof(Tmp)/1.609344);
    

    Und hier braucht er wieder das Wissen, was es mit Unicode und MBCS auf sich hat. PhilippW, du musst einem konstanten String einfach ein "L" voranstellen, damit es ein wchar_t* (wide string) ist und kein char*. Das ist in Projekten nötig, die auf Unicode eingestellt sind. Und das ist im Visual Studio die Standardeinstellung. Lies dir am besten mal durch, was Unicode und MBCS sind und was man so beachten muss. Ist eigentlich keine große Sache, man stolpert anfangs aber gerne mal drüber.

    Deshalb finde ich es schon sinnvoll, Anfängern mal zu zeigen, was er unabhängig von Vereinfachungen wie "#define CString CStringW" zu dem Thema wissen muss.



  • oder einfach projekt einstellungen auf multibyte ändern, woah.



  • Guten Tag, eine neue Woche hat begonnen und ich hab auch schon wieder die ersten C++ Probleme 😉

    Ich bin heute morgen bisher in dieser Reihenfolge vorgegangen:

    1. In den Projekteigenschaften auf "multibyte" umgestellt.
    2. Den Code von CTecS ausprobiert..
    3. die Ergänzung von _matze hinzugefügt (das "L") obwohl ich schon auf multibyte umgestellt habe.

    Nun weiß ich aber nicht genau wie ich CStrings als Membervariablen meiner Edit Felder benutze, wenn ich diese Edit Felder nicht veränder erhalte ich folgende Fehlermeldungen:

    Fehler 1 error C2228: Links von ".GetWindowTextA" muss sich eine Klasse/Struktur/Union befinden. z:\pwietzke\eigene dateien\visual studio 2008\projects\umrechnermfcv2\umrechnermfcv2\umrechnermfcv2dlg.cpp 112

    Fehler 2 error C2664: 'void ATL::CStringT<BaseType,StringTraits>::Format(const char *,...)': Konvertierung des Parameters 1 von 'const wchar_t [3]' in 'const char *' nicht möglich z:\pwietzke\eigene dateien\visual studio 2008\projects\umrechnermfcv2\umrechnermfcv2\umrechnermfcv2dlg.cpp 114

    Fehler 3 error C2228: Links von ".SetWindowTextA" muss sich eine Klasse/Struktur/Union befinden. z:\pwietzke\eigene dateien\visual studio 2008\projects\umrechnermfcv2\umrechnermfcv2\umrechnermfcv2dlg.cpp 116

    Ich habe meinen beiden Textfeldern bisher nur eine Membervariable zugewiesen, die kann ich aber auch nicht mehr ändern (ausgegraut), es sei denn ich erstell die Textboxen neu und benenn sie anders.

    Muss ich diesen beiden Textboxen auch eine Klasse hinzufügen ? Also per Rechtsklick "Klasse hinzufügen" ? Denn so verstehe ich die Fehlermeldung, allerdings erschließt sich mir nicht warum die Textbox zwingend eine Klasse benötigt?

    Daraufhin habe ich was anderes probiert, einfach beide Textboxen neu erstellt, denen die namen IDC_Eingabe2 und IDC_Ausgabe 2 gegeben und ihnen die Membervariablen "eingabe2STR" und "ausgabe2STR" gegeben, beim hinzufügen der Membervariable habe ich dann bei Variablentyp aber nicht das vorgegebene "CEdit" stehen gelassen, sondern CString eingegeben, in der hoffnung das meine Textboxen damit zu Eingabefeldern werden...
    Weiterhin weiß ich aber auch nicht genau was der "Steuerelementtyp" bedeutet, in dem "EDIT" drin steht. - Dieses lies sich aber so oder so nicht verändern, also hab ichs dabei belassen. Beim Komplimieren / Testen erhielt ich dann aber noch mehr Fehler:

    Fehler 1 error C2664: 'DDX_Control': Konvertierung des Parameters 3 von 'CString' in 'CWnd &' nicht möglich z:\pwietzke\eigene dateien\visual studio 2008\projects\umrechnermfcv2\umrechnermfcv2\umrechnermfcv2dlg.cpp 31
    Fehler 2 error C2664: 'DDX_Control': Konvertierung des Parameters 3 von 'CString' in 'CWnd &' nicht möglich z:\pwietzke\eigene dateien\visual studio 2008\projects\umrechnermfcv2\umrechnermfcv2\umrechnermfcv2dlg.cpp 33
    Fehler 3 error C2228: Links von ".GetWindowTextA" muss sich eine Klasse/Struktur/Union befinden. z:\pwietzke\eigene dateien\visual studio 2008\projects\umrechnermfcv2\umrechnermfcv2\umrechnermfcv2dlg.cpp 116
    Fehler 4 error C2664: 'void ATL::CStringT<BaseType,StringTraits>::Format(const char *,...)': Konvertierung des Parameters 1 von 'const wchar_t [3]' in 'const char *' nicht möglich z:\pwietzke\eigene dateien\visual studio 2008\projects\umrechnermfcv2\umrechnermfcv2\umrechnermfcv2dlg.cpp 118
    Fehler 5 error C2228: Links von ".SetWindowTextA" muss sich eine Klasse/Struktur/Union befinden. z:\pwietzke\eigene dateien\visual studio 2008\projects\umrechnermfcv2\umrechnermfcv2\umrechnermfcv2dlg.cpp 120

    Das war also falsch denke ich, habe das daraufhin wieder Rückgängig gemacht.

    Ich bin jetzt aber auch leicht verwirrt wie ich denn jetzt den String deklariere, immer noch mit "char eingabeSTR" oder mit wchar_t ? Oder gar mit CString ? Wieviele verschiedene Char und String typen gibt es denn und wie erkennt man sie ?

    Ist es kontraproduktiv wenn ich das Projekt auf Multibyte umstelle und zusätzlich das "L" in der Tmp.Format zeile eingebe ?



  • Achja und nochwas, wie stell ich VS2008 so ein, dass es die Codezeilen im Codefenster anzeigt ? find die option dazu nicht und im gegensatz zu VS2005 springt der bei doppelklick in der fehlerleiste auch nicht in die Zeile wo er den fehler vermutet, sondern markiert mir nur links in der "Ausgabe" nochmal die enstsprechende Zeile.

    *Edit*

    > Update <

    Habe 2 Sachen gefunden, ersteinmal habe ich bei den Edit Control Feldern unter "Variable hinzufügen" rechts die Kategorie entdeckt, wo man von control auf value umstellen kann - dann lässt sich auch CSting oder double auswählen.. also das was ich gesucht habe.
    Den Fehler das er eine Klasse oder eine Union etc. pp vor GetWindowText haben will hab ich jetzt auch weg- hatte an einer stelle n schreibfehler drin.

    Dafür hab ich 2 neue Fehler und die konvertierung des einen Strings scheint immer noch nicht zu klappen:

    Fehler 1 error C2039: 'GetWindowTextA': Ist kein Element von 'ATL::CStringT<BaseType,StringTraits>' z:\pwietzke\eigene dateien\visual studio 2008\projects\umrechnermfcv2\umrechnermfcv2\umrechnermfcv2dlg.cpp 115
    Fehler 2 error C2664: 'void ATL::CStringT<BaseType,StringTraits>::Format(const char *,...)': Konvertierung des Parameters 1 von 'const wchar_t [3]' in 'const char *' nicht möglich z:\pwietzke\eigene dateien\visual studio 2008\projects\umrechnermfcv2\umrechnermfcv2\umrechnermfcv2dlg.cpp 117
    Fehler 3 error C2039: 'SetWindowTextA': Ist kein Element von 'ATL::CStringT<BaseType,StringTraits>' z:\pwietzke\eigene dateien\visual studio 2008\projects\umrechnermfcv2\umrechnermfcv2\umrechnermfcv2dlg.cpp 119

    > Update 2 <

    Mittlerweile scheint die Konvertierung auch zu klappen, aber dieses GetWindow funktioniert immer noch nicht -.-

    Ich werde diese beiden .GetWindow und .SetWindow Fehler einfach nicht los...

    Fehler 1 error C2228: Links von ".GetWindowTextA" muss sich eine Klasse/Struktur/Union befinden. c:\tmp_usr\umrechnermfcv2.5\umrechnermfcv2\umrechnermfcv2dlg.cpp 122
    Fehler 2 error C2228: Links von ".SetWindowTextA" muss sich eine Klasse/Struktur/Union befinden. c:\tmp_usr\umrechnermfcv2.5\umrechnermfcv2\umrechnermfcv2dlg.cpp 126

    Hab grad eben schon 2 Klassen erstellt und am anfang includet... aber dann meint er da fehlen semikolons und will vor dem .GetWindow (also wo ich die klasse hingeschrieben habe) nen Semikolon haben - ja ne is klar 😃

    Wie mach ich das ohne GetWindow mit der UpdateData Variante ?



  • Nach Stundenlanger Google suche u.a. auch hier im Forum habe das ganze endlich hinbekommen.

    Der korrekte Code lautet:

    void CUmrechnerMFCv2Dlg::OnBnClickedkminm()
    {
    	CString Tmp;			
    
    	GetDlgItem(IDC_Eingabe)->GetWindowText(Tmp);
    	Tmp.Format("%f",atof(Tmp)/1.609344); 
    	GetDlgItem(IDC_Ausgabe)->SetWindowText(Tmp);
    }
    

    Ich hab ewig gebraucht um dieses GetDlgItem zu finden... damit wähl ich halt das eingabe bzw. ausgabe feld aus und darauf folgt dann das GetWindowText.
    Den Befehl kannte ich nicht mal und etwas suchen wenn man nicht weiß wie es heißt oder aussieht ist irgendwie doof...

    Naja jetzt funktionierts. - Und ich bin froh kein Programmierer zu sein, und hoffentlich nie beruflich einer sein zu müssen 😃

    Ein paar kleine Fragen hab ich auch noch, ich bedanke mich trotzdem schonmal für die bisherige Hilfe, auch wenn ich noch öfter hier rein gucken werde 😉

    1. Wie formatier ich jetzt das Ergebnis oder stell ein das er nur 2 oder 3 Nachkommastellen anzeigt ? Momentan sinds 5, das sind etwas viele.

    2. Wenn man im Programm Enter drückt ist standardmäßig die beenden taste ausgewählt, so das man das programm leicht versehentlich schließt, wie kann ich die priorität der buttons verändern so das z.B. der Kilometer in Meilen Button normalerweise ausgewählt ist ?

    3. Wie veränder ich die Schriftgröße der label bzw. des "static textes" ? Will oben im Programm nen Namen bzw. ne Überschrift haben und bisher habe ich nur etwas gefunden wie ich die gesamte Schrift des Programms vergrößert wird.

    4. Ich würde gerne die Anzahl an Ziffern welche man eingeben kann begrenzen, z.B. auf maximal 6 stellen (100000 sollte reichen) - wie mach ich das am besten ?
      Gibts da eine Option zu, ähnlich wie man einstellen kann das nur Ziffern.



    1. mit "%.2f"
      2)hab deine Romane nicht durchgelesen - weiss nicht wie du es beiher gelöst hast, aber für sowas eignen sich Radio-Buttons
    2. Du musst eine eigene Schrift definieren (CFont)
    3. hab ich noch nicht gemacht, aber mit dem Meldungstyp "EN-Change" müsste es klappen. (Ereignishandler).

    Noch was grundsätzliches: versuche deine Fragen präziser zu stellen und verzichte auf diese Romane. Die Hauptfunktion des Forums ist übrigens unmengen an Fragen und zugehörignn Antworten zu liefern. Alle Fragen die du hier gestellt hast sind bereits mehrfach beantwortet worden. Zunächst immer fleißig auf die Suche machen...



  • 2. im Dialogeditor für den OK-Button unter den Eigenschaften Standartschaltfläsche oder DefaultButton auf false setzen und bei dem Button deiner Wahl wieder setzen
    3. du mußt ein CFont als Meber der Klasse erstellen, mit Create(....) erzeugen und dem CStatic zuweisen SetFont(), das CFont objekt muß solange wie das Static leben sonnst ändert sich der Font nicht (machen die meisten falsch und wundern sich



  • Flockig schrieb:

    2)hab deine Romane nicht durchgelesen

    LOL, auch ich hab' nur eine begrenzte Lebensspanne und deshalb keine Zeit und Lust posts von epischer Breite durchzulesen.

    Ein Großteil der Fragen wäre sowieso auch einfach von google oder google/codesearch beantwortet worden.



  • PhilippW schrieb:

    Ist es kontraproduktiv wenn ich das Projekt auf Multibyte umstelle und zusätzlich das "L" in der Tmp.Format zeile eingebe ?

    Ziemlich, ja. Es hieß ja auch entweder oder. Nicht beides. Welche Lösung du wählst, ist davon abhängig, was du machen willst. Soll dein Projekt Unicode unterstützen, dann aktivier es und pack vor Stringliterale ein "L". Ansonsten stell auf MBCS um.

    Btw, du solltest deine Beiträge wirklich kürzer fassen. Es ist zwar löblich, dass du dein Problem sehr ausführlich beschreiben willst, aber das ist dann doch zuviel des Guten (auch mit vielen unwichtigen Infos) und wird sicher viele verschrecken. 🙂



  • Hmm okay, dankeschön.

    Ja ich komme aus der Hardware/Serverecke, und da regt man sich zu 90% über die Leute auf die keine detallierte Fehlerbeschreibung abgeben können oder nicht aufschreiben was sie geändert / ausprobiert haben.

    Daher dachte ich, ich schreibe lieber alles mit auf, wobei das bei der Programmierung durch das Fehlerlog des Compilers vllt. etwas übertrieben ist.

    In Zukunft werde ich mich kürzer fassen, das mit Google ist allerdings sone sache, allein für dieses GetDlgItem hab ich ca. 4 Stunden gesucht.
    Ganz einfach aus dem Grund das immer irgendwelche anderen Methoden genannt werden, da finden man unmengen an C und C# Hinweisen und haufenweise anderer Probleme. Ich dachte ja vorher die ganze zeit ich kann einfach die Variable vor .GetWindow schreiben...

    Normalerweise habe ich kein problem mit Google, doch finde ich auch hier wieder das es im Hardware / Serverbereich deutlich einfacher ist... meistens findet man bei dem einfachen übernehmen einer fehlermeldung nach sekunden bis minuten etwas.. mit der gleichen Methode hat man bei C++ tausende Seiten.
    Mag auch daran liegen das ich mich mit Hardware und Servern seit Jahren beschäftige und dort weiß wonach ich suchen muss.

    Aber vielen dank für die Antworten

    Gruß Philipp



  • PhilippW schrieb:

    Ja ich komme aus der Hardware/Serverecke, und da regt man sich zu 90% über die Leute auf die keine detallierte Fehlerbeschreibung abgeben können oder nicht aufschreiben was sie geändert / ausprobiert haben.

    Daher dachte ich, ich schreibe lieber alles mit auf, wobei das bei der Programmierung durch das Fehlerlog des Compilers vllt. etwas übertrieben ist.

    Wie gesagt, ist ja auch löblich, nur eben etwas zuviel des Guten. 😉 Das ist mir aber allemal lieber als jemand, der gar keine Fehlerbeschreibung liefert (oder etwas, was man kaum so nennen kann), ehrlich.

    Das Problem, als Anfänger mit den Google-Ergebnissen oder der MSDN leicht überfordert zu sein, verstehe ich sehr gut. Man muss sich in die ganze Materie erst mal einlesen. Das geht nicht in 5 Minuten.

    Dafür gibt es (u.a.) ja dieses Forum. Man soll Eigeninitiative zeigen, klar. Aber wenn jemand schon Stunden investiert hat und nicht weiterkommt, dann soll er selbstverständlich hier fragen. Das kann dir keiner vorwerfen.



  • Gut danke - ab sofort kürzer 😉

    1. %.2f" scheint zu printf zu gehören und ist somit "C" und nicht "C++" ?
      Außerdem nutze ich ja GetWindow und SetWindow zur Ausgabe in einem Textfenster, wo soll ich da nen printf einbauen?

    @ ctecs: Danke, defaultbutton klappt.

    Okay, dachte das mit der Schriftart geht vllt. einfacher, hab jetzt die allgemeine Schriftart größer eingestellt und werde es so lassen.

    Den Ereignishandler hab ich gesehen, nur weiß ich nicht welcher Code da rein muss - werds mal bei google weitersuchen.



  • PhilippW schrieb:

    1. %.2f" scheint zu printf zu gehören und ist somit "C" und nicht "C++" ?
      Außerdem nutze ich ja GetWindow und SetWindow zur Ausgabe in einem Textfenster, wo soll ich da nen printf einbauen?

    Du meinst SetWindowText, ne. sprintf (nicht printf, sprintf für Strings) ist auch Bestandtel von C++, wenn auch die Herkunft bei C liegt. Du kannst sehr wohl einen char* erzeugen und mit sprintf befüllen. Du kannst aber auch genausogut einen CString nehmen und Format()/AppendFormat() benutzen. Die Syntax ist übrigens die gleiche (vielleicht bis auf minimale Ausnahmen, bin da nicht ganz sicher).

    EDIT: Kleines Beispiel:

    CString cs;
    float f=.5;
    cs.Format("%.2f",f);
    


    1. EditCtlr im Dialog erstellen, rechte Mousetaste->Ereignishandler hinzufügen, Meldungstyp "EN_CHANGE" einstellen, OK. Der Wizzard erstellt dir nun u.a. die Methode, die bei jeder Änderung des EditCtrls aufgerufen wird. Dort kommen dann die Dinge rein, die du bei jeder Änderung durchführen lassen willst. In deinem Fall wäre hier eine Überprüfung der eingegebenen Zahl durchzuführen.


  • danke matze hat geklappt 😉 - jetzt hab ichs auch verstanden

    hab das ".2f" mit in meine rechnung/umwandlung reingeschrieben.

    void CUmrechnerFinalDlg::OnBnClickedkminm()
    {
    	CString Tmp;
    
    	GetDlgItem(IDC_Eingabe)->GetWindowText(Tmp);
    	Tmp.Format("%.2f",atof(Tmp)/1.609344);
    	GetDlgItem(IDC_Ausgabe)->SetWindowText(Tmp);
    }
    

Anmelden zum Antworten