828 lines
19 KiB
C++
828 lines
19 KiB
C++
#include "compatadmin.h"
|
|
|
|
#define LARGE_PAD 4
|
|
#define SMALL_PAD (LARGE_PAD / 2)
|
|
|
|
HWND g_hWndLastFocus = NULL;
|
|
CListView::CListView()
|
|
{
|
|
m_pList = NULL;
|
|
m_pSelected = NULL;
|
|
m_pCurrent;
|
|
m_nEntries = 0;
|
|
m_uCurrent = -1;
|
|
m_uTop = 0;
|
|
m_bHilight = FALSE;
|
|
m_pFreeList = NULL;
|
|
}
|
|
|
|
CListView::~CListView()
|
|
{
|
|
RemoveAllEntries();
|
|
}
|
|
|
|
BOOL CListView::AddEntry(CSTRING & szName, UINT uImage, PVOID pData)
|
|
{
|
|
PLIST pNew;
|
|
|
|
if ( NULL != m_pFreeList ) {
|
|
pNew = m_pFreeList;
|
|
m_pFreeList = m_pFreeList->pNext;
|
|
} else {
|
|
pNew = new LIST;
|
|
|
|
if ( NULL == pNew )
|
|
return FALSE;
|
|
}
|
|
|
|
//pNew->szText = szName;
|
|
lstrcpyn(pNew->szText,szName,sizeof(pNew->szText) / sizeof(TCHAR));
|
|
pNew->pNext = NULL;
|
|
pNew->uImageIndex = uImage;
|
|
pNew->pData = pData;
|
|
|
|
PLIST pWalk = m_pList;
|
|
PLIST pHold;
|
|
|
|
//This code is for adding the node in a sorted fashion.
|
|
while ( NULL != pWalk ) {
|
|
if ( 0 > lstrcmp(szName.pszString,pWalk->szText ))
|
|
break;
|
|
|
|
pHold = pWalk;
|
|
pWalk = pWalk->pNext;
|
|
}
|
|
|
|
if ( pWalk == m_pList ) {
|
|
// Insert at head.
|
|
|
|
pNew->pNext = m_pList; //NULL ?
|
|
m_pList = pNew;
|
|
} else {
|
|
// Insert in place or at tail.
|
|
|
|
pNew->pNext = pWalk;
|
|
pHold->pNext = pNew;
|
|
}
|
|
|
|
++m_nEntries;
|
|
m_uCurrent = -1;
|
|
|
|
// Adjust scrollbar
|
|
|
|
SCROLLINFO Info;
|
|
|
|
Info.cbSize = sizeof(SCROLLINFO);
|
|
Info.fMask = SIF_RANGE;
|
|
Info.nMin = 0;
|
|
Info.nMax = m_nEntries;
|
|
|
|
SetScrollInfo(m_hWnd,SB_VERT,&Info,TRUE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CListView::RemoveEntry(UINT uIndex)
|
|
{
|
|
PLIST pWalk = m_pList;
|
|
PLIST pHold;
|
|
|
|
if ( NULL == m_pList )
|
|
return FALSE;
|
|
|
|
while ( NULL != pWalk && 0 != uIndex ) {
|
|
--uIndex;
|
|
pHold = pWalk;
|
|
pWalk = pWalk->pNext;
|
|
}
|
|
|
|
if ( pWalk == m_pList )
|
|
m_pList = m_pList->pNext;
|
|
else
|
|
pHold->pNext = pWalk->pNext;
|
|
|
|
if ( pWalk == m_pSelected ) {
|
|
m_pSelected = NULL;
|
|
m_pCurrent = NULL;
|
|
|
|
// Send the notification to the parent regarding
|
|
// new selection.
|
|
|
|
LISTVIEWNOTIFY lvn;
|
|
|
|
lvn.Hdr.hwndFrom = m_hWnd;
|
|
lvn.Hdr.idFrom = 0;
|
|
lvn.Hdr.code = LVN_SELCHANGED;
|
|
lvn.pData = NULL;
|
|
|
|
SendMessage(GetParent(m_hWnd),WM_NOTIFY,0,(LPARAM) &lvn);
|
|
}
|
|
|
|
pWalk->pNext = m_pFreeList;
|
|
m_pFreeList = pWalk;
|
|
|
|
//delete pWalk;
|
|
|
|
--m_nEntries;
|
|
m_uCurrent = -1;
|
|
|
|
// Adjust scrollbar
|
|
|
|
SCROLLINFO Info;
|
|
|
|
Info.cbSize = sizeof(SCROLLINFO);
|
|
Info.fMask = SIF_RANGE;
|
|
Info.nMin = 0;
|
|
Info.nMax = m_nEntries;
|
|
|
|
SetScrollInfo(m_hWnd,SB_VERT,&Info,TRUE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
PLIST CListView::getSelected()
|
|
{
|
|
return(this->m_pSelected);
|
|
}
|
|
|
|
BOOL CListView::RemoveAllEntries(void)
|
|
{
|
|
while ( NULL != m_pList ) {
|
|
PLIST pHold = m_pList->pNext;
|
|
|
|
m_pList->pNext = m_pFreeList;
|
|
m_pFreeList = m_pList;
|
|
|
|
//delete m_pList;
|
|
|
|
m_pList = pHold;
|
|
}
|
|
|
|
m_uCurrent = -1;
|
|
m_nEntries = 0;
|
|
m_uTop = 0;
|
|
|
|
// Hide the scroll bar
|
|
|
|
SCROLLINFO Info;
|
|
|
|
Info.cbSize = sizeof(SCROLLINFO);
|
|
Info.fMask = SIF_RANGE;
|
|
Info.nMin = 0;
|
|
Info.nMax = 0;
|
|
|
|
SetScrollInfo(m_hWnd,SB_VERT,&Info,TRUE);
|
|
|
|
LISTVIEWNOTIFY lvn;
|
|
|
|
lvn.Hdr.hwndFrom = m_hWnd;
|
|
lvn.Hdr.idFrom = 0;
|
|
lvn.Hdr.code = LVN_SELCHANGED;
|
|
lvn.pData = NULL;
|
|
|
|
SendMessage(GetParent(m_hWnd),WM_NOTIFY,0,(LPARAM) &lvn);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
UINT CListView::GetNumEntries(void)
|
|
{
|
|
return m_nEntries;
|
|
}
|
|
|
|
CSTRING CListView::GetEntryName(UINT uIndex)
|
|
{
|
|
if ( !FindEntry(uIndex) )
|
|
return CSTRING(TEXT(""));
|
|
|
|
return m_pCurrent->szText;
|
|
}
|
|
|
|
UINT CListView::GetEntryImage(UINT uIndex)
|
|
{
|
|
if ( !FindEntry(uIndex) )
|
|
return -1;
|
|
|
|
return m_pCurrent->uImageIndex;
|
|
}
|
|
|
|
PVOID CListView::GetEntryData(UINT uIndex)
|
|
{
|
|
if ( !FindEntry(uIndex) )
|
|
return NULL;
|
|
|
|
return m_pCurrent->pData;
|
|
}
|
|
|
|
UINT CListView::GetSelectedEntry(void)
|
|
{
|
|
PLIST pWalk = m_pList;
|
|
UINT uIndex = 0;
|
|
|
|
while ( NULL != pWalk ) {
|
|
//K if (pWalk == m_pSelected)
|
|
if ( pWalk == m_pSelected )
|
|
return uIndex;
|
|
|
|
++uIndex;
|
|
pWalk = pWalk->pNext;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
BOOL CListView::FindEntry(UINT uIndex)
|
|
{
|
|
PLIST pWalk = m_pList;
|
|
|
|
if ( m_uCurrent > m_nEntries )
|
|
m_uCurrent = -1;
|
|
|
|
if ( m_uCurrent == uIndex )
|
|
return TRUE;
|
|
|
|
while ( NULL != pWalk && 0 != uIndex ) {
|
|
--uIndex;
|
|
pWalk = pWalk->pNext;
|
|
}
|
|
|
|
if ( NULL == pWalk )
|
|
return FALSE;
|
|
|
|
m_uCurrent = uIndex;
|
|
|
|
m_pCurrent = pWalk;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CListView::msgCreate(void)
|
|
{
|
|
HDC hDC = GetDC(NULL);
|
|
|
|
// Create fonts we're going to use
|
|
|
|
m_hCaptionFont = CreateFont(-MulDiv(9, GetDeviceCaps(hDC, LOGPIXELSY), 72),
|
|
0,
|
|
0,0,
|
|
FW_BOLD,
|
|
FALSE,
|
|
FALSE,
|
|
FALSE,
|
|
DEFAULT_CHARSET,
|
|
OUT_DEFAULT_PRECIS,
|
|
CLIP_DEFAULT_PRECIS,
|
|
DEFAULT_QUALITY,
|
|
DEFAULT_PITCH | FF_SWISS,
|
|
NULL);
|
|
|
|
m_hListFont = CreateFont( -MulDiv(8, GetDeviceCaps(hDC, LOGPIXELSY), 72),
|
|
0,
|
|
0,0,
|
|
FW_THIN,
|
|
FALSE,
|
|
FALSE,
|
|
FALSE,
|
|
DEFAULT_CHARSET,
|
|
OUT_DEFAULT_PRECIS,
|
|
CLIP_DEFAULT_PRECIS,
|
|
DEFAULT_QUALITY,
|
|
DEFAULT_PITCH | FF_SWISS,
|
|
NULL);
|
|
|
|
// Create pens
|
|
|
|
m_hLinePen = (HPEN) GetStockObject(DC_PEN);
|
|
SetDCPenColor(hDC,RGB(00,00,0xff));
|
|
|
|
|
|
// Create brushes
|
|
|
|
m_hGrayBrush = GetSysColorBrush(COLOR_INACTIVECAPTION);
|
|
|
|
m_hWindowBrush = GetSysColorBrush(COLOR_WINDOW);
|
|
|
|
//m_hWindowBrush = CreateSolidBrush(RGB(255,255,176));
|
|
|
|
m_hSelectedBrush = GetSysColorBrush(COLOR_HIGHLIGHT);
|
|
|
|
// Release the DC
|
|
|
|
ReleaseDC(NULL,hDC);
|
|
}
|
|
|
|
void CListView::msgPaint(HDC hWindowDC)
|
|
{
|
|
RECT rRect;
|
|
|
|
GetClientRect(m_hWnd,&rRect);
|
|
|
|
// Update the scroll bar
|
|
|
|
SCROLLINFO Info;
|
|
|
|
Info.cbSize = sizeof(SCROLLINFO);
|
|
Info.fMask = SIF_POS | SIF_TRACKPOS | SIF_RANGE;
|
|
Info.nPos = m_uTop;
|
|
Info.nTrackPos = m_uTop;
|
|
Info.nMin = 0;
|
|
Info.nMax = m_nEntries;
|
|
|
|
SetScrollInfo(m_hWnd,SB_VERT,&Info,TRUE);
|
|
|
|
// Create a working DC
|
|
|
|
HDC hDC = CreateCompatibleDC(hWindowDC);
|
|
HBITMAP hBmp = CreateCompatibleBitmap(hWindowDC,rRect.right,rRect.bottom);
|
|
HBITMAP hBmpOld;
|
|
|
|
hBmpOld = (HBITMAP) SelectObject(hDC,hBmp);
|
|
|
|
// Erase the background
|
|
|
|
FillRect(hDC,&rRect,m_hWindowBrush);
|
|
|
|
// Render the caption
|
|
|
|
RECT rCaptionRect = rRect;
|
|
TCHAR szCaption[MAX_PATH_BUFFSIZE];
|
|
SIZE CaptionSize;
|
|
|
|
GetWindowText(m_hWnd,szCaption,sizeof(szCaption)/sizeof(TCHAR));
|
|
|
|
|
|
SelectObject(hDC,m_hCaptionFont);
|
|
|
|
GetTextExtentPoint32(hDC,szCaption,lstrlen(szCaption),&CaptionSize);
|
|
|
|
rCaptionRect.bottom = CaptionSize.cy + LARGE_PAD;
|
|
|
|
m_uCaptionBottom = rCaptionRect.bottom + SMALL_PAD;
|
|
|
|
if ( m_hWnd == GetFocus() )
|
|
FillRect(hDC,&rCaptionRect,GetSysColorBrush(COLOR_ACTIVECAPTION));
|
|
else
|
|
FillRect(hDC,&rCaptionRect,GetSysColorBrush(COLOR_INACTIVECAPTION));
|
|
|
|
SetTextColor(hDC,GetSysColor(COLOR_CAPTIONTEXT));
|
|
|
|
SetBkMode(hDC,TRANSPARENT);
|
|
|
|
ExtTextOut( hDC,
|
|
rCaptionRect.left + 15,
|
|
rCaptionRect.top + 3,
|
|
ETO_CLIPPED,
|
|
&rCaptionRect,
|
|
szCaption,
|
|
lstrlen(szCaption),
|
|
NULL);
|
|
|
|
MoveToEx(hDC,rCaptionRect.left,rCaptionRect.bottom,NULL);
|
|
|
|
|
|
SelectObject(hDC,GetStockObject(DC_PEN));
|
|
|
|
SetDCPenColor(hDC,GetSysColor(COLOR_BTNFACE));
|
|
|
|
LineTo(hDC,rCaptionRect.right,rCaptionRect.bottom);
|
|
|
|
// Render the list of items.
|
|
|
|
PLIST pWalk = m_pList;
|
|
SIZE TextSize;
|
|
UINT uTop = rCaptionRect.bottom + SMALL_PAD;
|
|
RECT rText;
|
|
UINT uCount=0;
|
|
|
|
// Determine the count so we know background color
|
|
|
|
while ( NULL != pWalk && uCount != m_uTop ) {
|
|
++uCount;
|
|
pWalk = pWalk->pNext;
|
|
}
|
|
|
|
// Set the fonts
|
|
|
|
SelectObject(hDC,m_hListFont);
|
|
SelectObject(hDC,m_hLinePen);
|
|
|
|
// Compute page size
|
|
|
|
GetTextExtentPoint32(hDC,TEXT("Wxypq"),5,&TextSize);
|
|
|
|
m_uTextHeight = TextSize.cy + LARGE_PAD;
|
|
|
|
m_uPageSize = (rRect.bottom - rCaptionRect.bottom) / (m_uTextHeight + SMALL_PAD);
|
|
|
|
// Draw the actual items.
|
|
|
|
while ( NULL != pWalk ) {
|
|
LPTSTR szText = pWalk->szText;
|
|
UINT uLen = lstrlen(pWalk->szText); //.Length();
|
|
HBRUSH hBrush;
|
|
|
|
// Select background and foreground colors
|
|
|
|
if ( 0 == (uCount % 2) )
|
|
// hBrush = m_hGrayBrush;
|
|
hBrush = m_hWindowBrush;
|
|
|
|
else
|
|
hBrush = m_hWindowBrush;
|
|
|
|
/*Here we decide whether the selected item has to be shown as, highlighted
|
|
or not*/
|
|
|
|
|
|
if ( m_pSelected == pWalk )
|
|
if ( m_hWnd == GetFocus() )
|
|
hBrush = m_hSelectedBrush;
|
|
else
|
|
hBrush = m_hGrayBrush;
|
|
|
|
|
|
++uCount;
|
|
|
|
// Compute rects
|
|
|
|
SetRect(&rText,rRect.left,uTop,rRect.right,uTop + m_uTextHeight);
|
|
|
|
// Set the colors
|
|
|
|
|
|
|
|
FillRect(hDC,&rText,hBrush);
|
|
|
|
|
|
// Draw the image.
|
|
|
|
|
|
/*SelectObject(hDC, GetStockObject(DC_BRUSH));
|
|
SetDCBrushColor(hDC,RGB(0,200,0));
|
|
|
|
|
|
Ellipse(hDC, rText.left+5,rText.top, rText.left+15,rText.top + 10);
|
|
*/
|
|
|
|
//10 dia.
|
|
|
|
if ( m_pSelected == pWalk ) {
|
|
|
|
SetTextColor(hDC,GetSysColor(COLOR_HIGHLIGHTTEXT));
|
|
|
|
} else{
|
|
|
|
SetTextColor(hDC,0);
|
|
|
|
}
|
|
|
|
// Draw the text
|
|
|
|
ExtTextOut( hDC,
|
|
rText.left + 20,
|
|
rText.top + SMALL_PAD,
|
|
ETO_CLIPPED,
|
|
&rText,
|
|
szText,
|
|
uLen,
|
|
NULL);
|
|
|
|
// Draw separator line
|
|
|
|
MoveToEx(hDC,rText.left,rText.bottom-1,NULL);
|
|
LineTo(hDC,rText.right,rText.bottom-1);
|
|
|
|
uTop += m_uTextHeight;
|
|
|
|
if ( uTop > (UINT)rRect.bottom )
|
|
break;
|
|
|
|
pWalk = pWalk->pNext;
|
|
}//while ( NULL != pWalk )
|
|
|
|
// Blit the working surface to the window
|
|
|
|
BitBlt( hWindowDC,
|
|
0,0,
|
|
rRect.right,rRect.bottom,
|
|
hDC,
|
|
0,0,
|
|
SRCCOPY);
|
|
|
|
// Release the working DC
|
|
|
|
SelectObject(hDC,hBmpOld);
|
|
DeleteDC(hDC);
|
|
DeleteObject(hBmp);
|
|
}
|
|
|
|
void CListView::ShowHilight(BOOL bHilight)
|
|
{
|
|
/*
|
|
At one time either the m_bHilihgt of the Globallist (CDBView:m_GlobalList)
|
|
or the local list (CDBView:m_LocalList) would be on. ShowHilight would
|
|
therefore be always be called in pair, one TRUE and another FALSE.
|
|
|
|
When the msgPaint of the ListView gets called because of ListView:Refresh, then
|
|
depending upon, whether the bHilight is TRUE or FALSE; a * is drawn alongwith
|
|
the caption for the window.
|
|
|
|
*/
|
|
|
|
m_bHilight = bHilight;
|
|
|
|
Refresh();
|
|
}
|
|
|
|
void CListView::msgEraseBackground(HDC hDC)
|
|
{
|
|
// Do nothing. msgPaint will handle the entire window.
|
|
}
|
|
|
|
void CListView::msgChar(TCHAR chChar)
|
|
{
|
|
|
|
PLIST pWalk = m_pList;
|
|
UINT uCount = 0;
|
|
|
|
chChar = (TCHAR) toupper(chChar);
|
|
|
|
while ( NULL != pWalk ) {
|
|
TCHAR chUpper = (TCHAR) toupper(((LPCTSTR)pWalk->szText)[0]);
|
|
|
|
if ( chUpper == chChar )
|
|
break;
|
|
|
|
++uCount;
|
|
|
|
pWalk = pWalk->pNext;
|
|
}
|
|
|
|
if ( uCount != m_nEntries )
|
|
m_uTop = uCount;
|
|
|
|
if ( NULL != pWalk ) {
|
|
m_pCurrent = pWalk;
|
|
|
|
m_uCurrent = m_uTop;
|
|
|
|
m_pSelected = m_pCurrent;
|
|
|
|
// Send the notification to the parent regarding
|
|
// new selection.
|
|
|
|
LISTVIEWNOTIFY lvn;
|
|
|
|
lvn.Hdr.hwndFrom = m_hWnd;
|
|
lvn.Hdr.idFrom = 0;
|
|
lvn.Hdr.code = LVN_SELCHANGED;
|
|
lvn.pData = m_pCurrent->pData;
|
|
|
|
SendMessage(GetParent(m_hWnd),WM_NOTIFY,0,(LPARAM) &lvn);
|
|
}
|
|
|
|
Refresh();
|
|
}
|
|
|
|
LRESULT CListView::MsgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch ( uMsg ) {
|
|
case WM_LBUTTONDOWN:
|
|
{
|
|
UINT uY = HIWORD(lParam);
|
|
|
|
SetFocus(m_hWnd);
|
|
|
|
NMHDR Hdr;
|
|
|
|
Hdr.hwndFrom = m_hWnd;
|
|
Hdr.idFrom = 0;
|
|
Hdr.code = NM_SETFOCUS;
|
|
|
|
SendMessage(GetParent(m_hWnd),WM_NOTIFY,0,(LPARAM) &Hdr);
|
|
|
|
// On the caption? Nothing to do then.
|
|
|
|
if ( uY < m_uCaptionBottom )
|
|
break;
|
|
|
|
uY = m_uTop + (((uY - m_uCaptionBottom) / m_uTextHeight));
|
|
|
|
m_uCurrent = -1;
|
|
|
|
if ( FindEntry(uY) ) {
|
|
m_pSelected = m_pCurrent;
|
|
|
|
// Send the notification to the parent regarding
|
|
// new selection.
|
|
|
|
LISTVIEWNOTIFY lvn;
|
|
|
|
lvn.Hdr.hwndFrom = m_hWnd;
|
|
lvn.Hdr.idFrom = 0;
|
|
lvn.Hdr.code = LVN_SELCHANGED;
|
|
lvn.pData = m_pCurrent->pData;
|
|
|
|
SendMessage(GetParent(m_hWnd),WM_NOTIFY,0,(LPARAM) &lvn);
|
|
|
|
// Redraw the list view with the new selection.
|
|
|
|
Refresh();
|
|
}
|
|
|
|
m_uCurrent = uY;
|
|
}
|
|
break;
|
|
|
|
case WM_SETFOCUS:
|
|
{
|
|
NMHDR Hdr;
|
|
|
|
Hdr.hwndFrom = m_hWnd;
|
|
Hdr.idFrom = 0;
|
|
Hdr.code = NM_SETFOCUS;
|
|
|
|
SendMessage(GetParent(m_hWnd),WM_NOTIFY,0,(LPARAM) &Hdr);
|
|
Refresh();
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
case WM_KILLFOCUS:
|
|
{
|
|
g_hWndLastFocus = this->m_hWnd;
|
|
|
|
|
|
Refresh();
|
|
}
|
|
break;
|
|
|
|
case WM_KEYDOWN:
|
|
{
|
|
BOOL bSnap = FALSE;
|
|
|
|
switch ( wParam ) {
|
|
case VK_TAB:
|
|
{
|
|
NMKEY Key;
|
|
|
|
Key.hdr.hwndFrom = m_hWnd;
|
|
Key.hdr.idFrom = 0;
|
|
Key.hdr.code = NM_KEYDOWN;
|
|
Key.nVKey = VK_TAB;
|
|
|
|
SendMessage(GetParent(m_hWnd),WM_NOTIFY,0,(LPARAM) &Key);
|
|
}
|
|
break;
|
|
|
|
case VK_HOME:
|
|
{
|
|
m_uCurrent = 0;
|
|
|
|
bSnap = TRUE;
|
|
}
|
|
break;
|
|
|
|
case VK_END:
|
|
{
|
|
m_uCurrent = m_nEntries-1;
|
|
|
|
bSnap = TRUE;
|
|
}
|
|
break;
|
|
case VK_PRIOR:
|
|
{
|
|
if ( m_uCurrent > m_uPageSize )
|
|
m_uCurrent -= m_uPageSize;
|
|
else
|
|
m_uCurrent = 0;
|
|
|
|
bSnap = TRUE;
|
|
}
|
|
break;
|
|
case VK_NEXT:
|
|
{
|
|
if ( m_uCurrent + m_uPageSize < m_nEntries )
|
|
m_uCurrent += m_uPageSize;
|
|
|
|
bSnap = TRUE;
|
|
}
|
|
break;
|
|
case VK_UP:
|
|
{
|
|
if ( m_uCurrent > 0 )
|
|
--m_uCurrent;
|
|
|
|
bSnap = TRUE;
|
|
}
|
|
break;
|
|
|
|
case VK_DOWN:
|
|
{
|
|
if ( m_uCurrent < m_nEntries )
|
|
++m_uCurrent;
|
|
|
|
bSnap = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
if ( bSnap ) {
|
|
if ( (int)m_uCurrent >= 0 ) {
|
|
while ( (int)m_uTop >= (int)m_uCurrent )
|
|
m_uTop -= m_uPageSize;
|
|
|
|
if ( (int)m_uTop < 0 )
|
|
m_uTop = 0;
|
|
|
|
while ( m_uTop + m_uPageSize <= m_uCurrent )
|
|
m_uTop += m_uPageSize;
|
|
} else
|
|
m_uCurrent = 0;
|
|
|
|
UINT uHold = m_uCurrent;
|
|
|
|
m_uCurrent = -1;
|
|
|
|
if ( FindEntry(uHold) ) {
|
|
m_pSelected = m_pCurrent;
|
|
|
|
// Send the notification to the parent regarding
|
|
// new selection.
|
|
|
|
LISTVIEWNOTIFY lvn;
|
|
|
|
lvn.Hdr.hwndFrom = m_hWnd;
|
|
lvn.Hdr.idFrom = 0;
|
|
lvn.Hdr.code = LVN_SELCHANGED;
|
|
lvn.pData = m_pCurrent->pData;
|
|
|
|
SendMessage(GetParent(m_hWnd),WM_NOTIFY,0,(LPARAM) &lvn);
|
|
}
|
|
|
|
m_uCurrent = uHold;
|
|
|
|
Refresh();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_ACTIVATE:
|
|
{
|
|
if ( WA_INACTIVE != wParam )
|
|
SetFocus(m_hWnd);
|
|
}
|
|
break;
|
|
|
|
case WM_VSCROLL:
|
|
{
|
|
switch ( LOWORD(wParam) ) {
|
|
case SB_THUMBPOSITION:
|
|
case SB_THUMBTRACK:
|
|
{
|
|
m_uTop = HIWORD(wParam);
|
|
}
|
|
break;
|
|
|
|
case SB_PAGEUP:
|
|
{
|
|
if ( m_uTop > m_uPageSize )
|
|
m_uTop -= m_uPageSize;
|
|
else
|
|
m_uTop = 0;
|
|
}
|
|
break;
|
|
|
|
case SB_PAGEDOWN:
|
|
{
|
|
if ( m_uTop + m_uPageSize < m_nEntries )
|
|
m_uTop += m_uPageSize;
|
|
}
|
|
break;
|
|
|
|
case SB_LINEUP:
|
|
{
|
|
if ( m_uTop > 0 )
|
|
--m_uTop;
|
|
}
|
|
break;
|
|
|
|
case SB_LINEDOWN:
|
|
{
|
|
if ( m_uTop < m_nEntries )
|
|
if ( m_uTop + m_uPageSize < m_nEntries )
|
|
++m_uTop;
|
|
}
|
|
break;
|
|
}
|
|
|
|
Refresh();
|
|
}
|
|
break;
|
|
}
|
|
|
|
return CWindow::MsgProc(uMsg,wParam,lParam);
|
|
}
|