⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mylistctrl.cpp

📁 我上载了那么多怎么都说已经有上载的啦
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// MyListCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "GPMIS.h"
#include "MyListCtrl.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <afxdisp.h>	// OLE stuff
#include <shlwapi.h>	// Shell functions (PathFindExtension() in this case)
#include <afxpriv.h>	// ANSI to/from Unicode conversion macros
#include "ComboItem.h"
#include "EditItem.h"
#include "global.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMyListCtrl

CMyListCtrl::CMyListCtrl() : CListCtrl(),m_nSortedColumn(-1),
m_bSortAscending(TRUE),m_nCompareAs(ELCT_STRING_CASE),
m_nDateTimeType(0),m_nMinColumnWidth(10),m_nMaxColumnWidth(1000)
{
	for( int i = 0; i<64; i++ )
	{
		m_bCanEdit[i] = FALSE;
		m_nColumnType[i] = ELCT_STRING_CASE;
		m_nColumnCtrl[i] = eLast;
	}
	m_nDisableStartRow = -1;; 
	m_nDisableEndRow = -1; 

	//
	// Default drop mode
	//
	m_dropMode.iMask = DL_ACCEPT_FILES | DL_ACCEPT_FOLDERS;
	m_dropMode.pfnCallback = NULL;

	//
	// Initialize OLE libraries
	//
	m_bMustUninitOLE = FALSE;
	_AFX_THREAD_STATE* pState = AfxGetThreadState();
	if (!pState->m_bNeedTerm) // TRUE if OleUninitialize needs to be called
	{
		HRESULT hr = ::OleInitialize(NULL);
		if (FAILED(hr))
			// Or something of your choosing...
			AfxMessageBox(_T("OLE initialization failed.\n\nMake sure that the OLE libraries are the correct version."));
		else
			m_bMustUninitOLE = TRUE;
	}

	m_bSortFirstCol = TRUE;
}

CMyListCtrl::~CMyListCtrl()
{
	if(m_bMustUninitOLE)
	{
		::OleUninitialize();
	}

	m_MultiHeadArray.RemoveAll();
}

//////////////////////////////////////////////////////////////////////
// Message Maps
//////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CMyListCtrl)
	ON_NOTIFY(HDN_ITEMCLICKA, 0, OnHeaderClicked)
	ON_NOTIFY(HDN_ITEMCLICKW, 0, OnHeaderClicked)
	ON_WM_DROPFILES()
	ON_WM_CREATE()
	ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
	ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
	ON_NOTIFY_REFLECT(LVN_KEYDOWN, OnKeydown)
//}}AFX_MSG_MAP
	ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
	ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
END_MESSAGE_MAP()


//////////////////////////////////////////////////////////////////////
// AddRow()
// Parameters:  nRow  - .
//				lpszItem - 
//				oid
// Action:     Insert a item into list
//////////////////////////////////////////////////////////////////////
int CMyListCtrl::AddRow(int nRow, LPCTSTR lpszItem )
{
	int nRet = CListCtrl::InsertItem(nRow,lpszItem);

	return nRet;
}

int CMyListCtrl::AddRow( const LVITEM* pItem )
{
	int nRet = CListCtrl::InsertItem(pItem);

	return nRet;
}

//////////////////////////////////////////////////////////////////////
// DeleteRow()
// Parameters:  nRow  - .
//				oid
// Action:     Delete a item into list
//////////////////////////////////////////////////////////////////////
int CMyListCtrl::DeleteRow(int nRow)
{
	int nRet = CListCtrl::DeleteItem(nRow);
	return nRet;
}
//////////////////////////////////////////////////////////////////////
// OnHeaderClicked()
// Parameters:  pNMHDR  - Contains information about a notificationmessage.
//        LRESULT - Contains the result from the message
// Action:     Sort the column that the user clicks on. If it is not
//        the same column as the last sorting then sorting ascending.
//        If is the same column then toggle the sorting style. The
//        list only recieves this message if the "no sort header" is
//        NOT checked in the resource.// Returns:    Nothing.
//////////////////////////////////////////////////////////////////////
void CMyListCtrl::OnHeaderClicked(NMHDR* pNMHDR, LRESULT* pResult)
{
	HD_NOTIFY *phdNotify = (HD_NOTIFY *)pNMHDR;
	if (phdNotify->iButton == 0)
	{
		m_bSortAscending = (phdNotify->iItem == m_nSortedColumn) ?!m_bSortAscending : TRUE;
		m_nSortedColumn = phdNotify->iItem;
		m_nCompareAs = (ListCompareType)m_nColumnType[m_nSortedColumn];
		Sort();
	}
	*pResult = 0;
}

