// PATCH: listbox fix // References and documentation links for this code: // http://web.archive.org/web/20090826011441/http://support.microsoft.com/kb/66370 // ! http://forum.sources.ru/index.php?showtopic=207672 void AdjustListBoxHorizontalExtent(HWND hWndLstBox) { HFONT hFont; HDC hDCLstBox; TEXTMETRIC tm; DWORD dwExtent; int i, cnt, len; TCHAR *s; SIZE sz; // get item count cnt = SendMessage(hWndLstBox, LB_GETCOUNT, 0, 0); // note that LB_ERR defined as (-1) so this check // also handles any other unwanted things if (cnt > 0) { // find most large string (in characters) len = 0; for (i = 0; i < cnt; i++) { // LB_ERR defined as (-1) so it's safe to call max() here len = max(len, SendMessage(hWndLstBox, LB_GETTEXTLEN, i, 0)); } // found something? if (len > 0) { // allocate memory (in bytes) s = (TCHAR *) GetMem((len + 1) * sizeof(s[0])); // memory allocated? if (s) { // allocate GDI handles hDCLstBox = GetDC(hWndLstBox); hFont = (HFONT) SendMessage(hWndLstBox, WM_GETFONT, 0, 0); hFont = (HFONT) SelectObject(hDCLstBox, hFont); GetTextMetrics(hDCLstBox, (LPTEXTMETRIC) &tm); // find most large string (in pixels) dwExtent = 0; for (i = 0; i < cnt; i++) { len = SendMessage(hWndLstBox, LB_GETTEXT, i, (LPARAM) s); // got something? if (len > 0) { GetTextExtentPoint(hDCLstBox, s, len, &sz); dwExtent = max(dwExtent, sz.cx); } } dwExtent += tm.tmAveCharWidth; // free GDI handles SelectObject(hDCLstBox, hFont); ReleaseDC(hWndLstBox, hDCLstBox); // free memory FreeMem(s); // should dwExtent be fixed? if (SendMessage(hWndLstBox, LB_GETHORIZONTALEXTENT, 0, 0) < dwExtent) { SendMessage(hWndLstBox, LB_SETHORIZONTALEXTENT, dwExtent, 0); InvalidateRect(hWndLstBox, NULL, TRUE); } } // (s) } // (len > 0) } // (cnt > 0) }
2015.04.15