Textfeld in Dialogbox, Breite während der Laufzeit anpassen



  • Moin,

    ich benutze für verschiede Aufrufe ein und die selbe Dialogbox und ändere nur die Textfelder mit SetDlgItemText(...), soweit so gut das funktioniert. Jetzt füge ich nur Textblöcke unterschiedlicher Breite ein, hierbei ergibt sich das Poblem, dass wenn das Textfeld länger ist als der eingefügte Text meine selbst gebastelte Funktion "CursorChangeOnTextfeld" ungenau funktioniert. Der Cursor ändert sich logischerweise immer wenn er irgendwo im Textfeld liegt ganz gleich ob der Text schon zu Ende ist oder nicht, da die Funktion ja die Fläche des Textfeldes und nicht deren Inhalt abfragt. Wie kann ich nun das Problem lösen. Ich dachte mir man müsste die Breite dem Text anpassen, aber wie gehe ich da am besten vor, für Vorschläge wäre ich sehr dankbar.


  • Mod

    Fange WM_COMMAND EN_CHANGE ab und führe ein entsprechendes MoveWindow/SetWindowPos aus.



  • Ja, so ähnlich hab ich mir den Anfang vor gestellt, EN_UPDATE oder EN_CHANGE abzufangen, aber wie ermittle ich die erforderliche Breite der edit Control?


  • Mod

    DC besorgen. Font aus dem Fenster selektieren. DrawText DT_CALCRECT ausführen und ein paar Pixel dazuschlagen.



  • Hallo Martin,
    ich hab jetz mal eine kleine Funktion geschrieben die "bedingt" funktioniert, das mit dem Font selektieren konnte ich noch nicht umsetzen, da ich nicht weiss wie das geht, kannst du oder jemand anderst helfen? Ansonsten scheint es zu funktioieren.

    void Fit_TextToWindow(HWND Dlg_hWnd, UINT Ctl_ID){
    
    	HWND			Ctl_hWnd;
    	HDC			hDC;
    	RECT			CtrlRect;
    	POINT			pt;
    	int			height, widht;
    	char			TextBuff[2048];
    
    	Ctl_hWnd = GetDlgItem(Dlg_hWnd, Ctl_ID);
    	GetWindowRect(Ctl_hWnd, &CtrlRect);
    	hDC = GetDC(Ctl_hWnd);
    	GetDlgItemText(Dlg_hWnd, Ctl_ID, TextBuff, sizeof(TextBuff));
    	pt.x = CtrlRect.left;
    	pt.y = CtrlRect.top;
    	ScreenToClient(Dlg_hWnd, &pt);
    	DrawText(hDC, TextBuff, lstrlen(TextBuff), &CtrlRect, DT_CALCRECT | DT_INTERNAL);
    	height = CtrlRect.bottom - CtrlRect.top;
    	widht = CtrlRect.right - CtrlRect.left;
    	MoveWindow(Ctl_hWnd, pt.x, pt.y, widht, height, TRUE);
    	ReleaseDC(Dlg_hWnd, hDC);
    }
    

  • Mod

    WM_GETFONT Nachricht verwenden um den Font zu holen. SelectObject ausführen. DrawText. Danach nicht vergessen den alten Font zurückzusetzen (Achtung GDI Leaks).



  • Hallo zusammen,

    ich hab meine Funktion jetzt erweitert und die erforderliche Breite des Fensters im Bezug auf dessen Textinhalt wird nun korrekt eingestellt. Jedoch wüsste ich gerne ob mein Code so richtig ist. Insbesondere die Stellen die diese GDI Leaks hervorrufen können, wenn man da was falsch programmiert.

    void Fit_TextToWindow(HWND Dlg_hWnd, UINT Ctrl_ID){
    
    	HWND		Ctrl_hWnd;
    	HDC		hDC;
    	RECT		Ctrl_Rect;
    	POINT		pt;
    	int		height, widht;
    	char		TextBuff[2048];
    	HFONT		tmpFont, oldFont;
    	LOGFONT	lf;
    
    	Ctrl_hWnd = GetDlgItem(Dlg_hWnd, Ctrl_ID);
    	hDC = GetDC(Ctrl_hWnd);
    	memset(&lf, 0, sizeof(lf));
    	oldFont = (HFONT)SendMessage(Ctrl_hWnd, WM_GETFONT, 0, 0);
    	GetObject(oldFont, sizeof(LOGFONT), (PTSTR)&lf);
    	tmpFont = CreateFontIndirect(&lf);
    	SelectObject(hDC, tmpFont);
    	GetDlgItemText(Dlg_hWnd, Ctrl_ID, TextBuff, sizeof(TextBuff));
    	GetWindowRect(Ctrl_hWnd, &Ctrl_Rect);
    	pt.x = Ctrl_Rect.left;
    	pt.y = Ctrl_Rect.top;
    	ScreenToClient(Dlg_hWnd, &pt);
    	DrawText(hDC, TextBuff, lstrlen(TextBuff), &Ctrl_Rect, DT_CALCRECT);
    	height = Ctrl_Rect.bottom - Ctrl_Rect.top;
    	widht = Ctrl_Rect.right - Ctrl_Rect.left;
    	MoveWindow(Ctrl_hWnd, pt.x, pt.y, widht, height, TRUE);
    	ReleaseDC(Dlg_hWnd, hDC);
    	SelectObject(hDC, oldFont);
    	DeleteObject(tmpFont);
    }
    


  • Sieht soweit korrekt aus, wobei eigentlich üblich ist:

    oldFont = (HFONT)SelectObject(hDC, tmpFont);
    

    Den Rest kannst Du so lassen 😉 .



  • Oh danke, aber ich glaub ich hab ganz unten die Reihenfolge nicht beachtet

    :
    :
        ReleaseDC(Dlg_hWnd, hDC);
        SelectObject(hDC, oldFont);
        DeleteObject(tmpFont);
    }
    

    müsste doch so heissen oder?

    :
    :
        SelectObject(hDC, oldFont);
        ReleaseDC(Dlg_hWnd, hDC);
        DeleteObject(tmpFont);
    }
    

Anmelden zum Antworten