//////////////////////////////////////////////////////////////////////// Sort()
// Parameters:  None.
// Action:      This function is called when the user clicks on a column
//              header. Derived classes should override this function
//              if they want to change the m_nCompareAs based on the
//              the column that was selected.// Returns:     Nothing.
//////////////////////////////////////////////////////////////////////
void CMyListCtrl::Sort()
{
	Sort(m_nSortedColumn, m_bSortAscending, m_nCompareAs);
}

//////////////////////////////////////////////////////////////////////// Sort()
// Parameters:  nColumn - column to sort by
//              bAscending - TRUE ascending sort, FALSE descending
//              nCompareAs - How to compare the values as
// Action:      Set all the sorting attributes then do a quick sort
//              on the whole list. Derived class may want to override
//              this if they want to use a different sort algorithm or
//              want to use a different range// Returns:     Nothing.
//////////////////////////////////////////////////////////////////////
void CMyListCtrl::Sort(int nColumn, BOOL bAscending, ListCompareType nCompareAs)
{
	m_nSortedColumn = nColumn;
	m_bSortAscending = bAscending;
	m_nCompareAs = nCompareAs;
	QuickSort(0, GetItemCount() - 1);
}

//////////////////////////////////////////////////////////////////////
// QuickSort()
// Parameters:  p - start position, usually index 0
//              q - end position, usually last index
// Action:      Standard quick sort algorthim// Returns:     Nothing.
//////////////////////////////////////////////////////////////////////
void CMyListCtrl::QuickSort(int p, int r)
{
	if (p < r)
	{
		int q = Partition(p, r);
		QuickSort(p, q);
		QuickSort(q + 1, r);
	}
}

//////////////////////////////////////////////////////////////////////
// Partition()
// Parameters:  p - start position//              q - end position
// Action:      Partition of the array in the quick sort algorithm
// Returns:     Nothing.
///////////////////////////////////////////////////////////////////
int CMyListCtrl::Partition(int p, int r)
{   
	CString tmp;    
	CString x = GetItemText( p, m_nSortedColumn);
    int i = p - 1;    
	int j = r + 1;    
	while (i < j)   
	{        
		do       
		{
            j--;           
			tmp = GetItemText(j,  m_nSortedColumn);
        } 
		while (CompareBy(tmp, x, m_bSortAscending ? ELOT_GT :   ELOT_LT));
        do 
		{
            i++;
            tmp = GetItemText(i, m_nSortedColumn);
        } 
		while (CompareBy(tmp, x, m_bSortAscending ? ELOT_LT :   ELOT_GT));
        if (i < j)        
		{            
			SwapRow(i, j);        
		}    
	}   
	return j;
}

//////////////////////////////////////////////////////////////////////
// CompareBy()
// Parameters:  str1 - string 1 (left operand)
//              str2 - string 2 (right operand)
//              op - operator type
// Action:      Convert strings to new data type based on m_nCompareAs'
//              value. Compare the strings using the operator.
// Returns:     The result of (str1 op str2)
//////////////////////////////////////////////////////////////////////
BOOL CMyListCtrl::CompareBy(CString str1, CString str2, ListOperatorType  op)
{
    BOOL bReturn = FALSE;    
	switch (m_nCompareAs)   
	{
        case ELCT_INTEGER:       
			{           
				int val1 = atoi(str1);
	            int val2 = atoi(str2);           
				if (op == ELOT_LT)
					bReturn =  (val1 < val2);   
				else if (op == ELOT_GT)
					bReturn =  (val1 > val2);     
				else if (op == ELOT_LTE)
	                bReturn =  (val1 <= val2);      
				else if (op == ELOT_GTE)
					bReturn =  (val1 >= val2);   
				else
				    bReturn =  (val1 == val2);    
				break;        
			}
        case ELCT_DOUBLE:       
			{            
				double val1 = atof(str1);
				double val2 = atof(str2);     
				if (op == ELOT_LT)
			        bReturn =  (val1 < val2);    
				else if (op == ELOT_GT)
		            bReturn =  (val1 > val2);       
				else if (op == ELOT_LTE)
	                bReturn =  (val1 <= val2);    
				else if (op == ELOT_GTE)
					bReturn =  (val1 >= val2);    
				else
				    bReturn =  (val1 == val2);    
				break; 
			}
        case ELCT_DATETIME:       
			{           
				COleDateTime val1 = ParseDateTime(str1);
	            COleDateTime val2 = ParseDateTime(str2);           
				if (op == ELOT_LT)
					bReturn =  (val1 < val2);   
				else if (op == ELOT_GT)
					bReturn =  (val1 > val2);     
				else if (op == ELOT_LTE)
	                bReturn =  (val1 <= val2);      
				else if (op == ELOT_GTE)
					bReturn =  (val1 >= val2);   
				else
				    bReturn =  (val1 == val2);    
				break;        
			}
        case ELCT_STRING_NOCASE:      
			{            
				str1.MakeUpper();
				str2.MakeUpper();    
			}    
		case ELCT_STRING_CASE:
        default:      
			{   
				if (op == ELOT_LT)
					bReturn =  (str1 < str2);    
				else if (op == ELOT_GT)
				    bReturn =  (str1 > str2);       
				else if (op == ELOT_LTE)
			        bReturn =  (str1 <= str2);       
				else if (op == ELOT_GTE)
		            bReturn =  (str1 >= str2);    
				else
	                bReturn =  (str1 == str2);       
				break;        
			}  
	}
    return bReturn;
}

