I want to resize automatically a listbox depending on the number of items added
Here is how I found the width:


invoke lnstr,ADDR buffer
cmp eax,dwMaxLen
jb ok ;if smaller
mov dwMaxLen,eax ;maximum length
ok:
mov eax, dwMaxLen
lea eax,[+67] ;listbox width
invoke SetWindowPos,hWnd,HWND_TOP,0,0,eax,ebx,SWP_SHOWWINDOW
invoke SendMessage, hWnd,WM_SETREDRAW, 1, NULL


It works if I a specify a custom font. But what I can do to calculate the height ?
Posted on 2003-07-06 16:37:27 by Prahogi


void CalcMaxItemSize(HWND hwndListBox, long *width, long *height)
{
TCHAR buffer[512];
HFONT oldfont;
HFONT font;
SIZE sz;
HDC hdc;
long cnt;
long i;

*width = *height = 0;

cnt = SendMessage(hwndListBox, LB_GETCOUNT, 0, 0);
font = (HFONT) SendMessage(hwndListBox, WM_GETFONT, 0, 0);
hdc = GetDC(hwndListBox);

if (NULL != font)
oldfont = SelectObject(hdc, font);

for (i = 0; i < cnt; i++)
{
SendMessage(hwndListBox, LB_GETTEXT, (WPARAM) i, (LPARAM) buffer);
GetTextExtentPoint32(hdc, buffer, lstrlen(buffer), &sz);
*width = max(*width, sz.cx);
*height = max(*height, sz.cy);
}

if (NULL != font)
SelectObject(hdc, oldfont);
ReleaseDC(hwndListBox, hdc);

return;
}
Posted on 2003-07-07 19:24:48 by P2M
Excuse me for pointing out the bleeding obvious, but I can't stands it no mo.
The code presented is lovely, but it's not going to take much to filll a listbox to the extents of the screen, is it? Wasn't this the point of scrolling? Are you just wanting to reduce the visible listbox size when it has fewer items than the screen resolution can display onscreen?
Posted on 2003-07-08 01:41:33 by Homer
I show as possible define the size item
Use autosize listbox possible in
Posted on 2003-07-08 03:44:36 by P2M
Privet P2M,

Thank you for your code, you use the same technique as I did last night. I save the Largest item in my filling loop first

It is okey for listbox height. But computing the width is tricky. I guess you have to take space characters into account to compute string length.

When you get the Sze.x and Sze.y you still have to transform them into window coords in order to pass them to SetWindowPos...
What is your approach ? This works for me at any screen res
.data
fnt LOGFONT <20, 0, 0, 0, FW_BOLD,
0, 0, 0, RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH OR FF_DONTCARE, "Georgia">

.code

mov eax,Sze.y ;font height
mov ecx,dwCount
inc ecx
xor edx,edx
mul ecx
mov ebx,eax
shr eax,2
add ebx,eax

mov ecx,10
mov eax,Sze.x ;font width
xor edx,edx
div ecx
invoke SetWindowPos,hWnd,HWND_TOP,0,0,eax,ebx,SWP_SHOWWINDOW
Posted on 2003-07-08 15:39:19 by Prahogi
Prahogi
    [*]Before invoke GetTextExtentPoint32 need select hFont for hDc[*]wrong algo calc window size, need:
    width = Sze.x + 2 * GetSystemMetrics(SM_CXBORDER)
    height = Sze.y * dwCount + GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYCAPTION)[*]wrong third parameter GetTextExtentPoint32 need lstrlen(szLargest)[*]need ReleaseDC

    as a result:
    
    
    ...
    invoke GetDC,hWnd
    test eax,eax
    jnz @F
    MakeMessage "Cannot get DC"
    @@:
    mov hDc,eax

    invoke SendMessage, hWnd, WM_GETFONT, 0, 0
    invoke SelectObject, hDc, eax
    ; can simple
    ; invoke SelectObject, hDc, hFont

    push eax ; !!! save previous font for following reconstruction

    invoke GetTextExtentPoint32, hDc, ADDR szLargest, dwMaxLen, ADDR Sze
    test eax,eax
    jnz @F
    invoke GetErrDescription,eax
    @@:

    ; calc window height in Sze.y
    mov eax,Sze.y
    mov ecx,dwCount
    inc ecx ; add one row
    xor edx,edx
    mul ecx
    mov Sze.y,eax
    invoke GetSystemMetrics, SM_CYBORDER
    add Sze.y,eax
    invoke GetSystemMetrics, SM_CYCAPTION
    add Sze.y,eax

    ; calc window width in Sze.x
    mov eax,Sze.x
    xor edi,edi
    mov ecx,dwMaxLen
    div ecx
    add Sze.x,eax ; add one char
    invoke GetSystemMetrics, SM_CXBORDER
    shl eax,1
    add Sze.x,eax

    pop eax
    invoke SelectObject, hDc, eax
    invoke ReleaseDC, hWnd, hDc

    invoke SetWindowPos, hWnd, HWND_TOP, 0, 0, Sze.x, Sze.y, SWP_SHOWWINDOW
    StartLoop:
    ...


    Privet P2M
    You speak/write russian?
Posted on 2003-07-08 21:52:56 by P2M
Prahogi,
; mov edi, enumSRVret
;xor esi, esi
mov esi, enumSRVret
....
....
dec esi
jnz @b

invoke lstrcpy, ADDR buffer, edx ; this is avoidable
...
invoke lstrcpy, ADDR szLargest,ADDR buffer ; this is avoidable too

You can use edi and work directly with every lpDisplayName because it is a ponter to string.
Example:
invoke lnstr, edi
invoke SendMessage, hWnd, LB_ADDSTRING, 0, edi
...
invoke GetTextExtentPoint32,hDc, edi, 256,ADDR Sze

Regards,
Lingo
Posted on 2003-07-08 22:19:23 by lingo12
Thank you guys,
Lingo, thank you for your analysys, I'll try to think about it, it's an opportunity to learn.

P2M, ? ?? ??????(?????? ????? ?????, ??? ? 1992). ? ?? ?
Posted on 2003-07-09 14:38:05 by Prahogi
Prahogi
??????? ? ???? ? ???c?
Posted on 2003-07-09 18:52:19 by P2M