/*----------------------------------------------------------------------
Copyright (C)2001 MJSoft. All Rights Reserved.
          This source may be used freely as long as it is not sold for
					profit and this copyright information is not altered or removed.
					Visit the web-site at www.mjsoft.co.uk
					e-mail comments to info@mjsoft.co.uk
File:     SortListCtrl.cpp
Purpose:  Provides a sortable list control, it will sort text, numbers
          and dates, ascending or descending, and will even draw the
					arrows just like windows explorer!
----------------------------------------------------------------------*/

#include "stdafx.h"
#include "PListCtrl.h"
#include "resource.h"

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

LPCTSTR g_pszSection = _T("ListCtrls");

PListCtrl::PListCtrl()
	: m_iNumColumns( 0 )
	, m_iSortColumn( -1 )
	, m_bSortAscending( TRUE )
{
	m_pMyTabWnd = NULL;
	m_pWnd = NULL;
}

PListCtrl::~PListCtrl()
{
}

BEGIN_MESSAGE_MAP(PListCtrl, CListCtrl)
	//{{AFX_MSG_MAP(PListCtrl)
	ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick)
	ON_WM_DESTROY()
	ON_WM_CREATE()
	ON_WM_RBUTTONDOWN()
	ON_WM_LBUTTONDOWN()
	ON_WM_KEYUP()
	ON_WM_KEYDOWN()
	// ON_COMMAND(ID_ALARM_MANAGEMENT, OnAlarmManagement)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// PListCtrl message handlers
void PListCtrl::OnRButtonDown( UINT nFlags, CPoint point )
{
	CListCtrl::OnRButtonDown(nFlags, point);
	if( m_pMyTabWnd )
	{
		m_pMyTabWnd->GetParent()->SendMessage( WM_RBUTTON_DOWN , (unsigned long)this , 0 );
		// if( this == m_pParentWnd->GetChild() )
	}
	if( NULL != m_pWnd )
	{
		m_pWnd->SendMessage( WM_RBUTTON_DOWN , 0 , 0 );
		// if( this == m_pParentWnd->GetChild() )
	}
}

void PListCtrl::OnLButtonDown( UINT nFlags, CPoint point )
{
	CListCtrl::OnLButtonDown(nFlags, point);
	if( NULL != m_pWnd )
	{
		m_pWnd->SendMessage( WM_LBUTTON_DOWN , 0 , 0 );
		// if( this == m_pParentWnd->GetChild() )
	}
}

void PListCtrl::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{	
	CListCtrl::OnKeyUp(nChar, nRepCnt, nFlags);
	if( NULL != m_pWnd )
	{
		m_pWnd->SendMessage( WM_LISTCTRL_KEYUP , 0 , 0 );
	}
}

void PListCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{	
	CListCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
	if( NULL != m_pWnd )
	{
		m_pWnd->SendMessage( WM_LISTCTRL_KEYDOWN , 0 , 0 );
	}
}

void PListCtrl::PreSubclassWindow()
{
	// the list control must have the report style.
	ASSERT( GetStyle() & LVS_REPORT );
	if( GetHeaderCtrl()->GetSafeHwnd() )
	{
		VERIFY( m_ctlHeader.SubclassWindow( GetHeaderCtrl()->GetSafeHwnd() ) );
	}
	CListCtrl::PreSubclassWindow();
}

int PListCtrl::GetSortColumn()
{
	return m_iSortColumn;
}

int PListCtrl::GetSortAscending()
{
	return m_bSortAscending;
}

void PListCtrl::SetTabWnd( CWnd* pMyTabWnd )
{
	m_pMyTabWnd = pMyTabWnd;
}

void PListCtrl::SetWnd( CWnd* pWnd )
{
	m_pWnd = pWnd;
}


BOOL PListCtrl::SetHeadings( UINT uiStringID )
{
	CString strHeadings;
	VERIFY( strHeadings.LoadString( uiStringID ) );
	return SetHeadings( strHeadings );
}