//////////////////////////////////////////////////////////////////////
// GetColumnCount()
// Parameters:  None.// Action:
// Returns:     The number of columns in the list control
//////////////////////////////////////////////////////////////////////
int CMyListCtrl::GetColumnCount() const
{
    //Get the header control
    CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
    //Return the number of items in it (i.e. the number of columns)
    return pHeader->GetItemCount();
}

//////////////////////////////////////////////////////////////////////
// SwapRow()
// Parameters:  nRow1 - row index (zero based)
//              nRow2 - row index (zero based)
// Action:      Swap nRow1 with nRow2
// Returns:     TRUE if successful, else FALSE
//////////////////////////////////////////////////////////////////////
BOOL CMyListCtrl::SwapRow(int nRow1, int nRow2)
{ 
	BOOL bOk = FALSE;      
	int nStart = 0;
	if( !m_bSortFirstCol )
		nStart = 1;
		
    int nMaxRows = GetItemCount();    

	if ((nRow1 >= 0) && (nRow1 < nMaxRows) &&
        (nRow2 >= 0) && (nRow2 < nMaxRows) && 
		(nRow1 != nRow2))    
	{
        int nMaxColumns = GetColumnCount();        //swap rows
        LV_ITEM lvItem1, lvItem2;        //hold all text for a single row
        CStringArray rowText;    
		rowText.SetSize(nMaxColumns);
        //save all the text in row      
		for(int i = nStart; i < nMaxColumns; i++)
        {   
			rowText[i] = GetItemText(nRow1, i);        
		}
        //setup parameters to get item data
        lvItem1.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
        lvItem1.iItem = nRow1;        lvItem1.iSubItem = 0;
        lvItem1.stateMask = LVIS_CUT | LVIS_DROPHILITED |
                            LVIS_FOCUSED | LVIS_SELECTED |
                            LVIS_OVERLAYMASK | LVIS_STATEIMAGEMASK;
        lvItem2 = lvItem1;    
		lvItem2.iItem = nRow2;  
		//get item data
        GetItem(&lvItem1);    
		GetItem(&lvItem2);
        //set the text for the lo (left)    
		for(i = nStart; i < nMaxColumns; i++)
        {  
			SetItemText(nRow1, i, GetItemText(nRow2, i));        
		}
		lvItem2.iItem = nRow1;    
		SetItem(&lvItem2);

		for(i = nStart; i < nMaxColumns; i++)    
		{
			SetItemText(nRow2, i, rowText[i]);  
		}
		lvItem1.iItem = nRow2;     
		SetItem(&lvItem1);   

		CString key1;
		key1.Format("%d",nRow1);
		CString key2;
		key2.Format("%d",nRow2);

	}   
	return bOk;
}

//////////////////////////////////////////////////////////////////////
// ParseDateTime()
// Parameters:  lpszDate - date time string
// Action:      get date time from string
// Returns:     COleDateTime 
//////////////////////////////////////////////////////////////////////
COleDateTime CMyListCtrl::ParseDateTime(LPCTSTR lpszDate)
{
	COleDateTime odtVal;// = COleDateTime::GetCurrentTime();
	CString strDate;
	strDate.Format("%s",lpszDate);
	int nYear,nMon,nDay;
	int nHour=0,nMin=0,nSec=0;

	if( !odtVal.ParseDateTime(lpszDate) )
	{
		switch(m_nDateTimeType)
		{
		case 0:
		default:
			if( strchr(lpszDate,' ') != NULL )
				sscanf(lpszDate,"%4d%2d%2d %2d:%2d:%2d",
					&nYear,&nMon,&nDay,&nHour,&nMin,&nSec);
			else
				sscanf(lpszDate,"%4d%2d%2d",
					&nYear,&nMon,&nDay);
			break;
		case 1:
			if( strchr(lpszDate,' ') != NULL )
				sscanf(lpszDate,"%4d/%d/%d %2d:%2d:%2d",
					&nYear,&nMon,&nDay,&nHour,&nMin,&nSec);
			else
				sscanf(lpszDate,"%4d/%d/%d",
					&nYear,&nMon,&nDay);
			break;
		case 2:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -