Other Software > Developer's Corner
Contrary ListView Control
(1/1)
Stoic Joker:
Okay, so I've had this nagging ongoing issue with ListView control behavior for a year or so. I thought I'd find a fix for it eventually...But damn-it that's taking too long :)
Here's the rub. I have a standard ListView control that has the grid lines alternate color going down to make it easier to read. Now this control works just fine right up until I add the (below code) use XP style controls line to stdafx.h.
--- Code: C++ ---// This line Allows the Application to Use the XP Themes Control Styles!#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
Then it becomes completely EviL; when program starts all the lines are white, and the last line of the report is a complete artifact nightmare. Below pic is of two different copies of Page Countster, both with the same report open to demonstrate the issue. The top copy is with out the above code, and looks fine. The bottom copy contains the above (XP style controls) code and has an echo of the last line of the report as an artifact that appears to be a line that isn't quite scrolled into view. It also opens as plain white and screws-up the last few lines of the report leaving them as all gray.
I've tried calling InvalidateRect(...) in a variety of places that caused the control to flicker so badly it was a seizure risk...But still no joy.
What am I missing?
Stoic Joker:
Hm... Okay, I'll assume by the lack of response that there's not enough information. So here's (the code I'm working with) a bit more detail:
ListView control is subclassed in WM_CREATE like so:
--- Code: C++ ---///////////////////////////////////////////////////////////// prevWndFunc = (FARPROC)(LONG_PTR)GetWindowLong (g_hListBox, GWL_WNDPROC); SetWindowLong (g_hListBox, GWL_WNDPROC, (LONG)(LRESULT)ListViewWndProc); /////////////////////////////////////////////////////////////
And here is the procedure:
--- Code: C++ ---#include "stdafx.h" #define ROW_SHADE 90extern FARPROC prevWndFunc; //=========================================================//-> create a lighter shade (by fPercent %) of a given colorCOLORREF colorShade(COLORREF c, BYTE fPercent) { return RGB((GetRValue (c) * fPercent / 100.0), (GetGValue (c) * fPercent / 100.0), (GetBValue (c) * fPercent / 100.0));} //====================================================//-> re-draw rows with the appropriate background colorvoid PaintAlternatingRows(HWND hWnd) { int iItems, iTop; RECT rectDestin, // temporary storage rectUpd, // rectangle to update rect; // row rectangle POINT pt; // >>>--->.<---<<< 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++) { char szPCount[MIN_BUFF] = {0};// 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), ROW_SHADE) : GetSysColor(COLOR_WINDOW); ListView_SetTextBkColor(hWnd, c);//--------------------------------------------------------------------------------------------> ListView_GetItemText(hWnd, i, 5, szPCount, sizeof(szPCount)); if(strcmp(szPCount, "OffLine!")) { //---++++++---> String Match = 0 <-> So... ListView_SetTextColor(hWnd, CLR_DEFAULT); //-> OnLine Printers Stay Black }else{ //-------------------------------------------------> ...and... ListView_SetTextColor(hWnd, RGB(255, 0, 0)); // OffLine Printers Turn Red }//-------------------------------------------------------------------------------------------->// invalidate the row rectangle then... InvalidateRect(hWnd, &rect, FALSE);// ...force default processing CallWindowProc((WNDPROC)prevWndFunc, hWnd, WM_PAINT, 0, 0); } }}// re-draw row backgrounds with the appropriate background colourvoid EraseAlternatingRowBkgnds(HWND hWnd, HDC hDC) { int iItems, iTop; HBRUSH brushCol1, // 1st color brushCol2; // 2nd color RECT rect; // row rectangle POINT pt; // create colored brushes brushCol1 = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); brushCol2 = CreateSolidBrush(colorShade(GetSysColor(COLOR_WINDOW), ROW_SHADE));// 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 color FillRect(hDC, &rect, (i % 2) ? brushCol2 : brushCol1); } // cleanup DeleteObject(brushCol1); DeleteObject(brushCol2);} //=======================================================================================//-----------------------------------------------------------> SubClassed Window ProcedureLRESULT CALLBACK ListViewWndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { switch(iMessage) { case WM_PAINT:// 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 client area background requires re-drawing EraseAlternatingRowBkgnds(hWnd, (HDC) wParam); return 0; } // continue with default message processing return CallWindowProc((WNDPROC)prevWndFunc, hWnd, iMessage, wParam, lParam);}
Navigation
[0] Message Index
Go to full version