2016-08-22 59 views
1

我創建了一個所有者繪製列表框,並將其綁定爲如下所示的向量。最好的方式來告訴所有者繪製listbox重繪一個項目?

vector<wchar_t*> texts; 

lbHWND = CreateWindowExW(NULL, WC_LISTBOX, NULL, 
     WS_CHILD | WS_BORDER | WS_VISIBLE | LBS_NODATA | 
     LBS_OWNERDRAWFIXED | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT, 
     0, 0, 400, 400, tkHWND, (HMENU)IDC_LISTBOX_ENTRY, hInstance, 0); 

SCROLLINFO lbSi = { 0 }; 
lbSi.cbSize = sizeof(SCROLLINFO); 
lbSi.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; 
lbSi.nMin = 0; 
lbSi.nMax = text.size(); 
lbSi.nPage = 20; 
lbSi.nPos = 0; 
SetScrollInfo(lbHWND, SB_VERT, &lbSi, TRUE); 

SendMessageW(lbHWND, LB_RESETCONTENT, 0, 0); 
SendMessage(lbHWND, LB_SETCOUNT, iTotal, 0); 

LRESULT CALLBACK WndProc(HWND phwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
     case WM_MEASUREITEM: 
     { 
      MEASUREITEMSTRUCT* lpmis = (LPMEASUREITEMSTRUCT)lParam; 
      switch (lpmis->CtlID) 
      { 
       case IDC_LISTBOX_ENTRY: 
        lpmis->itemHeight = 20; 
        break; 
       default: 
        break; 
      } 
      return TRUE; 
     } 
     case WM_DRAWITEM: 
     { 
      DRAWITEMSTRUCT* lpdis = (LPDRAWITEMSTRUCT)lParam; 

      if (lpdis->itemID == -1) return; 
      HBRUSH hb = NULL; 
      HPEN hp = NULL; 

      switch (lpdis->itemAction) 
      { 
       case ODA_SELECT: 
       case ODA_DRAWENTIRE: 
        SetBkMode(lpdis->hDC, TRANSPARENT); 
        hb = CreateSolidBrush(lpdis->itemState & ODS_SELECTED ? 0xf1f1f1 : 0xffffff); 
        hp = CreatePen(PS_SOLID, 1, lpdis->itemState & ODS_SELECTED ? 0xcfcfcf : 0xffffff); 
        SelectObject(lpdis->hDC, hp); 
        SelectObject(lpdis->hDC, hb); 

        Rectangle(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, lpdis->rcItem.right, lpdis->rcItem.bottom); 

        TextOut(lpdis->hDC, 
         lpdis->rcItem.left + 5, 
         lpdis->rcItem.top + 2, 
         texts[i], 
         wcslen(texts[i]); 
        break; 
      } 
      if (hp) DeleteObject(hp); 
      if (hb) DeleteObject(hb); 
     } 
    } 
} 

現在假設我在texts更新項目,你能告訴我一個很好的方式來告訴列表框重繪該項目?

目前,我使用下面的代碼:

texts[2] = L"Some text"; 
SendMessageW(lbHWND, LB_RESETCONTENT, 0, 0); 
SendMessage(lbHWND, LB_SETCOUNT, iTotal, 0); 

迫使列表框重繪所有項目,不僅是第三項。有一個更好的方法嗎?

回答

2

您可以使用LB_GETITEMRECT檢索項目的座標,然後InvalidateRect()迫使窗口的特定區域的重繪:

RECT r = {}; 
if (SendMessage(lbHWND, LB_GETITEMRECT, index, &r) != LB_ERR) 
    InvalidateRect(lbHWND, &r, 0); 
+0

好的解決辦法,謝謝:) – Sakura

相關問題