virtual CListView
Gene Sewell -- genes@fast.net
Monday, May 13, 1996
Hi,
I was asked to provide code for a comment I made a bit ago about virtual
CListView. I chopped the following out of my code - tried to narrow it down
to the essentials. Hope it's of some help to someone!
------------------------------------------------------------------------
I made a new class CDBListView based on CListView. As most folks will have to
do, I am using style: LVS_REPORT | LVS_OWNERDRAWFIXED. I'm only going to
comment on the virtual listbox function here, though.
The important functions are:
void CDBListView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
void CDBListView::VirtualVScroll(long lStart)
------------------------------------------------------------------------
VirtualVScroll is the main function - it's passed the starting record to
display.
// this function sets up listbox and handle's all the virtual functions
void CDBListView::VirtualVScroll(long lStart)
{
if (mx_ListUnderConstruction)
return; // should never happen....
// turn on flag to keep size guy from going crazy....
mx_ListUnderConstruction = TRUE; // keep everyone else quiet....
// we always start from scratch each time...
m_ctlList.DeleteAllItems();
m_TopRec = lStart;
// Prepare a LV_COLUMN structure for GetColumn()
char itemTxt[16];
LV_COLUMN lvColumn;
lvColumn.pszText = itemTxt;
lvColumn.cchTextMax = sizeof( itemTxt );
lvColumn.mask = LVCF_TEXT;
m_CurrentScrollPos = (long)((double)NumRec*lStart);
iMax = min(m_ItemsVisible, m_ProfileDoc->mx_Fmt.recs - m_CurrentScrollPos);
for( i = 0; i <= iMax; ++i )
{
// I'm deleting how I got the data - just that I'm getting it from
// somewhere....
for(curColumn = 0; curColumn < m_NumColumns; curColumn++ )
{
// I made a function, but this is easy...
AddItem( i,
curColumn,
f4str( hField[ curColumn ] ),
i % NUM_STATE_IMAGES,
recno );
}
}
// turn off flag to keep size guy quiet...
mx_ListUnderConstruction = FALSE; // keep everyone else quiet....
}
------------------------------------------------------------------------
This variable changes when the window is resized....
m_ItemsVisible = m_ctlList.GetCountPerPage( );
I generated a user defined message which is mapped to a function to update
the thumb position.
#define WM_UPDATESCROLL_INFO WM_USER +11
It's mapped into the message map as:
ON_MESSAGE(WM_UPDATESCROLL_INFO, UpdateScrollValues)
I invoke this function using the following define:
#define UPDATE_SCROLL_POSITION(pos) PostMessage(WM_UPDATESCROLL_INFO,
(pos), 0)
------------------------------------------------------------------------
Here is where the scroll function is handled:
afx_msg LRESULT CDBListView::UpdateScrollValues(WPARAM wParam, LPARAM lParam)
{
if (!mx_ListUnderConstruction)
{
// In my case, mx_Fmt.recs is the number of items I want to display
if (m_ProfileDoc->mx_Fmt.recs > m_ItemsVisible)
{
m_ctlList.ShowScrollBar(SB_VERT,TRUE);
SCROLLINFO ScrollInfo;
// I had tons of problems with this function
// I sort of loop trying to stabilize the window until
// the scroll bars are stable
BOOL bR = m_ctlList.GetScrollInfo( SB_VERT, &ScrollInfo, SIF_ALL ); //
SIF_POS
if (bR) // often not working....
{
mx_ScrollAttempts = 0; // reset # times around the barn
ScrollInfo.nMin = 1;
ScrollInfo.nMax = m_ProfileDoc->mx_Fmt.recs;
ScrollInfo.nPage = m_ItemsVisible - 1;
ScrollInfo.nPos = wParam;
bR = SetScrollInfo(SB_VERT, &ScrollInfo, 1);
}
else
{
if (mx_ScrollAttempts < MAX_ATTEMPTS)
{
mx_ScrollAttempts++; // yikes - this sucks
m_ctlList.UpdateWindow();
// resubmit request for scroll info - deferred post
UPDATE_SCROLL_POSITION(wParam); // this will update scroll bar pos
}
}
}
else
m_ctlList.ShowScrollBar(SB_VERT,FALSE); // default ...
}
return (LRESULT)1;
}
------------------------------------------------------------------------
Here's how I handle the scroll bars
void CDBListView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
long CurPos;
// make it so on paging, the item at the bottom becomes the item at the top
// and vice versa...
int page = m_ItemsVisible - 1;
switch (nSBCode)
{
case SB_BOTTOM:
CurPos = NumRec;
VirtualVScroll(CurPos);
break;
case SB_ENDSCROLL:
CurPos = -1;
break;
case SB_LINEDOWN:
if (NumRec > (CurPos + (page - BLANK_AT_END)))
{
VirtualVScroll(++CurPos);
}
break;
case SB_LINEUP:
if (CurPos > 0)
{
VirtualVScroll(--CurPos);
}
break;
case SB_PAGEDOWN:
if (NumRec > CurPos)
{
CurPos = min(NumRec - (CurPos + page) + BLANK_AT_END, page );
VirtualVScroll(CurPos);
}
break;
case SB_PAGEUP:
if (CurPos > 0)
{
CurPos = min(CurPos, page );
VirtualVScroll(CurPos);
}
break;
case SB_THUMBPOSITION:
apos = (double)(max(0, nPos - 1)) / (double)(max(NumRec, 1));
CurPos = (long)((double)NumRec*apos); // it's not precise, add buffer
VirtualVScroll(CurPos);
break;
case SB_THUMBTRACK:
// this would be too much overhead....
CurPos = -1;
break;
case SB_TOP:
VirtualVScroll(CurPos = 0);
break;
default:
CurPos = -1;
break;
}
if (CurPos >= 0)
{
UPDATE_SCROLL_POSITION(CurPos); // this will do it all
}
}
note: I allow some blank lines at the bottom to show there's no more...
#define BLANK_AT_END 2
------------------------------------------------------------------------
Guess that covers most of it. I had to delete a bunch of special code,
so I don't know that this will run, but it should....
I'll be happy to explain anything - just ask!
Gene
----
Friend - One who knows all about you and likes you just the same.
Frederic Steppe -- FredericS@msn.com
Tuesday, May 14, 1996
>I was asked to provide code for a comment I made a bit ago about virtual
>CListView. I chopped the following out of my code - tried to narrow it down
>to the essentials. Hope it's of some help to someone!
Thanks, sure it will help.
Do you think it could be possible to modify a little bit this ?
- It would be great to work entirely at the CListCtrl level (subclassed).
- It may be interesting to avoid filling the entire list every time you
scroll (only in the case of a line-scroll)
I didn't implement your sample right now, but I'll work on this asap.
Frederic Steppe (frederics@msn.com)
Gene Sewell -- genes@fast.net
Thursday, May 16, 1996
Hi Frederic,
>>I was asked to provide code for a comment I made a bit ago about virtual
>>CListView. I chopped the following out of my code - tried to narrow it down
>>to the essentials. Hope it's of some help to someone!
>
>Thanks, sure it will help.
Good.
>Do you think it could be possible to modify a little bit this ?
> - It would be great to work entirely at the CListCtrl level (subclassed).
Go for it!
> - It may be interesting to avoid filling the entire list every time you
>scroll (only in the case of a line-scroll)
Actually, in my case, I'm displaying a multi-user database, and it's a good
thing to constantly refresh the screen from the shared database so that the
display is up to date. In every other case, you are right - I think for one
line scrolling, you could just add one new line.
>I didn't implement your sample right now, but I'll work on this asap.
Hope it helps.
Gene
----
This is the gender that invented the polio vacine?
-- Snow Crash
| Вернуться в корень Архива
|