// the heading text is in the format column 1 text,column 1 width;column 2 text,column 3 width;etc.
BOOL PListCtrl::SetHeadings( const CString& strHeadings )
{
	int iStart = 0;

	for( ;; )
	{
		const int iComma = strHeadings.Find( _T(','), iStart );

		if( iComma == -1 )
			break;

		const CString strHeading = strHeadings.Mid( iStart, iComma - iStart );

		iStart = iComma + 1;

		int iSemiColon = strHeadings.Find( _T(';'), iStart );

		if( iSemiColon == -1 )
			iSemiColon = strHeadings.GetLength();

		const int iWidth = atoi( strHeadings.Mid( iStart, iSemiColon - iStart ) );
		
		iStart = iSemiColon + 1;

		// update 0530
		if( CListCtrl::InsertColumn( m_iNumColumns++, strHeading, LVCFMT_LEFT, iWidth ) == -1 )
			return FALSE;
	}

	return TRUE;
}

int PListCtrl::AddItem( LPCTSTR pszText, ... )
{
	// update 0530
	const int iIndex = CListCtrl::InsertItem( GetItemCount(), pszText );

	LPTSTR* arrpsz = new LPTSTR[ m_iNumColumns ];
	arrpsz[ 0 ] = new TCHAR[ lstrlen( pszText ) + 1 ];
	(void)lstrcpy( arrpsz[ 0 ], pszText );

 	va_list list;
	va_start( list, pszText );

	for( int iColumn = 1; iColumn < m_iNumColumns; iColumn++ )
	{
		pszText = va_arg( list, LPCTSTR );
		ASSERT_VALID_STRING( pszText );
		VERIFY( CListCtrl::SetItem( iIndex, iColumn, LVIF_TEXT, pszText, 0, 0, 0, 0 ) );

		arrpsz[ iColumn ] = new TCHAR[ lstrlen( pszText ) + 1 ];
		(void)lstrcpy( arrpsz[ iColumn ], pszText );
	}

	va_end( list );

	VERIFY( SetTextArray( iIndex, arrpsz ) );

	return iIndex;
}

void PListCtrl::FreeItemMemory( const int iItem )
{
	ItemData* pid = reinterpret_cast<ItemData*>( CListCtrl::GetItemData( iItem ) );

	LPTSTR* arrpsz = pid->arrpsz;

	for( int i = 0; i < m_iNumColumns; i++ )
		delete [] arrpsz[ i ];

	delete [] arrpsz;
	// 추가
	// TRACE( "해제 : %08X\n"  , pid );
	delete pid;

	VERIFY( CListCtrl::SetItemData( iItem, NULL ) );
}

BOOL PListCtrl::DeleteItem( int iItem )
{
	PData* pData = ( PData* )this->GetItemData( iItem );
	if( pData != NULL )
	{
		if( pData->m_nType == DATA_TYPE_STRING )
		{
			PStringData* p = ( PStringData* )pData;
			delete p;
		}
		else if( pData->m_nType == DATA_TYPE_DICTIONARY )
		{
			PDicData* p = ( PDicData* )pData;
			delete p;
		}
	}
	
	FreeItemMemory( iItem );
	
	return CListCtrl::DeleteItem( iItem );
}

BOOL PListCtrl::DeleteAllItems()
{
	TRACE( "InDeleteItem\n" );
	for( int iItem = 0; iItem < GetItemCount(); iItem ++ )
	{
		PData* pData = ( PData* )this->GetItemData( iItem );
		if( pData != NULL )
		{
			if( pData->m_nType == DATA_TYPE_STRING )
			{
				PStringData* p = ( PStringData* )pData;
				delete p;
			}
			else if( pData->m_nType == DATA_TYPE_DICTIONARY )
			{
				PDicData* p = ( PDicData* )pData;
				delete p;
			}
		}

		FreeItemMemory( iItem );
	}

	return CListCtrl::DeleteAllItems();
}

bool IsNumber( LPCTSTR pszText )
{
	ASSERT_VALID_STRING( pszText );

	for( int i = 0; i < lstrlen( pszText ); i++ )
		if( !_istdigit( pszText[ i ] ) )
			return false;

	return true;
}

int NumberCompare( LPCTSTR pszNumber1, LPCTSTR pszNumber2 )
{
	ASSERT_VALID_STRING( pszNumber1 );
	ASSERT_VALID_STRING( pszNumber2 );

	const int iNumber1 = atoi( pszNumber1 );
	const int iNumber2 = atoi( pszNumber2 );

	if( iNumber1 < iNumber2 )
		return -1;
	
	if( iNumber1 > iNumber2 )
		return 1;

	return 0;
}

bool IsDate( LPCTSTR pszText )
{
	ASSERT_VALID_STRING( pszText );

	// format should be 99/99/9999.

	if( lstrlen( pszText ) != 10 )
		return false;

	return _istdigit( pszText[ 0 ] )
		&& _istdigit( pszText[ 1 ] )
		&& pszText[ 2 ] == _T('/')
		&& _istdigit( pszText[ 3 ] )
		&& _istdigit( pszText[ 4 ] )
		&& pszText[ 5 ] == _T('/')
		&& _istdigit( pszText[ 6 ] )
		&& _istdigit( pszText[ 7 ] )
		&& _istdigit( pszText[ 8 ] )
		&& _istdigit( pszText[ 9 ] );
}

int DateCompare( const CString& strDate1, const CString& strDate2 )
{
	const int iYear1 = atoi( strDate1.Mid( 6, 4 ) );
	const int iYear2 = atoi( strDate2.Mid( 6, 4 ) );

	if( iYear1 < iYear2 )
		return -1;

	if( iYear1 > iYear2 )
		return 1;

	const int iMonth1 = atoi( strDate1.Mid( 3, 2 ) );
	const int iMonth2 = atoi( strDate2.Mid( 3, 2 ) );

	if( iMonth1 < iMonth2 )
		return -1;

	if( iMonth1 > iMonth2 )
		return 1;

	const int iDay1 = atoi( strDate1.Mid( 0, 2 ) );
	const int iDay2 = atoi( strDate2.Mid( 0, 2 ) );

	if( iDay1 < iDay2 )
		return -1;

	if( iDay1 > iDay2 )
		return 1;

	return 0;
}

BOOL IsEqualStirngAndDifferentDigit( const CString& strLString , const CString& strRString , int *nIndex )
{
	TCHAR lChar;
	TCHAR rChar;

	int nLLastCharIndex = -1;
	int nRLastCharIndex = -1;

	int nLStringLength = strLString.GetLength();
	int nRStringLength = strRString.GetLength();

	for( int i = nLStringLength - 1 ; i >= 0 ; i-- )
	{
		lChar = strLString.GetAt( i );
		if( _istdigit( lChar ) )
		{
			continue;
		}
		else
		{
			nLLastCharIndex = i;
			break;
		}
	}
	
	for( i = nRStringLength - 1 ; i >= 0 ; i-- )
	{
		rChar = strRString.GetAt( i );
		if( _istdigit( rChar ) )
		{
			continue;
		}
		else
		{
			nRLastCharIndex = i;
			break;
		}
	}

	if( nLLastCharIndex != nRLastCharIndex || nLLastCharIndex == -1 || nRLastCharIndex == -1 )
	{
		return FALSE;
	}
	else
	{
		*nIndex = nRLastCharIndex + 1;

		if( *nIndex > nLStringLength - 1 || *nIndex > nRStringLength - 1 )
		{
			return FALSE;
		}

		for( i = nRLastCharIndex ; i >= 0 ; i-- )
		{
			lChar = strLString.GetAt( i );
			rChar = strRString.GetAt( i );

			if( _istdigit( lChar ) || _istdigit( rChar ) )
			{
				return FALSE;
			}

			if( lChar == rChar )
			{
				continue;
			}
			else
			{
				return FALSE;
			}
		}
	}

	return TRUE;
}

// 뒤에서 부터 찾으면 되~
/* BOOL IsEqualStirngAndDifferentDigit( const CString& strLString , const CString& strRString , int *nIndex )
{
	TCHAR lChar;
	TCHAR rChar;
	
	int nMaxCompareFreq = 0;
	int nLStringLen = strLString.GetLength();
	int nRStringLen = strRString.GetLength();

	nMaxCompareFreq = nLStringLen;
	if( nRStringLen > nLStringLen )
	{
		nMaxCompareFreq = nRStringLen;
	}

 	for( int i = 0 ; i < nMaxCompareFreq ; i++ )
	{
		if( nLStringLen <= i || nRStringLen <= i )
		{
			return FALSE;
		}

		lChar = strLString.GetAt( i );
		rChar = strRString.GetAt( i );

		if( _istdigit( lChar ) && _istdigit( rChar ) )
		{
			if( i == 0 )
			{
				return FALSE;
			}
			else
			{
				*nIndex = i;
				return TRUE;
			}
		}
		else
		{
			if( lChar == rChar )
			{
				continue;
			}
			else
			{
				return FALSE;
			}
		}
	}

	return FALSE;
} */

int StringAndDigitCompare( const CString& strLString , const CString& strRString , int nStartIndex )
{
	// TRACE( "%s , %s\n" , strRString.Mid( nStartIndex ) , strLString.Mid( nStartIndex ) ) ;
	int nLDigit = atoi( strLString.Mid( nStartIndex ) );
	int nRDigit = atoi( strRString.Mid( nStartIndex ) );

	if( nLDigit > nRDigit )
	{
		return -1;
	}
	else if( nLDigit < nRDigit )
	{
		return 1;
	}
	else
	{
		return 0;
	}

	return 0;
}

int CALLBACK PListCtrl::CompareFunction( LPARAM lParam1, LPARAM lParam2, LPARAM lParamData )
{
	PListCtrl* pListCtrl = reinterpret_cast<PListCtrl*>( lParamData );

	ASSERT( pListCtrl->IsKindOf( RUNTIME_CLASS( CListCtrl ) ) );

	int nStartDigitIndex = 0;

	ItemData* pid1 = reinterpret_cast<ItemData*>( lParam1 );
	ItemData* pid2 = reinterpret_cast<ItemData*>( lParam2 );

	ASSERT( pid1 );
	ASSERT( pid2 );

	LPCTSTR pszText1 = pid1->arrpsz[ pListCtrl->m_iSortColumn ];
	LPCTSTR pszText2 = pid2->arrpsz[ pListCtrl->m_iSortColumn ];

	ASSERT_VALID_STRING( pszText1 );
	ASSERT_VALID_STRING( pszText2 );

	//update code 0530
	/* if( IsNumber( pszText1 ) && IsNumber( pszText2 ) )
	{
		return pListCtrl->m_bSortAscending ? NumberCompare( pszText1, pszText2 ) : NumberCompare( pszText2, pszText1 );
	}
	else if( IsDate( pszText1 ) && IsDate( pszText2 ) )
	{
		return pListCtrl->m_bSortAscending ? DateCompare( pszText1, pszText2 ) : DateCompare( pszText2, pszText1 );
	} */
	// update 0531
	// else 
	if( IsEqualStirngAndDifferentDigit( pszText1 , pszText2 , &nStartDigitIndex ) )
	{
		// TRACE( "IsEqualStirngAndDifferentDigit\n" );
		return pListCtrl->m_bSortAscending ? StringAndDigitCompare( pszText1, pszText2 , nStartDigitIndex ) : 
		StringAndDigitCompare( pszText2, pszText1 , nStartDigitIndex );
	}
	else
	{
		return pListCtrl->m_bSortAscending ? lstrcmp( pszText1, pszText2 ) : lstrcmp( pszText2, pszText1 );
	}

	/* 길이를 기준으로~ 정렬 확임 됨
	int nRet = 0;
	int nLength1 = strlen ( pszText1 );
	int nLength2 = strlen ( pszText2 );
	if ( nLength1 > nLength2 )
	{
		nRet = 1;
	}
	else if ( nLength1 < nLength2 )
	{
		nRet = -1;
	}
	else
	{
		nRet = strcmp ( pszText1 , pszText2 );
	}
	
	if ( pListCtrl->m_bSortAscending )
	{
		nRet *= -1;
	}
	
	return nRet; 
	*/
}

void PListCtrl::OnColumnClick( NMHDR* pNMHDR, LRESULT* pResult )
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	const int iColumn = pNMListView->iSubItem;

	// if it's a second click on the same column then reverse the sort order,
	// otherwise sort the new column in ascending order.
	Sort( iColumn, iColumn == m_iSortColumn ? !m_bSortAscending : TRUE );

	*pResult = 0;
}

void PListCtrl::Sort( int iColumn, BOOL bAscending )
{
	m_iSortColumn = iColumn;
	m_bSortAscending = bAscending;

	// show the appropriate arrow in the header control.
	m_ctlHeader.SetSortArrow( m_iSortColumn, m_bSortAscending );

	VERIFY( SortItems( CompareFunction, reinterpret_cast<DWORD>( this ) ) );
}

void PListCtrl::LoadColumnInfo()
{
	// you must call this after setting the column headings.
	ASSERT( m_iNumColumns > 0 );

	CString strKey;
	strKey.Format( _T("%d"), GetDlgCtrlID() );

	UINT nBytes = 0;
	BYTE* buf = NULL;
	if( AfxGetApp()->GetProfileBinary( g_pszSection, strKey, &buf, &nBytes ) )
	{
		if( nBytes > 0 )
		{
			CMemFile memFile( buf, nBytes );
			CArchive ar( &memFile, CArchive::load );
			m_ctlHeader.Serialize( ar );
			ar.Close();

			m_ctlHeader.Invalidate();
		}

		delete[] buf;
	}
}

void PListCtrl::SaveColumnInfo()
{
	ASSERT( m_iNumColumns > 0 );

	CString strKey;
	strKey.Format( _T("%d"), GetDlgCtrlID() );

	CMemFile memFile;

	CArchive ar( &memFile, CArchive::store );
	m_ctlHeader.Serialize( ar );
	ar.Close();

	DWORD dwLen = memFile.GetLength();
	BYTE* buf = memFile.Detach();	

	VERIFY( AfxGetApp()->WriteProfileBinary( g_pszSection, strKey, buf, dwLen ) );

	free( buf );
}

void PListCtrl::OnDestroy()
{
	DeleteAllItems();
	/*
	for( int iItem = 0; iItem < GetItemCount(); iItem ++ )
	{
		PData* pData = ( PData* )this->GetItemData( iItem );
		if( pData != NULL )
		{
			if( pData->m_nType == DATA_TYPE_STRING )
			{
				PStringData* p = ( PStringData* )pData;
				delete p;
			}
			else if( pData->m_nType == DATA_TYPE_STRING )
			{
				PDicData* p = ( PDicData* )pData;
				delete p;
			}
		}

		FreeItemMemory( iItem );
	}
	*/
	
	CListCtrl::OnDestroy();
}

int PListCtrl::InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int Format, int nWidth )
{
	if ( nCol >= m_iNumColumns )
	{
		m_iNumColumns = nCol + 1;
	}

	return CListCtrl::InsertColumn( nCol, lpszColumnHeading, Format, nWidth );
}

int PListCtrl::InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int Format, int nWidth, int nSubItem )
{
	if (nCol >= m_iNumColumns )
	{
		m_iNumColumns = nCol + 1;
	}

	return CListCtrl::InsertColumn( nCol, lpszColumnHeading, Format, nWidth, nSubItem );
}

int PListCtrl::InsertColumn( int nCol, const LVCOLUMN* pColumn )
{
	if (nCol >= m_iNumColumns )
	{
		m_iNumColumns = nCol + 1;
	}

	return CListCtrl::InsertColumn( nCol, pColumn );
}

int PListCtrl::InsertItem( int nItem, LPCTSTR lpszItem )
{
	// 실제로 Insert 한 행의 Index를 넘겨 줌.
	const int iIndex = CListCtrl::InsertItem( nItem, lpszItem );
	
	LPTSTR* arrpsz = new LPTSTR[ m_iNumColumns ];
	arrpsz[ 0 ] = new TCHAR[ lstrlen( lpszItem ) + 1 ];
	(void)lstrcpy( arrpsz[ 0 ], lpszItem );
	
	va_list list;
	va_start( list, lpszItem );
	
	for( int iColumn = 1; iColumn < m_iNumColumns; iColumn++ ) 
	{
		//lpszItem = va_arg( list , LPCTSTR );
		ASSERT_VALID_STRING( lpszItem );
		VERIFY( CListCtrl::SetItem( iIndex, iColumn, LVIF_TEXT, lpszItem, 0, 0, 0, 0 ) );
		
		arrpsz[ iColumn ] = new TCHAR[ lstrlen( lpszItem ) + 1 ];
		(void)lstrcpy( arrpsz[ iColumn ], lpszItem );
	}
	
	va_end( list );
	
	VERIFY( SetTextArray( iIndex, arrpsz ) );
	
	return iIndex;
}

