[C/Win32] Ermitteln der benötigten Feldhöhe einer Ownerdraw-Listbox

Rene Albrecht

Erfahrenes Mitglied
Hi,

ich habe eine Ownerdraw-Listbox erzeugt (Dank @Endurion). Jetzt könnte ich mittels Redifinition des rcItem.bottom im DRAWITEMSTRUCT die Höhe des Feldeintrags manipulieren - aber wie? Ich schreibe z.B. mittels DrawText() eine Zeichenkette in das Feld, die Zeilenumbrüche enthält... Es wird jedoch nur die erste Zeile angezeigt.

Gruß
René
 
Du kannst DrawText mit DT_CALCRECT aufrufen. Dann wird nichts dargestellt, aber das übergebene RECT wird abgeändert.

Vergiss nur nicht, da nicht DT_SINGLELINE zu verwenden (sollte aber klar sein).
 
Danke, sieht schon etwas besser aus mit

Code:
case WM_DRAWITEM:
{
   DRAWITEMSTRUCT *ds = (DRAWITEMSTRUCT *)lParam;
   if(ds->CtlType != ODT_LISTBOX) return 0;
   char szTemp[4096];
   SendMessage(GetDlgItem(hwndDlg, IDD_NACHRICHTEN), LB_GETTEXT, ds->itemID, (LPARAM)&szTemp[0]);
   DrawText(ds->hDC, szTemp, lstrlen(szTemp), &(ds->rcItem), DT_CALCRECT);
   DrawText(ds->hDC, szTemp, lstrlen(szTemp), &(ds->rcItem), DT_LEFT);
   return 0;
}

Beim ersten Eintrag mit mehreren Zeilen stellt er diese auch sauber dar. Beim nächsten Eintrag in der Listbox werden allerdings die zuvor gerenderten Zeilen > 1 überschrieben... :( Woran kann das liegen?

Nachtrag:
Hab gerade mitbekommen, dass ich hierzu die Nachricht WM_MEASUREITEM nutzen kann, indem ich das Feld itemHeight in der Struktur MEASUREITEMSTRUCT setze. Wie kann ich allerdings ein DrawText mit dem Flag DT_CALCRECT machen, ohne ein Handle auf den DC zu haben? Die WM_MEASUREITEM wird schließlich vor der WM_DRAWITEM abgesetzt.
 
Zuletzt bearbeitet:
Du kannst dir ja jederzeit mit GetDC ein HDC holen. Nicht vergessen, nach dem Aufruf mit ReleaseDC wieder freigeben!
 
So klappt's:

Code:
case WM_MEASUREITEM:
{
	MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
	if (mis->CtlID != IDD_NACHRICHTEN) return 0;
	HDC tmpHdc=GetDC(NULL);
	RECT tmpRect;
	char tmpString[4096];
	SendMessage(GetDlgItem(hwndDlg, IDD_NACHRICHTEN), LB_GETTEXT, mis->itemID, (LPARAM)&tmpString[0]);
	DrawText(tmpHdc, tmpString, lstrlen(tmpString), &tmpRect, DT_CALCRECT|DT_EXTERNALLEADING);
	mis->itemHeight=tmpRect.bottom;
	ReleaseDC(NULL, tmpHdc);
	return 0;
}

case WM_DRAWITEM:
{
	DRAWITEMSTRUCT *ds = (DRAWITEMSTRUCT *)lParam;
	if (ds->CtlID != IDD_NACHRICHTEN) return 0;
	char tmpString[4096];
	SendMessage(GetDlgItem(hwndDlg, IDD_NACHRICHTEN), LB_GETTEXT, ds->itemID, (LPARAM)&tmpString[0]);
	DrawText(ds->hDC, tmpString, lstrlen(tmpString), &(ds->rcItem), DT_LEFT);
	return 0;
}

Danke, Endurion...
 
Zurück