WindowsXP-SP1/admin/hmonitor/snapin/hmlist.cpp
2020-09-30 16:53:49 +02:00

318 lines
7.5 KiB
C++

// HMList.cpp : implementation file
//
#include "stdafx.h"
#include "Snapin.h"
#include "HMList.h"
#include "SortClass.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int _IDM_HEADER_CONTEXTMENU_BASE = 1500;
/////////////////////////////////////////////////////////////////////////////
// CHMList
/////////////////////////////////////////////////////////////////////////////
// Construction/Destruction
/////////////////////////////////////////////////////////////////////////////
CHMList::CHMList()
{
m_bSorting = false;
m_lColumnSortStates = 0;
}
CHMList::~CHMList()
{
}
/////////////////////////////////////////////////////////////////////////////
// Sorting Operations
/////////////////////////////////////////////////////////////////////////////
void CHMList::SortColumn( int iSubItem, bool bSortingMultipleColumns )
{
int iNumCombinedSortedCols = GetNumCombinedSortedColumns();
m_bSorting = true;
if( bSortingMultipleColumns )
{
if( NotInCombinedSortedColumnList( iSubItem ) )
{
m_aCombinedSortedColumns[ iNumCombinedSortedCols++ ] = iSubItem;
}
else
{
MoveItemInCombinedSortedListToEnd( iSubItem );
}
for( int i = iNumCombinedSortedCols - 1; i >= 0 ; i-- )
{
SORT_STATE ssEachItem = GetItemSortState( m_aCombinedSortedColumns[i] );
if( iNumCombinedSortedCols - 1 != i )
{
ssEachItem = (SORT_STATE)!ssEachItem;
}
CSortClass csc(this, m_aCombinedSortedColumns[i] );
csc.Sort( ssEachItem ? true : false );
if( i == iNumCombinedSortedCols - 1 )
{ //Only swap the last column's sort order.
m_headerctrl.SetSortImage( m_aCombinedSortedColumns[i], ssEachItem ? true : false );
SetItemSortState( m_aCombinedSortedColumns[i] , (SORT_STATE)!ssEachItem );
}
}
}
else
{
m_headerctrl.RemoveAllSortImages();
EmptyArray(m_aCombinedSortedColumns);
m_aCombinedSortedColumns[ 0 ] = iSubItem;
SORT_STATE ssEachItem = GetItemSortState( iSubItem );
CSortClass csc(this, iSubItem );
csc.Sort( ssEachItem ? true : false );
m_headerctrl.SetSortImage( iSubItem, ssEachItem ? true : false );
SetItemSortState( iSubItem , (SORT_STATE)!ssEachItem );
}
m_bSorting = false;
}
const int CHMList::GetNumCombinedSortedColumns() const
{
for( int i = 0; i < MAX_COLUMNS; i++ )
{
if( m_aCombinedSortedColumns[i] == -1 )
{
return i;
}
}
return MAX_COLUMNS;
}
bool CHMList::NotInCombinedSortedColumnList(int iItem) const
{
int iNumCombinedSortedColumns = GetNumCombinedSortedColumns();
for( int i = 0; i < iNumCombinedSortedColumns; i++ )
{
if( m_aCombinedSortedColumns[i] == iItem )
{
return false;
}
}
return true;
}
void CHMList::MoveItemInCombinedSortedListToEnd(int iItem)
{
int iNumCombinedSortedColumns = GetNumCombinedSortedColumns();
int aCombinedSortedColumns[MAX_COLUMNS];
memset( aCombinedSortedColumns, -1, MAX_COLUMNS );
int iItemIndex = FindItemInCombedSortedList( iItem );
if( iItemIndex != -1 )
{
if( iItemIndex > 0 )
{
memcpy( aCombinedSortedColumns, m_aCombinedSortedColumns, iItemIndex * sizeof( int ) );
memcpy( &aCombinedSortedColumns[iItemIndex], &m_aCombinedSortedColumns[iItemIndex + 1], (iNumCombinedSortedColumns - iItemIndex - 1) * sizeof(int) );
}
}
aCombinedSortedColumns[ iNumCombinedSortedColumns - 1 ] = iItem;
memcpy( m_aCombinedSortedColumns, aCombinedSortedColumns, MAX_COLUMNS * sizeof(int) );
for( int i = 0; i < MAX_COLUMNS ; i++ )
{
if( aCombinedSortedColumns[i] == -1 )
break;
}
}
const SORT_STATE CHMList::GetItemSortState( int iItem ) const
{
return (SORT_STATE)((m_lColumnSortStates) & ( 1 << iItem ));
}
void CHMList::SetItemSortState(int iItem, SORT_STATE bSortState)
{
if( bSortState != GetItemSortState( iItem ) )
{
m_lColumnSortStates ^= (1 << iItem);
}
}
void CHMList::EmptyArray( int *pArray )
{
memset( pArray, -1, MAX_COLUMNS );
}
const bool CHMList::IsColumnNumeric( int iCol ) const
{
for( int i = 0; i < m_aNumericColumns.GetSize(); i++ )
{
if( m_aNumericColumns.GetAt( i ) == (UINT)iCol )
{
return true;
}
}
return false;
}
int CHMList::FindItemInCombedSortedList( int iItem )
{
int iNumCombinedSortedColumns = GetNumCombinedSortedColumns();
for( int i = 0; i < iNumCombinedSortedColumns; i++ )
{
if(m_aCombinedSortedColumns[i] == iItem )
{
return i;
}
}
return -1;
}
const int CHMList::IsControlPressed() const
{
return (::GetKeyState( VK_SHIFT ) < 0 );
}
BEGIN_MESSAGE_MAP(CHMList, CListCtrl)
//{{AFX_MSG_MAP(CHMList)
ON_WM_CREATE()
ON_WM_CONTEXTMENU()
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHMList message handlers
BOOL CHMList::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style = cs.style|LVS_EDITLABELS|LVS_REPORT;
cs.lpszClass = _T("SysListView32");
return CListCtrl::PreCreateWindow(cs);
}
int CHMList::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
m_headerctrl.SubclassWindow( GetHeaderCtrl()->GetSafeHwnd() );
return 0;
}
void CHMList::OnContextMenu(CWnd* pWnd, CPoint point)
{
// Handle right click on the header control
if( pWnd->GetSafeHwnd() == GetHeaderCtrl()->GetSafeHwnd() )
{
CMenu listcontextmenu;
listcontextmenu.CreatePopupMenu();
/* menu.LoadMenu(IDR_MENU_HEADER_CONTEXT);
CMenu& listcontextmenu = *menu.GetSubMenu(0);
CHeaderCtrl* pHdrCtrl = GetHeaderCtrl();
DWORD dwStyle = GetWindowLong(pHdrCtrl->GetSafeHwnd(),GWL_STYLE);
if( dwStyle & HDS_FILTERBAR )
{
listcontextmenu.CheckMenuItem(ID_HEADERCONTEXT_FILTERBAR,MF_BYCOMMAND|MF_CHECKED);
}
*/
int iCol = 0;
TCHAR szName[255];
LVCOLUMN lvc;
ZeroMemory(&lvc,sizeof(LVCOLUMN));
lvc.mask = LVCF_TEXT|LVCF_WIDTH;
lvc.pszText = szName;
lvc.cchTextMax = 255;
while( GetColumn(iCol,&lvc) )
{
if( lvc.cx > 0 )
{
listcontextmenu.AppendMenu(MF_CHECKED|MF_STRING,_IDM_HEADER_CONTEXTMENU_BASE+iCol,lvc.pszText);
}
else
{
listcontextmenu.AppendMenu(MF_UNCHECKED|MF_STRING,_IDM_HEADER_CONTEXTMENU_BASE+iCol,lvc.pszText);
}
iCol++;
}
listcontextmenu.TrackPopupMenu(TPM_LEFTALIGN,point.x,point.y,this);
listcontextmenu.DestroyMenu();
}
}
void CHMList::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if( IsControlPressed() )
{
SortColumn( pNMListView->iSubItem, MULTI_COLUMN_SORT );
}
else
{
SortColumn( pNMListView->iSubItem, SINGLE_COLUMN_SORT );
}
*pResult = 0;
}
void CHMList::OnDestroy()
{
CListCtrl::OnDestroy();
}
BOOL CHMList::OnCommand(WPARAM wParam, LPARAM lParam)
{
WORD wID = LOWORD(wParam);
if( wID >= _IDM_HEADER_CONTEXTMENU_BASE )
{
TCHAR szName[255];
int iCol = wID - _IDM_HEADER_CONTEXTMENU_BASE;
LVCOLUMN lvc;
ZeroMemory(&lvc,sizeof(LVCOLUMN));
lvc.mask = LVCF_TEXT|LVCF_WIDTH;
lvc.cx = 0;
lvc.pszText = szName;
lvc.cchTextMax = 255;
GetColumn(iCol,&lvc);
if( lvc.cx == 0 )
{
CDC dc;
dc.Attach(::GetDC(NULL));
// get the width in pixels of the item
CSize size = dc.GetTextExtent(lvc.pszText);
lvc.cx = size.cx + 50;
HDC hDC = dc.Detach();
::ReleaseDC(NULL,hDC);
}
else
{
lvc.cx = 0;
}
SetColumn(iCol,&lvc);
}
return CListCtrl::OnCommand(wParam, lParam);
}