Textgröße eines CEdit-Feldes



  • Sorry, wegen dem Dialog, war das was schnell zur Hand war 😉
    Eigentlich sollte es auch direkt mit SetFont funktionieren. Kannst Du mal ein Stück Code posten? Wird eventuell der Destruktor deines Fonts aufgerufen nachdem du den Font zugewiesen hast?



  • Ja kein Problem. Zur Erklärung: ich habe eine Membervariable M_MyEdit1 vom Typ CEdit in meiner View-Klasse. In der OnCreate füge ich das Edit-feld in mein View ein und habe da wie folgt versucht, den Font zuzuweisen:

    int CTestAppView::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    	if (CView::OnCreate(lpCreateStruct) == -1)
    		return -1;
    
    	// TODO:  Fügen Sie Ihren spezialisierten Erstellcode hier ein.
    	m_MyEdit1.Create("Test",WS_CHILD|WS_BORDER|WS_VISIBLE|SS_RIGHT,CRect(10,10,300,50),this,IDC_MYEDIT1);
    	CFont font; 
    	font.CreateFont(28,// nHeight 
               0,// nWidth 
               0,// nEscapement 
               0,// nOrientation 
               FW_NORMAL,// nWeight 
               FALSE,// bItalic 
               FALSE,// bUnderline 
               0,// cStrikeOut 
               ANSI_CHARSET,// nCharSet 
               OUT_DEFAULT_PRECIS,// nOutPrecision 
               CLIP_DEFAULT_PRECIS,// nClipPrecision 
               DEFAULT_QUALITY,// nQuality 
               DEFAULT_PITCH | FF_SWISS,// nPitchAndFamily 
               "Verdana");// lpszFacename 
    	m_MyEdit1.SetFont(&font,true);
    	DeleteObject(font);
    	return 0;
    }
    

    Das lässt sich problemlos compilieren auch beim Ausführen gibts keine Ausnahmen oder Asserts. Verändere ich den Typ der Membervariablen in CRichEditCtrl so funktioniert das wunderbar. Deshalb habe ich damit Verständnisprobleme. Aber vielleicht seh ich ja den Wald vor lauter Bäumen nicht.



  • connan schrieb:

    Also bei mir funktioniert das eigentlich, auch ohne Ableitung:

    Als Bsp ein Dialog der ein CEdit IDC_EDIT enthält:

    nach dem das Feld existiert (in OnInitDialog())

    CFont *pFont = new CFont();
        pFont->CreateFont(10,10,0,0,0,0,0,0,0,0,0,0,0,0);
        CWnd* pEdit = this->GetDlgItem(IDC_EDIT);
        pEdit->SetFont( pFont);
    

    Bin da gerade auf ein weiteres Problem gestoßen. Wann vernichtest Du denn deinen pFont? Wenn man das so wie da gezeigt stehen lässt funktioniert das zwar, man hat aber ein Speicherleck. Gibt man direkt nach SetFont den pFont frei ist nur der Cursor in der gewünschten Texthöhe, der Text selbst aber wieder wie vorher klein. 😕



  • In DestroyWindow() mit GetFont() wäre eine Möglichkeit. Wie wärs, wenn Du den Fontpointer einfach als Member deiner App deklarierst. Ich habe mal probiert den Font, so wie Du, auf dem Stack zu erzeugen aber selbst da kommt bei mir schon Mist raus 😕 .



  • connan schrieb:

    In DestroyWindow() mit GetFont() wäre eine Möglichkeit. Wie wärs, wenn Du den Fontpointer einfach als Member deiner App deklarierst. Ich habe mal probiert den Font, so wie Du, auf dem Stack zu erzeugen aber selbst da kommt bei mir schon Mist raus 😕 .

    Hab ich zwar so nicht ausprobiert dürfte aber funktionieren, da man innerhalb der View-Klasse von überall drauf zugreifen kann. Vom Verständnis her dachte ich, dass der Font nur zum Erstellen des CEdits (also in der Create()) gebraucht wird um der zu erstellenden Instanz neue Eigenschaften zu übergeben, die sie dann auch behält. Allerdings existiert die Instanz ja schon seit dem Aufruf des Konstruktors der View-Klasse, da dies ein Member der View ist.
    Was mich allerdings verwundert ist, dass der Cursor die Größe der gewünschten Texthöhe immer noch hat. Es funktioniert halt nicht, da das Font-Objekt bereits in der OnCreate() zerstört wurde. Lässt man den delete()-Befehl weg funktionerts und das Spiecherleck entsteht. Ist es nicht aber so das generell beim Beenden der OnCreate() die Adresse des Zeigers zerstört wird und der Zeiger nur noch physisch im Speicher als Datenblock (ohne Startadresse) existiert (was ja dann auch das Speicherleck induziert)? Oder hab ich da ein Verständnisproblem? Anscheinend scheint sich das CEdit die Adresse zu merken, die OnCreate() vernichtet diese beim Beenden, so dass man extern nicht mehr zugreifen kann.
    Dann stellt sich immer noch die Fragen warum das hier

    int CTestAppView::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    	if (CView::OnCreate(lpCreateStruct) == -1)
    		return -1;
    
    	m_RichText.Create(WS_CHILD|WS_VISIBLE|SS_RIGHT|WS_BORDER, 
        CRect(10,10,300,50),this,IDC_RICHTEXT);
        CFont font; 
        font.CreateFont(28,// nHeight 
               0,// nWidth 
               0,// nEscapement 
               0,// nOrientation 
               FW_NORMAL,// nWeight 
               FALSE,// bItalic 
               FALSE,// bUnderline 
               0,// cStrikeOut 
               ANSI_CHARSET,// nCharSet 
               OUT_DEFAULT_PRECIS,// nOutPrecision 
               CLIP_DEFAULT_PRECIS,// nClipPrecision 
               DEFAULT_QUALITY,// nQuality 
               DEFAULT_PITCH | FF_SWISS,// nPitchAndFamily 
               "Verdana");// lpszFacename 
        m_RichText.SetFont(&font,1);
    	DeleteObject(font);
    	return 0;
    }
    

    problemlos funktioniert.



  • Eigentlich sollte es wirklich so sein, dass der Font nur für die Erstellung benötigt wird, da er ja auch so ein GDIObject ist. Vieleicht liegt auch da der Unterschied, ein RichEdit selectiert vieleicht den Font direkt im DC damit kann er nicht zerstört werden. In der Folge müsste DeleteObject eigentlich FALSE zurückgeben und Du hast denselben Fall wie mit dem Edit. Hast Du mal geprüft was DeleteObject() zurückgibt?



  • connan schrieb:

    Eigentlich sollte es wirklich so sein, dass der Font nur für die Erstellung benötigt wird, da er ja auch so ein GDIObject ist. Vieleicht liegt auch da der Unterschied, ein RichEdit selectiert vieleicht den Font direkt im DC damit kann er nicht zerstört werden. In der Folge müsste DeleteObject eigentlich FALSE zurückgeben und Du hast denselben Fall wie mit dem Edit. Hast Du mal geprüft was DeleteObject() zurückgibt?

    DeleteObject() gibt in beiden Fällen (CStatic und CRichEditCtrl) TRUE zurück. In einem anderen Thread hier ging es um um ein ähnliches Problem allerdings mit Buttons. Da wurde empfohlen den Font als Member der Viewklasse anzulegen und dann hat man ja von überall drauf Zugriff. Dennoch ist nicht klar, warum es hier bei den zwei Klassen Unterschiede gibt. Wenn wir schon mal dabei sind: über den Font kann ich aber nicht die Schriftfarbe definieren, oder? Das geht dann irgendwie über die WM_CRTCOLOR-Behandlungsmethode des Dialogobjektes?



  • Genau, dafür gibts CDC::SetTextColor(..) und CDC::SetBKColor(..) (IMHO 😉 )
    aufzurufen in CWnd::OnCtlColor. Jetzt kommst Du aber um eine eigene Klasse nicht mehr drumrum.



  • Hab ja nicht gesagt das ich mir keine eigene Klasse schaffen will. Mir kam nur so die Idee das es hilfreich wäre wenn der Eingabewert außerhalb des Vorgabebereiches liegt den Text rot zu färben und ansonsten schwarz zu lassen. Deshalb auch das dynamische Vorgehen.
    Im übrigen: das mit den Fonts als Member funktioniert ganz prima. Leider beantwortet es die Frage nicht und mich nervt das wenn ich nicht rausfinde warum etwas so ist wie es ist.



  • Geht mir genauso 🙄


Anmelden zum Antworten