int PListCtrl::InsertItem( int index, LPCTSTR pszText, int image )
{
	const int iIndex = CListCtrl::InsertItem( index, pszText, image );
	
	LPTSTR* arrpsz = new LPTSTR[ m_iNumColumns ];
	arrpsz[ 0 ] = new TCHAR[ lstrlen( pszText ) + 1 ];
	(void)lstrcpy( arrpsz[ 0 ], pszText );
	
	for (int i = 1; i < m_iNumColumns; ++i)
		arrpsz[ i ] = 0;
	
	VERIFY( SetTextArray( iIndex, arrpsz ) );
	
	return iIndex;
}


BOOL PListCtrl::SetItemText( int nItem, int nSubItem, LPCTSTR lpszText )
{
	if( !CListCtrl::SetItemText( nItem, nSubItem, lpszText ) )
		return FALSE;

	LPTSTR* arrpsz = GetTextArray( nItem );
	LPTSTR pszText = arrpsz[ nSubItem ];
	delete[] pszText;
	pszText = new TCHAR[ lstrlen( lpszText ) + 1 ];
	(void)lstrcpy( pszText, lpszText );
	arrpsz[ nSubItem ] = pszText;

	return TRUE;
}

BOOL PListCtrl::SetItemData( int nItem, DWORD dwData )
{
	if( nItem >= GetItemCount() )
		return FALSE;

	ItemData* pid = reinterpret_cast<ItemData*>( CListCtrl::GetItemData( nItem ) );
	ASSERT( pid );
	pid->dwData = dwData;

	return TRUE;
}

DWORD PListCtrl::GetItemData( int nItem ) const
{
	ASSERT( nItem < GetItemCount() );

	ItemData* pid = reinterpret_cast<ItemData*>( CListCtrl::GetItemData( nItem ) );
	ASSERT( pid );
	return pid->dwData;
}

DWORD PListCtrl::GetItemlParamData( int nItem ) const
{
	ASSERT( nItem < GetItemCount() );

	ItemData* pid = reinterpret_cast<ItemData*>( CListCtrl::GetItemData( nItem ) );
	ASSERT( pid );
	
	return ( DWORD )pid;
}

BOOL PListCtrl::SetTextArray( int iItem, LPTSTR* arrpsz )
{
	ASSERT( CListCtrl::GetItemData( iItem ) == NULL );
	ItemData* pid = new ItemData;
	pid->arrpsz = arrpsz;
	return CListCtrl::SetItemData( iItem, reinterpret_cast<DWORD>( pid ) );
}

LPTSTR* PListCtrl::GetTextArray( int iItem ) const
{
	ASSERT( iItem < GetItemCount() );

	ItemData* pid = reinterpret_cast<ItemData*>( CListCtrl::GetItemData( iItem ) );
	return pid->arrpsz;
}

/* 
BOOL PListCtrl::Create( DWORD dwStyle , const RECT& rect , CWnd* pParentWnd , UINT nID )
{
	return CListCtrl::Create( dwStyle , rect , pParentWnd , nID );
} 
*/

int PListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CListCtrl::OnCreate(lpCreateStruct) == -1)
		return -1;

	VERIFY( m_ctlHeader.SubclassWindow( GetHeaderCtrl()->GetSafeHwnd() ) );
	
	return 0;
}

/* 
void PListCtrl::OnAlarmManagement() 
{
	CString strUserInfo;
	CString* pSensorId;
	CString strAlarmTime;

	int nIndex = 0;

	nIndex = this->GetNextItem( - 1 , LVNI_SELECTED );
	if( nIndex != -1 )
	{
		strAlarmTime = this->GetItemText( nIndex , 0 );
		strUserInfo = this->GetItemText( nIndex , 1 );
		pSensorId = ( CString* )this->GetItemData( nIndex );
	}
	else
	{
		MessageBox( "조치를 항목을 선택해 주세요." , "알람" , MB_ICONWARNING );
		return;
	}

	DlgAlarmManagement dlg( strUserInfo , *pSensorId , strAlarmTime );
	// DlgAlarmManagement dlg( "Sensor" , "Sensor" );
	if( dlg.DoModal() ==IDOK )
	{
		if( pSensorId )
		{
			delete pSensorId;
		}
		this->DeleteItem( nIndex );
	}
} 
*/