가상 List-View 컨트롤을 사용하는 방법
이 항목에서는 가상 목록 보기 컨트롤을 사용하는 방법을 보여 줍니다. 함께 제공되는 C++ 코드 예제에서는 가상 목록 보기 컨트롤 알림 메시지를 처리하는 방법, 캐시를 최적화하는 방법 및 캐시에서 항목을 검색하는 방법을 보여 줍니다.
- 알아야 할
- 가상 처리 List-View 제어 알림 코드
- 캐시 최적화
- 캐시 항목을 검색합니다.
- 관련 항목
메모
이 섹션의 예제 코드는 캐시가 애플리케이션 정의 구조의 동적으로 할당된 배열이라고 가정합니다. 구조체는 다음 C++ 코드 예제에서 정의됩니다.
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.
};
알아야 할 사항
기술
필수 구성 요소
- C/C++
- Windows 사용자 인터페이스 프로그래밍
지시
가상 List-View 제어 알림 코드 처리
다른 목록 보기 컨트롤에서 보낸 알림 코드 외에도 가상 목록 보기 컨트롤은 LVN_ODCACHEHINT 및 LVN_ODFINDITEM 알림 코드를 보낼 수 있습니다.
이 애플리케이션 정의 함수는 가상 목록 보기 컨트롤에서 일반적으로 전송되는 알림 메시지를 처리합니다.
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);
}
캐시 최적화
가상 목록 보기 컨트롤은 표시 영역의 내용이 변경되면 LVN_ODCACHEHINT 알림 메시지를 보냅니다. 메시지에는 캐시할 항목 범위에 대한 정보가 포함됩니다. 알림 메시지를 받으면 애플리케이션이 요청된 범위에 대한 항목 정보가 포함된 캐시를 로드할 준비가 되어 있어야 LVN_GETDISPINFO 알림 메시지를 보낼 때 정보를 쉽게 사용할 수 있습니다.
다음 C++ 코드 예제에서 애플리케이션 정의 함수는 가상 목록 보기 컨트롤에서 보낸 캐시에 대한 항목 범위를 허용합니다. 요청된 항목 범위가 아직 캐시되지 않은지 확인하기 위해 확인을 수행한 다음 필요한 전역 메모리를 할당하고 필요한 경우 캐시를 채웁니다.
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.
}
}
}
캐시에서 항목 검색
이 예제 함수는 애플리케이션 정의 구조체의 주소와 목록에 있는 항목의 인덱스를 나타내는 정수 값의 두 매개 변수를 허용합니다. 인덱스 값을 확인하여 원하는 항목이 캐시되는지 검색합니다. 이 경우 함수에 전달된 포인터가 캐시의 위치로 설정됩니다. 항목이 주 캐시 또는 끝 캐시에 없는 경우 항목 정보를 수동으로 찾아야 합니다.
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.
}
}
발언
목록 보기 컨트롤에서 처리되는 창 메시지 목록은 기본 List-View 메시지 처리참조하세요.
전체 예제
관련 항목