1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
HWND PrevWndFunc;
WNDPROC prevWndFunc;
//---------------------------------------------------------------------------
COLORREF colorShade (COLORREF c, float fPercent)
// create a lighter shade (by fPercent %) of a given colour
{
return RGB ((BYTE) ((float) GetRValue (c) * fPercent / 100.0),
(BYTE) ((float) GetGValue (c) * fPercent / 100.0),
(BYTE) ((float) GetBValue (c) * fPercent / 100.0));
}
void PaintAlternatingRows (HWND hWnd)
// re-draw rows with the appropriate background colour
{
RECT rectUpd, // rectangle to update
rectDestin, // temporary storage
rect; // row rectangle
POINT pt;
int iItems,
iTop;
COLORREF
c; // temporary storage
// get the rectangle to be updated
GetUpdateRect (hWnd, &rectUpd, FALSE);
// allow default processing first
CallWindowProc (
(WNDPROC) PrevWndFunc, hWnd, WM_PAINT, 0, 0);
// set the row horizontal dimensions
SetRect (&rect, rectUpd.left, 0, rectUpd.right, 0);
// number of displayed rows
iItems = ListView_GetCountPerPage (hWnd);
// first visible row
iTop = ListView_GetTopIndex (hWnd);
ListView_GetItemPosition (hWnd, iTop, &pt);
for (int i=iTop ; i<=iTop+iItems ; i++) {
// set row vertical dimensions
rect.top = pt.y;
ListView_GetItemPosition (hWnd, i+1, &pt);
rect.bottom = pt.y;
// if row rectangle intersects update rectangle then it requires re-drawing
if (IntersectRect (&rectDestin, &rectUpd, &rect)) {
// change text background colour accordingly
c = (i % 2) ?
colorShade (GetSysColor (COLOR_WINDOW), 95.0) :
GetSysColor (COLOR_WINDOW);
ListView_SetTextBkColor (hWnd, c);
// invalidate the row rectangle then...
InvalidateRect (hWnd, &rect, FALSE);
// ...force default processing
CallWindowProc (
(WNDPROC) prevWndFunc, hWnd, WM_PAINT, 0, 0);
}
}
}
void EraseAlternatingRowBkgnds (HWND hWnd, HDC hDC)
// re-draw row backgrounds with the appropriate background colour
{
RECT rect; // row rectangle
POINT pt;
int iItems,
iTop;
HBRUSH brushCol1, // 1st colour
brushCol2; // 2nd colour
// create coloured brushes
brushCol1 = CreateSolidBrush (GetSysColor (COLOR_WINDOW));
brushCol2 = CreateSolidBrush (colorShade (GetSysColor (COLOR_WINDOW), 95.0));
// get horizontal dimensions of row
GetClientRect (hWnd, &rect);
// number of displayed rows
iItems = ListView_GetCountPerPage (hWnd);
// first visible row
iTop = ListView_GetTopIndex (hWnd);
ListView_GetItemPosition (hWnd, iTop, &pt);
for (int i=iTop ; i<=iTop+iItems ; i++) {
// set row vertical dimensions
rect.top = pt.y;
ListView_GetItemPosition (hWnd, i+1, &pt);
rect.bottom = pt.y;
// fill row with appropriate colour
FillRect (hDC, &rect, (i % 2) ? brushCol2 : brushCol1);
}
// cleanup
DeleteObject (brushCol1);
DeleteObject (brushCol2);
}
LRESULT CALLBACK ListViewWndProc (HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
// subclassed window procedure
{
switch (iMessage) {
case WM_PAINT:
Beep(500,400);
// intercept the WM_PAINT message which is called each time an area
// of the control's client area requires re-drawing
PaintAlternatingRows (hWnd);
return 0;
case WM_ERASEBKGND:
// intercept the WM_ERASEBKGRN message which is called each time an area
// of the control's lient area background requires re-drawing
EraseAlternatingRowBkgnds (hWnd, (HDC) wParam);
return 0;
}
// continue with default message processing
return CallWindowProc (
(WNDPROC) prevWndFunc, hWnd, iMessage, wParam, lParam);
}
|