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
| Вернуться в корень Архива |