Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Det här avsnittet visar hur du arbetar med kontroller för virtuell listvy. I de tillhörande C++-kodexemplen visas hur du bearbetar meddelanden om kontroll av virtuell listvy, hur du optimerar cachen och hur du hämtar ett objekt från cacheminnet.
- Vad du behöver veta
- Processaps Virtuala List-View Kontrollnotificationskoder
- Optimera cachen
- Hämta ett objekt från cachen
- Relaterade ämnen
Not
Exempelkoden i det här avsnittet förutsätter att cachen är en dynamiskt allokerad matris med programdefinierade strukturer. Strukturen definieras i följande C++-kodexempel.
struct RndItem
{
int iIcon; // Bitmap assigned to this item.
UINT state; // Item state value.
TCHAR Title[BUFFER_SIZE]; // BUFFER_SIZE is a user-defined macro value.
TCHAR SubText1[BUFFER_SIZE]; // Text for the label of the first sub-item.
TCHAR SubText2[BUFFER_SIZE]; // Text for the label of the second item.
};
Vad du behöver veta
Teknologier
Förutsättningar
- C/C++
- Programmering av Windows-användargränssnitt
Instruktioner
Bearbeta meddelandekoder för virtuell List-View-kontroll
Förutom de meddelandekoder som skickas av andra listvykontroller kan virtuella listvisningskontroller också skicka LVN_ODCACHEHINT- och LVN_ODFINDITEM-meddelandekoderna.
Den här programdefinierade funktionen hanterar meddelanden som ofta skickas från en virtuell listvykontroll.
LRESULT OnNotify(HWND hwnd, NMHDR* pnmhdr)
{
HRESULT hr;
LRESULT lrt = FALSE;
switch (pnmhdr->code)
{
case LVN_GETDISPINFO:
{
RndItem rndItem;
NMLVDISPINFO* plvdi = (NMLVDISPINFO*) pnmhdr;
if (-1 == plvdi->item.iItem)
{
OutputDebugString(TEXT("LVOWNER: Request for -1 item?\n"));
DebugBreak();
}
// Retrieve information for item at index iItem.
RetrieveItem( &rndItem, plvdi->item.iItem );
if(plvdi->item.mask & LVIF_STATE)
{
// Fill in the state information.
plvdi->item.state |= rndItem.state;
}
if(plvdi->item.mask & LVIF_IMAGE)
{
// Fill in the image information.
plvdi->item.iImage = rndItem.iIcon;
}
if(plvdi->item.mask & LVIF_TEXT)
{
// Fill in the text information.
switch (plvdi->item.iSubItem)
{
case 0:
// Copy the main item text.
hr = StringCchCopy(plvdi->item.pszText, MAX_COUNT, rndItem.Title);
if(FAILED(hr))
{
// Insert error handling code here. MAX_COUNT
// is a user-defined value. You must not enter
// more characters than specified by MAX_COUNT or
// the text will be truncated.
}
break;
case 1:
// Copy SubItem1 text.
hr = StringCchCopy( plvdi->item.pszText, MAX_COUNT, rndItem.SubText1);
if(FAILED(hr))
{
// Insert error handling code here. MAX_COUNT
// is a user-defined value. You must not enter
// more characters than specified by MAX_COUNT or
// the text will be truncated..
}
break;
case 2:
// Copy SubItem2 text.
hr = StringCchCopy(plvdi->item.pszText, MAX_COUNT, rndItem.SubText2);
if(FAILED(hr))
{
// Insert error handling code here. MAX_COUNT
// is a user-defined value. You must not enter
// more characters than specified by MAX_COUNT or
// the text will be truncated..
}
break;
default:
break;
}
}
lrt = FALSE;
break;
}
case LVN_ODCACHEHINT:
{
NMLVCACHEHINT* pcachehint = (NMLVCACHEHINT*) pnmhdr;
// Load the cache with the recommended range.
PrepCache( pcachehint->iFrom, pcachehint->iTo );
break;
}
case LVN_ODFINDITEM:
{
LPNMLVFINDITEM pnmfi = NULL;
pnmfi = (LPNMLVFINDITEM)pnmhdr;
// Call a user-defined function that finds the index according to
// LVFINDINFO (which is embedded in the LPNMLVFINDITEM structure).
// If nothing is found, then set the return value to -1.
break;
}
default:
break;
} // End Switch block.
return(lrt);
}
Optimera cachen
En virtuell listvykontroll skickar ett LVN_ODCACHEHINT meddelandemeddelande när innehållet i dess visningsområde har ändrats. Meddelandet innehåller information om det intervall med objekt som ska cachelagras. När du tar emot meddelandemeddelandet måste programmet vara förberett på att läsa in cachen med objektinformation för det begärda intervallet så att informationen blir lättillgänglig när ett LVN_GETDISPINFO meddelandemeddelande skickas.
I följande C++-kodexempel accepterar den programdefinierade funktionen intervallet med objekt för cacheminnet som skickas av en virtuell listvykontroll. Den utför en verifiering för att fastställa att det begärda intervallet av objekt inte redan har cachelagrats, och sedan allokerar det nödvändiga globala minnet och fyller cachen om det behövs.
void PrepCache(int iFrom, int iTo)
{
/* Global Variables
* g_priCache[ ]: the main cache.
* g_iCache: the index of the first item in the main cache.
* g_cCache: the count of items in the main cache.
*
* g_priEndCache[ ]: the cache of items at the end of the list.
* g_iEndCache: the index of the first item in the end cache.
* g_cEndCache: the count of items in the end cache.
*/
// Local Variables
int i;
BOOL fOLFrom = FALSE;
BOOL fOLTo = FALSE;
// Check to see if this is the end cache.
if ((iTo == g_cCache - 1) && ((iTo - iFrom) < 30)) // 30 entries wide.
{
// Check to see if this is a portion of the current end cache.
if ((g_cCache) && (iFrom >= g_iEndCache) && (iFrom < g_iEndCache+g_cEndCache))
return;
// If it is a part of current end cache, no loading is necessary.
// This is a new end cache. Free the old memory.
if ( g_priEndCache )
GlobalFree( g_priEndCache );
// Set the index and count values for the new end cache,
// and then retrieve the memory.
g_iEndCache = iFrom;
g_cEndCache = (iTo - iFrom + 1);
g_priEndCache = (RndItem *)GlobalAlloc(GPTR, sizeof(RndItem) * g_cEndCache);
if (! g_priEndCache)
{
// TODO: Out of memory. Perform error handling.
}
// Loop to fill the cache with the recommended items.
for (i=0; i<g_cEndCache; i++)
{
// TODO: Call a function that accesses item information and
// fills a cache element.
}
}
else
{
// It is not a member of the current end cache.
// Try the primary cache instead.
// Check to see if iFrom is within the primary cache.
if ((g_cCache) && (iFrom >= g_iCache) && (iFrom < g_iCache+g_cCache))
fOLFrom = TRUE;
// Check to see if iTo is within the primary cache.
if ((g_cCache) && (iTo >= g_iCache) && (iTo <= g_iCache+g_cCache))
fOLTo = TRUE;
// do nothing if both iFrom and iTo are within the current cache.
if (fOLFrom && fOLTo)
return;
// Enlarge the cache size rather than make it specific to this hint.
if (fOLFrom)
iFrom = g_iCache;
else if (fOLTo)
iTo = g_iCache + g_cCache;
// A new primary cache is needed. Free the old primary cache.
if ( g_priCache )
GlobalFree( g_priCache );
// Set the index and count values for the new primary cache,
// and then retrieve the memory.
g_iCache = iFrom;
g_cCache = (iTo - iFrom + 1);
g_priCache = (RndItem *)GlobalAlloc( GPTR, sizeof( RndItem ) * g_cCache );
if (!g_priCache)
{
// TODO: Out of memory. Do error handling.
}
// Loop to fill the cache with the recommended items.
for (i=0; i<g_cCache; i++)
{
// TODO: Call a function that accesses item information
// and fills a cache element.
}
}
}
Hämta ett objekt från cachen
Den här exempelfunktionen accepterar två parametrar, adressen till den programdefinierade strukturen och ett heltalsvärde som representerar indexet för objektet i listan. Den kontrollerar indexvärdet för att identifiera om det önskade objektet cachelagras. I så fall är pekaren som skickades till funktionen inställd på en plats i cacheminnet. Om objektet inte finns i huvud- eller slutcachen måste objektinformationen finnas manuellt.
void RetrieveItem( RndItem * prndItem, int index )
{
// Global Variables
// g_priCache[ ]: the main cache.
// g_iCache: the index of the first item in the main cache.
// c_cCache: the count of items in the main cache.
//
// g_priEndCache[ ]: the cache of items at the end of the list.
// g_iEndCache: the index of the first item in the end cache.
// g_cEndCache: the count of items in the end cache.
//
// Check to see if the item is in the main cache.
if ((index >= g_iCache) && (index < g_iCache + g_cCache))
*prndItem = g_priCache[index-g_iCache];
// If it is not in the main cache, then check to see if
// the item is in the end area cache.
else if ((index >= g_iEndCache) && (index < g_iEndCache + g_cEndCache))
*prndItem = g_priEndCache[index-g_iEndCache];
else
{
// The item is not in either cache.
// Therefore, retrieve the item information manually.
}
}
Anmärkningar
En lista över de fönstermeddelanden som bearbetas av en listvykontroll finns i Standard List-View Meddelandebearbetning.
Fullständigt exempel
Relaterade ämnen