Zahra19977
Zahra19977

Reputation: 355

Drawing list view items by WM_DRAWITEM

I need to set height of list view items in win32 api so i use LVS_OWNERDRAWFIXED to get WM_MEASUREITEM message and set height of items.But when i use LVS_OWNERDRAWFIXED in CreateWindow() when creating the list, all items that i inserted by ListView_InsertItem() unappeared.

I have read in this case should draw items when WM_DRAWITEM is sent to the parent window procedure.I know there is a pointer to DRAWITEMSTRUCT struct in the lParam but i dont know how to force it to display the items.

I have the following code inside WinMain() :

 HWND hwndList1 = CreateWindow(WC_LISTVIEW , L"" ,  WS_VISIBLE | WS_CHILD | LVS_REPORT | WS_BORDER  |  WS_VSCROLL | LVS_OWNERDRAWFIXED , 10 , 10 , width , height, hwnd, NULL, GetModuleHandle(NULL), 0); 
 CreateItem(hwndList1 , "My item");

And these are CreateItem() and WndProc() :

int CreateItem(HWND hwndList, char*  Text)
{ 
  LVITEM lvi = {0};

  lvi.mask = LVIF_TEXT | LVCF_FMT | LVCFMT_LEFT;
  lvi.pszText = (LPWSTR)Text;

return ListView_InsertItem(hwndList, &lvi);
} 


LRESULT CALLBACK WndProc( HWND hwnd , UINT msg , WPARAM wParam , LPARAM lParam)
{
switch(msg){


  case WM_DRAWITEM:{ //I dont know what to do
     }
     break;

  case WM_MEASUREITEM:{
            MEASUREITEMSTRUCT* m= (MEASUREITEMSTRUCT*) lParam;
            m->itemHeight=25;
            }
            break;

  case WM_CLOSE:
    DestroyWindow( hwnd );
    break;

  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  default:
    return DefWindowProc( hwnd , msg , wParam , lParam );
 }
return 0;
}

Please how to draw and display items?

Upvotes: 3

Views: 1896

Answers (1)

Adrian Mole
Adrian Mole

Reputation: 51894

To handle WM_DRAWITEM, you need to actually draw each item using WinAPI GDI calls! As a starting point, the following may give you some clues:

case WM_DRAWITEM: { //I dont know what to do
    LPDRAWITEMSTRUCT pDIS = (LPDRAWITEMSTRUCT)(lParam);
    HDC hDC = pDIS->hDC;
    RECT rc = pDIS->rcItem;
    HBRUSH bg = (HBRUSH)(::GetStockObject(LTGRAY_BRUSH));
    HPEN pn = (HPEN)(::GetStockObject(BLACK_PEN));
    ::SelectObject(hDC, bg);
    ::SelectObject(hDC, pn);
    ::SetTextColor(hDC, RGB(0, 0, 0));
    const wchar_t *text = L"Dummy Text";
    ::Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
    ::DrawText(hDC, text, wcslen(text), &rc, DT_SINGLELINE | DT_VCENTER);
}
break;

Obviously, there's a lot more you will need to do in a real-world program, like fetching the actual text for the item and changing the colours of text and background, depending on the selection state, etc. You can get much of the information you need from the various members of the DRAWITEMSTRUCT that is passed.

If this is helpful, let me know and we can think about further refinements. But try this 'dummy run' first, and see if it works and you can understand what's happening.

Upvotes: 2

Related Questions