// ------------------------------------------------------------------------------------------------------------------------
//	Zip Studio 3.0 - Developer Edition
//	DllDemo sample for Microsoft Visual C++ 4.0
//
//	Copyright Hexanet 1993-1996, All rights reserved
// ------------------------------------------------------------------------------------------------------------------------
//	Note:
//	This sample uses the DLL version of the API (ZSAPI32.DLL).
//	This DLL must be on the path of this appication.
// ------------------------------------------------------------------------------------------------------------------------
#include "stdafx.h"
#include "DllDemo.h"
#include "MainFrm.h"
#include "DllDDoc.h"
#include "DLLDView.h"
#include "UZBox.h"
#include "ZipBox.h"

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


// ----------------------------------------------------
//	AfxGiveTheHand = DoEvents
//	under VB4
// ----------------------------------------------------
void AfxGiveTheHand( )
	{
	MSG msg;
	while ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE) )
		{
		TranslateMessage( &msg );
		DispatchMessage( &msg );
		}
	}


/////////////////////////////////////////////////////////////////////////////
// CDllDemoView

IMPLEMENT_DYNCREATE(CDllDemoView, CFormView)

BEGIN_MESSAGE_MAP(CDllDemoView, CFormView)
	//{{AFX_MSG_MAP(CDllDemoView)
	ON_WM_SIZE()
	ON_WM_DESTROY()
	ON_NOTIFY(LVN_GETDISPINFO, IDC_MYLIST, OnGetdispinfoMylist)
	ON_NOTIFY(LVN_COLUMNCLICK, IDC_MYLIST, OnColumnclickMylist)
	ON_NOTIFY(NM_DBLCLK, IDC_MYLIST, OnDblclkMylist)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDllDemoView construction/destruction

CDllDemoView::CDllDemoView()
	: CFormView(CDllDemoView::IDD)
{
	//{{AFX_DATA_INIT(CDllDemoView)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// TODO: add construction code here

}

CDllDemoView::~CDllDemoView()
{
}

void CDllDemoView::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDllDemoView)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BOOL CDllDemoView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CFormView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CDllDemoView diagnostics

#ifdef _DEBUG
void CDllDemoView::AssertValid() const
{
	CFormView::AssertValid();
}

void CDllDemoView::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}

