2012-12-03 3 views
0

목록 상자는 자동 크기 조정되지 않습니다. 우리가 가진 것 중에 최고입니다목록 상자의 너비를 동적으로 변경합니다.

SendMessage(my_listbox, LB_SETHORIZONTALEXTENT, 1000, 0); 

MS 유용하게. "... 목록 상자가 동적으로 수평 범위를 업데이트하지 않습니다"고 지적 (도대체하지 ...하지만 난 빗나가 이유)

어떻게 폭 1000px보다 긴 메시지의 텍스트를 절단 방지하기 위해 동적으로 설정 될 수있다? 내가 질문을 이해한다면

답변

1

... :-)

당신은 기본적으로 너비를 조정 한 다음 목록 상자에서 모든 항목을 측정하고 목록 상자 내용의 최대 폭을 계산하고해야합니다

목록 상자의.

다음은 this project의 코드입니다 (목록 상자에 자동 가로 스크롤바가 추가됨). 이 조각은 때 글꼴 변경이라고하지만 무엇이 필요 (약) 보여줍니다된다

static void OnSetFont(HWND hwnd, HFONT hFont) 
// 
// Font has changed! 
// We need to measure all of our items and reset the horizontal extent of the listbox 
{ 
    CData *pData = reinterpret_cast< CData * >(::GetProp(hwnd, g_pcszDataProperty)); 

    pData->m_hFont = hFont; 

    // 
    // Set up a HDC... 
    HDC hdc = GetDC(hwnd); 
    HGDIOBJ hOld = SelectObject(hdc, pData->m_hFont); 


    // 
    // Record the average width for use as our 'fudge factor' later. 
    TEXTMETRIC tm; 
    GetTextMetrics(hdc, &tm); 
    pData->m_nAvergeCharWidth = tm.tmAveCharWidth; 


    pData->m_nMaxWidth = 0; 

    // 
    // This is used as our item buffer. Saves us from having to handle the reallocation 
    // for different string lengths 
    CArray< TCHAR, TCHAR > arrBuffer; 

    // 
    // Quick reference to make the code below read better 
    CArray< int, int > &arrWidth = pData->m_arrItemWidth; 

    // 
    // The main loop. Iterate over the items, get their text from the listbox and measure 
    // it using our friendly little helper function. 
    const UINT uCount = arrWidth.GetSize(); 
    for(UINT u = 0; u < uCount; u++) 
    { 
     const int nLength = ::SendMessage(hwnd, LB_GETTEXTLEN, u, 0); 
     arrBuffer.SetSize(nLength + 1); 
     ::SendMessage(hwnd, LB_GETTEXT, u, (WPARAM)arrBuffer.GetData()); 


     const int nItemWidth = BaseMeasureItem(pData, hwnd, hdc, arrBuffer.GetData()); 

     pData->m_arrItemWidth.SetAt(u, nItemWidth); 
     if(nItemWidth > pData->m_nMaxWidth) 
     { 
      pData->m_nMaxWidth = nItemWidth; 
     } 
    } 


    // 
    // Now, either set the horizontal extent or not, depending on whether we think we need it. 
    if(pData->m_nMaxWidth > pData->m_nClientWidth) 
    { 
     ::SendMessage(hwnd, LB_SETHORIZONTALEXTENT, pData->m_nMaxWidth + pData->m_nAvergeCharWidth, 0); 
    } 
    else 
    { 
     ::SendMessage(hwnd, LB_SETHORIZONTALEXTENT, 0, 0); 
    } 

    // 
    // The usual release of resources. 
    SelectObject(hdc, hOld); 
    ReleaseDC(hwnd, hdc); 
} 

하고 정확하게, 그것은처럼 보이는 이해 ...

static int BaseMeasureItem(CData *pData, HWND hwnd, HDC hdc, LPCTSTR pcszText) 
// 
// Measure and item and adjust the horizontal extent accordingly. 
// Because the HDC is already set up we can just do it. 
// We return the width of the string so our caller can use it. 
{ 
    SIZE size; 
    ::GetTextExtentPoint32(hdc, pcszText, _tcslen(pcszText), &size); 

    if(size.cx > pData->m_nMaxWidth) 
    { 

     pData->m_nMaxWidth = size.cx; 

     if(pData->m_nMaxWidth > pData->m_nClientWidth) 
     { 
      ::SendMessage(hwnd, LB_SETHORIZONTALEXTENT, pData->m_nMaxWidth + pData->m_nAvergeCharWidth, 0); 
     } 

    } 

    return size.cx; 
} 
+0

합니다. 나는 이걸 내일 봐야 겠어, 나는 잠시 머리가된다. 감사! – Ben

관련 문제