CDllDemoDoc* CDllDemoView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDllDemoDoc)));
	return (CDllDemoDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDllDemoView message handlers
BOOL bLoaded = FALSE;


// Set the ListView attributes
void CDllDemoView::OnInitialUpdate() 
	{
	CFormView::OnInitialUpdate();
	UpdateData( FALSE );
	// 1 - Set the images list ---------
	if ( !bLoaded )
		{
		ZSInitialize( 0L, _T(""), _T(""), (long)m_hWnd );
		AfxGetApp()->BeginWaitCursor();
		//	Call this function to build the Zip Studio HIMAGELIST handles.
		//	You must not call this function twice. Once the program terminate
		//	we use <DestroyZIPITEMImageList> (see <OnDestroy> below)
		ZSBuildZIPITEMImageList();
		AfxGetApp()->EndWaitCursor();
		bLoaded = TRUE;
		}
	
	//	Now we must set the ImageList for our ListView control.
	//	Our ListView control will automatically use these icons list and we won' t
	//	to paint anything by ourselves
	//	There are 2 ImageList: The first one for big icons ( <GetZIPITEMHImageList>( TRUE ) )
	//	and the next one for the small icons ( <GetZIPITEMHImageList>( FALSE ) )
	

	((CListCtrl*)GetDlgItem(IDC_MYLIST))->SetImageList( CImageList::FromHandle( (HIMAGELIST)(ZSGetZIPITEMHImageList( TRUE ))), LVSIL_NORMAL );
	((CListCtrl*)GetDlgItem(IDC_MYLIST))->SetImageList( CImageList::FromHandle( (HIMAGELIST)ZSGetZIPITEMHImageList( FALSE )), LVSIL_SMALL );
	
	
	// 2 - Add columns for the REPORT mode -----------
	LV_COLUMN lvc; 
    
	// Initialize the LV_COLUMN structure. 
    lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; 
    
	lvc.fmt = LVCFMT_LEFT; 
    lvc.cx = 200; 
    lvc.pszText = _T("File"); 
 	lvc.iSubItem = 0; 
   if ((int)((CListCtrl*)GetDlgItem(IDC_MYLIST))->SendMessage( LVM_INSERTCOLUMN, (WPARAM)(int)(0), (LPARAM)(const LV_COLUMN FAR*)(&lvc)) == -1 )
        return; 
   
	lvc.fmt = LVCFMT_RIGHT; 
    lvc.cx = 100; 
    lvc.pszText = _T("Size"); 
 	lvc.iSubItem = 1; 
   if ((int)((CListCtrl*)GetDlgItem(IDC_MYLIST))->SendMessage( LVM_INSERTCOLUMN, (WPARAM)(int)(1), (LPARAM)(const LV_COLUMN FAR*)(&lvc)) == -1 )
        return; 
   
	lvc.fmt = LVCFMT_LEFT; 
    lvc.cx = 150; 
    lvc.pszText = _T("Directory"); 
 	lvc.iSubItem = 2; 
    if ((int)((CListCtrl*)GetDlgItem(IDC_MYLIST))->SendMessage( LVM_INSERTCOLUMN, (WPARAM)(int)(2), (LPARAM)(const LV_COLUMN FAR*)(&lvc)) == -1 )
	     return; 
   	
	((CListCtrl*)GetDlgItem(IDC_MYLIST))->SetBkColor( ::GetSysColor( COLOR_WINDOW) );
	((CListCtrl*)GetDlgItem(IDC_MYLIST))->SetTextBkColor( ::GetSysColor( COLOR_WINDOW) );

}


// Resize the main ListView control according to the main window
void CDllDemoView::OnSize(UINT nType, int cx, int cy) 
{
	CFormView::OnSize(nType, cx, cy);
	if ( GetDlgItem( IDC_MYLIST) )
		{
		CRect r;
		GetClientRect( r );
  		HDWP h = ::BeginDeferWindowPos(2);
  		GetDlgItem( IDC_MYLIST )->MoveWindow(  r.left, r.top, r.right-r.left, r.bottom-r.top, TRUE );
		::EndDeferWindowPos(h);
		}
}

// We receive this message when we close the program.
//	We must delete the ListView items (and free the corresponding memory)
//	and delete the Zip Studio ImageLists.
void CDllDemoView::OnDestroy() 
{
//	This function will destroy all the items we have in the current ListView.
//	The items are ZIPITEMs and we stored them as the LPARAM values of our List.
ZSDestroyZIPITEMLParam( (short)GetDlgItem(IDC_MYLIST)->m_hWnd);
//	Remove the HLISTIMAGEs of Zip Studio DLL
ZSDestroyZIPITEMImageList(  );
// Remove temp. directories (for <View> and <BuildZIPITEMList>)
ZSDeleteTempDirectories();

CFormView::OnDestroy();
}


//	We will receive this message each time the ListView control needs to repaint
//	an item.
//	As we use Visual C++ we can directly access the ZIPITEM value of the item by
//	casting the LPARAM value of the ListView (ZIPITEM* z = (ZIPITEM*)lParam )
//	Otherwise we have to call the Zip Studio <GetZIPITEM...> method to
//	retrieve this value.
//	We put the value to 'pDispInfo->item.pszText' as described in the SDK doc.
//	'pDispInfo->item.iSubItem' corresponds to the column index we are updating
//
void CDllDemoView::OnGetdispinfoMylist(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
	CString sTemp(' ', 128);

	// TODO: Add your control notification handler code here
   if (pDispInfo->item.mask & LVIF_TEXT) 
		{ 
        if ( pDispInfo->item.lParam )
			{
		ZIPITEM *pItem = (ZIPITEM *) (pDispInfo->item.lParam); 
        if ( pDispInfo->item.iSubItem == 0 )
			{
			if ( pItem->bIsDir ) 
				lstrcpy(pDispInfo->item.pszText, pItem->szDir );
			else
				lstrcpy(pDispInfo->item.pszText, pItem->szName );
			pDispInfo->item.mask = pDispInfo->item.mask | LVIF_DI_SETITEM;
			}
		else if ( pDispInfo->item.iSubItem == 1  )
			{
			if ( !(pItem->bIsDir) )
				{
				sTemp.Format( _T("%ld"), (long)( pItem->lOriginalSize) );
				lstrcpy(pDispInfo->item.pszText, (LPCTSTR)sTemp );
				}
			}
		else if (  pDispInfo->item.iSubItem == 2 ) 
			{
			if ( !(pItem->bIsDir) )
				lstrcpy(pDispInfo->item.pszText, pItem->szDir );
			}
		if ( pDispInfo->item.pszText )
			{
			OemToChar( pDispInfo->item.pszText, pDispInfo->item.pszText);
			CharLower( pDispInfo->item.pszText );
			}
			}
		} 

	
	*pResult = 0;
}

// ListViewCompareFunc - sorts the list view control. It is a 
//     comparison function. 
// Returns a negative value if the first item should precede the 
//     second item, a positive value if the first item should 
//     follow the second item, and zero if the items are equivalent. 
// lParam1 and lParam2 - item data for the two items (in this 
//     case, pointers to application-defined MYITEM structures) 
// lParamSort - value specified by the LVM_SORTITEMS message 
//     (in this case, the index of the column to sort) 
int CALLBACK ListViewCompareFunc(  LPARAM lParam1, LPARAM lParam2,  LPARAM lParamSort) 
	{ 
    ZIPITEM *pItem1 = (ZIPITEM *) lParam1; 
    ZIPITEM *pItem2 = (ZIPITEM *) lParam2; 
 	int iResult;
	CString sItem1, sItem2;
	
	switch ( (int)lParamSort )	// The column
		{
		case 0: iResult = lstrcmp( (pItem1->szName != _T("")) ? pItem1->szName : pItem1->szDir,
												  (pItem2->szName != _T("")) ? pItem2->szName : pItem2->szDir ); break;
		case 1: if ( pItem1->lOriginalSize < pItem2->lOriginalSize )
						iResult =  -1;
					else if ( pItem1->lOriginalSize > pItem2->lOriginalSize )
						iResult =  1;
					else
						iResult = 0;
					break;
		default: sItem1 = ( strcmp( pItem1->szDir, _T("")) )? pItem1->szDir : _T(":");
					 sItem1 = sItem1 + pItem1->szName;
					 sItem2 = ( strcmp( pItem2->szDir, _T("")) )? pItem2->szDir : _T(":");
					 sItem2 = sItem2 + pItem2->szName;
					 iResult = lstrcmp( sItem1, sItem2 ); break;
		}
	return iResult;
} 


void CDllDemoView::OnColumnclickMylist(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	((CListCtrl*)GetDlgItem( IDC_MYLIST ))->SortItems( ListViewCompareFunc, (LPARAM) (pNMListView->iSubItem) ); 
	
	*pResult = 0;
}

void CDllDemoView::OnDblclkMylist(NMHDR* pNMHDR, LRESULT* pResult) 
{
	MessageBox( "Not implemented!");
	
	*pResult = 0;
}


