www.pudn.com > DlgScrSaver.rar > Collect.h


/////////////////////////////////////////////////////////////////////////////// 
//                                                                           // 
// Dateiname: COLLECT.H                                                      // 
//                                                                           // 
// Autor:     Andreas Jäger, Friedrich-Schiller-Universität Jena             // 
//                                                                           // 
// System:    WIN_RWPM.EXE und WINLRWPM.EXE                                  // 
//                                                                           // 
// Beschreibung: Kollektionen als Templates                                  // 
//                                                                           // 
// Hinweise:                                                                 // 
//                                                                           // 
/////////////////////////////////////////////////////////////////////////////// 
#include "resource.h" 
 
 
/////////////////////////////////////////////////////////////////////////////// 
// template-Klasse CCollection                                               // 
/////////////////////////////////////////////////////////////////////////////// 
/* 
Diese Klasse entspricht in ihrer Funktionalität dem bekannten PASCAL-Objekt, 
sie ist jedoch typensicherer, da nicht mit generischen, sondern mit T* - Zeigern 
gearbeitet wird. Außerdem ist die Zahl der Objekte in der Kollektion nahezu un- 
begrenzt (Indizierung mit long). 
Es können Objekte des Typs "T" oder "abgeleitet von T" gespeichert werden, 
wobei ein Zeiger auf ein Objekt vom Typ T entgegengenommen wird, der dann von 
der Kollektion verwaltet wird.  
Zusätzlich ist es möglich, mittels des mitgelieferten Dialogs CChooseCollDialog 
bzw. TNoHelpChooseCollDialog ein Item als selektiert zu markieren. 
Wird CChooseCollDialog verwendet, so muß das Objekt T eine (virtuelle) Help- 
Funktion bereitstellen. 
 
Sortierte Kollektionen müssen zusätzlich zur Help-Funktion eine 
Vegleichs-Funktion Compare bereitstellen. 
*/ 
template  
class CCollection : public CObject 
{ 
public: 
	// Konstruktor und Standard-Konstruktor 
	CCollection(const char* name = _T("CCollection"), long _limit = 2, long _delta = 50); 
 
	// Destruktor 
	virtual ~CCollection(); 
 
	// Lesender Zugriff auf count und delta 
	long Count() const                     {return count;}; 
	long CountNonZero() const; // Anzahl der gespeicherten Zeiger ohne Berücksichtigung der NULL-Zeiger 
	long Delta() const                     {return delta;}; 
	bool IsEmpty() const                   {return count == 0L;}; 
	void SetDelta(long _delta)             {delta = _delta;}; 
 
	// Zugriff auf Items 
	T* At(long index) const                {return ((index>=0L) && (index=0L) && (index0L) ? items[0L] : NULL;}; 
	T* Last() const                        {return (count>0L) ? items[count-1L] : NULL;}; 
 
	// Löschen von Items 
	virtual void AtFree(long index, bool discardmem = false); 
	virtual void FreeAll(bool discardmem = false); // true übergeben, um freigewordenen Speicher zu verwerfen 
 
protected: 
	// Speicher-Verwaltung 
	virtual T** Alloc_Mem(long _limit)     {T** _items = new T*[_limit]; ASSERT(_items); return _items;}; 
	virtual void ReleaseMem()              {delete[] items;}; 
	virtual void Resize(long _limit); // Anpassung des Speicherblocks, es werden keine Items eingefügt 
 
public: 
	// Einfügen von Items 
	virtual void AtInsert(T* t, long index); 
	virtual void Insert(T* t); 
 
	// Ersetzen von Items 
	virtual void AtPut(T* t, long index); 
	// Zeiger in der Kollektion durch NULL-Zeiger ersetzen, hilfreich, wenn 
	// das Objekt von außerhalb gelöscht wurde 
	virtual void SetNULL(long index)      {if (index>=0 && index& operator << (CCollection& dest, CCollection& source); 
 
	//virtual void Serialize(CArchive& ar); 
 
	// Datenfelder 
public: 
	CString Name; 
protected: 
	long count; // Anzahl der Elemente, die sich in der Collection befinden 
	long delta; // Inkrement, um das sich die Zahl der aufnehmbaren Elemente vergrößert oder verkleinert 
	long limit; // Anzahl der aufnehmbaren Elemente, ohne die Collection zu vergrößern 
	T** items;  // Zeiger auf Speicherblock 
 
	// Privater Kopier-Konstruktor und Zuweisungsoperator.  
	// Somit werden die vom Compiler automatisch generierten 
	// Funktionen verborgen, da diese nicht korrekt arbeiten. 
	// Kollektionen haben in dieser Version keine Kopier- 
	// Semantik. 
private: 
	CCollection(const CCollection& /*coll*/)  {}; 
	CCollection& operator = (const CCollection& /*coll*/) {return *this;}; 
}; 
 
template  
class CSortCollection : public CCollection 
{ 
public: 
	// Konstruktor 
	CSortCollection(const char* name = _T("CSortedCollection"), long _limit = 2L, long _delta = 50L) 
		: CCollection(name, _limit, _delta) 
	{ }; 
 
	// Vergleich von Items 
	virtual int Compare(T* t1, T* t2) const; 
 
	// Suche nach Items 
	long Search(T* t) const; 
	long BSearch(T* t) const; 
	 
	// Sortieren 
	virtual bool BubbleSort(); 
	virtual bool InsertionSort(); 
	virtual bool SelectionSort(); 
	virtual bool ShellSort(); 
	virtual bool QuickSort(long l = -1, long r = -1); 
	virtual bool MergeSort(long l = -1, long r = -1); 
 
	// Privater Kopier-Konstruktor und Zuweisungsoperator.  
	// Somit werden die vom Compiler automatisch generierten 
	// Funktionen verborgen, da diese nicht korrekt arbeiten. 
	// Kollektionen haben in dieser Version keine Kopier- 
	// Semantik. 
private: 
	CSortCollection(const CSortCollection& /*coll*/) {}; 
	CSortCollection& operator = (const CSortCollection& /*coll*/) {return *this;}; 
}; 
 
template  
class CSortedCollection : public CSortCollection 
{ 
public: 
	// Konstruktor 
	CSortedCollection(const char* name = _T("CSortedCollection"), long _limit = 2L, long _delta = 50L, bool _duplicates = false) 
		: CSortCollection(name, _limit, _delta), duplicates(_duplicates) 
	{ }; 
 
	virtual ~CSortedCollection()           {}; 
 
	// Duplikate 
	void SetDuplicates(bool _duplicates = false)  {duplicates = _duplicates;}; 
	bool Duplicates() const                {return duplicates;}; 
 
	// Einfügen von Items 
	virtual void Insert(T* t); 
 
protected: 
	bool duplicates; 
 
	// Privater Kopier-Konstruktor und Zuweisungsoperator.  
	// Somit werden die vom Compiler automatisch generierten 
	// Funktionen verborgen, da diese nicht korrekt arbeiten. 
	// Kollektionen haben in dieser Version keine Kopier- 
	// Semantik. 
private: 
	CSortedCollection(const CSortedCollection& /*coll*/) {}; 
	CSortedCollection& operator = (const CSortedCollection& /*coll*/) {return *this;}; 
}; 
 
// Template-Klasse CChooseCollection.  
template 
class CChooseCollection : public CCollection 
{ 
public: 
	// Konstruktor und Standard-Konstruktor 
	CChooseCollection(const char* name = _T("CChooseCollection"), long _limit = 2, long _delta = 50) 
		: CCollection(name, _limit, _delta), Selected(0) 
	{ 
	}; 
 
	// Destruktor 
	virtual ~CChooseCollection()      {}; 
 
	// Auswahl 
	long GetSelIndex() const          {return Selected;}; 
	CString GetSelName() const        {return *GetSelected();}; 
	void SetSelIndex(long _index); 
	void SetSelIndex(const char* _name); 
	T* GetSelected() const            {return At(Selected);}; 
	bool ChooseSelected(const char* dialogtitle = _T("Auswahl"), CWnd* parent = NULL); 
	long* MultiSelection(const char* dialogtitle = _T("Auswahl")); 
	long Find(const char* name) const; 
 
	//virtual void Serialize(CArchive& ar); 
 
protected: 
	long Selected; 
 
	// Privater Kopier-Konstruktor und Zuweisungsoperator.  
	// Somit werden die vom Compiler automatisch generierten 
	// Funktionen verborgen, da diese nicht korrekt arbeiten. 
	// Kollektionen haben in dieser Version keine Kopier- 
	// Semantik. 
private: 
	CChooseCollection(const CChooseCollection& /*coll*/) {}; 
	CChooseCollection& operator = (const CChooseCollection& /*coll*/) {return *this;}; 
}; 
 
template 
class CChooseCollDialog : public CDialog 
{ 
public: 
	//enum { IDD = IDD_CHOOSECOLLDIALOG1 }; 
	CChooseCollDialog(CChooseCollection& coll, LPCTSTR lpszTemplateName, CWnd* parent = NULL) : CDialog(lpszTemplateName, parent), Coll(coll), Selected(coll.GetSelIndex()) {}; 
	CChooseCollDialog(CChooseCollection& coll, CWnd* parent = NULL, UINT nIDTemplate = IDD_CHOOSECOLLDIALOG) : CDialog(nIDTemplate, parent), Coll(coll), Selected(coll.GetSelIndex()) {}; 
	virtual void DoDataExchange(CDataExchange* pDX); 
	virtual BOOL OnInitDialog(); 
	virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); 
 
	CListBox m_ctlListBox; 
	int Selected; 
	CChooseCollection& Coll; 
}; 
 
// ================== CCollection ============================================= 
 
template  
CCollection::CCollection(const char* name, long _limit, long _delta) : Name(name) 
{ 
	items = Alloc_Mem(_limit); 
	count = 0L; 
	delta = _delta; 
	limit = _limit; 
}; 
 
template  
CCollection::~CCollection() 
{ 
	for (long i=0L; i 
void CCollection::Resize(long _limit) 
{ 
	if (_limit == limit) return; // nichts zu tun 
 
	// temporäres Feld erzeugen 
	T** tempitems = Alloc_Mem(_limit); 
	// Kopieren 
	memcpy(tempitems, items, min(limit, _limit)*sizeof(T*)); 
	// Altes Feld freigeben 
	ReleaseMem(); 
	limit = _limit; 
	items = tempitems; 
}; 
 
template  
void CCollection::Insert(T* t) 
{ 
	if (count == limit) 
	{ 
		Resize(limit + delta); 
	} 
	items[count++] = t; 
}; 
 
template  
void CCollection::FreeAll(bool discardmem) // true übergeben, um freigewordenen Speicher zu verwerfen 
{ 
	for (long i=0L; i 
void CCollection::AtPut(T* t, long index) 
{ 
	ASSERT(index>=0); 
	if (index < 0) return; 
	if(index>=count)  
	{ 
		if (limit 
void CCollection::AtFree(long index, bool discardmem) 
{ 
	ASSERT(index>=0L && index=count)) return; 
	delete items[index]; 
	items[index] = NULL; 
	if (discardmem) 
	{ 
		for (long i=index; i 
void CCollection::AtInsert(T* t, long index) 
{ 
	ASSERT(index>=0L && index<=count); 
	if(index>=count)  
	{ 
		if (limitindex; i--) 
		{ 
			items[i] = items[i-1]; 
		}; 
		items[index] = t; 
	} 
}; 
 
template  
long CCollection::Search(T* t) const 
{ 
	for (long i=0L; i 
long CCollection::CountNonZero() const 
{ 
	long ptrcount = 0L; 
	long i; 
	for (i=0L; i 
void CCollection::Pack() 
{ 
	long ptrcount = CountNonZero(); 
	T** tempitems = Alloc_Mem(ptrcount + 10L);  // kleine Sicherheit 
	// Kopieren 
	long j = 0L; 
	for (long i=0L; i 
CCollection& operator << (CCollection& dest, CCollection& source) 
{ 
	for (long i=0L; i 
void CCollection::Serialize(CArchive& ar) 
{ 
	if (ar.IsStoring()) 
	{ 
		try 
		{ 
			ar << CountNonZero(); 
			ar << delta; 
			ar << limit; 
			ar << Name; 
			for (long i=0; iSerialize(ar); 
				} 
			} 
		} 
		catch (...) 
		{ 
			return; 
		} 
	} 
	else 
	{ 
		FreeAll(); 
		try 
		{ 
			ar >> count; 
			ar >> delta; 
			ar >> limit; 
			ar >> Name; 
			if (count < 0) 
				count = 0; 
			if (delta < 0) 
				delta = 2; 
			if (limit < count) 
				limit = count; 
			items = Alloc_Mem(limit); 
			for (long i=0; iSerialize(ar); 
				items[i] = t; 
			} 
		} 
		catch (...) 
		{ 
			count = 0; 
			limit = 2; 
			items = Alloc_Mem(limit); 
			return; 
		} 
	} 
}; 
*/ 
// ================== CSortCollection ======================================= 
 
template  
long CSortCollection::Search(T* t) const 
{ 
	// kann mit binärer Suche (BSearch) effizienter erledigt werden 
	 
	for(long i=0L; i 
long CSortCollection::BSearch(T* t) const 
{ 
	long l = 0; 
	long r = count-1; 
	long m; 
 
	while (l<=r) 
	{ 
		m = (l+r)/2; 
		switch (Compare(At(m), t)) 
		{ 
		case -1: l = m+1; break; 
		case 0:  return m; 
		case 1:  r = m-1; 
		} 
	} 
	return -1; 
}; 
 
template  
int CSortCollection::Compare(T* t1, T* t2) const 
{ 
	if (!t1 && !t2) return 0; 
	if (!t1) return -1; 
	if (!t2) return  1; 
	return t1->Compare(*t2); 
}; 
 
template  
bool CSortCollection::BubbleSort() 
{ 
	for (long i=1; i=i; j--) 
		{ 
			if (Compare(At(j), At(j-1)) == -1) 
			{ 
				T* t = items[j]; 
				items[j] = items[j-1]; 
				items[j-1] = t; 
				j--; 
			} 
		} 
	} 
	return true; 
}; 
 
template  
bool CSortCollection::InsertionSort() 
{ 
	for (long i=1; i0 && Compare(At(j), At(j-1)) == -1)  
		{ 
			T* t = items[j]; 
			items[j] = items[j-1]; 
			items[j-1] = t; 
			j--; 
		} 
	} 
	return true; 
}; 
 
template  
bool CSortCollection::SelectionSort() 
{ 
	for (long i=0; i 
bool CSortCollection::ShellSort() 
{ 
	return true; 
}; 
 
template  
bool CSortCollection::MergeSort(long l, long r) 
{ 
	if (l==-1) l = 0; 
	if (r==-1) r = count-1; 
	return true; 
}; 
 
template  
bool CSortCollection::QuickSort(long l, long r) 
{ 
	if (l==-1) l = 0; 
	if (r==-1) r = count-1; 
	return true; 
}; 
 
// ================== CSortedCollection ======================================= 
 
template  
void CSortedCollection::Insert(T* t) 
{ 
	if (!duplicates && Search(t)) 
	{ 
		return;    // keine doppelten Schlüssel -> Item wird nicht eingefügt 
	}; 
	if (count == limit) 
	{ 
		Resize(limit + delta); 
	}; 
 
	count++; 
	for(long i=count-1; i>0L; i--) 
	{ 
		if (Compare(items[i-1], t) <= 0) 
		{ 
			items[i] = t; 
			return; 
		}; 
		items[i] = items[i-1]; 
	}; 
	items[0] = t; 
}; 
 
// ================== CChooseCollection ======================================= 
template  
void CChooseCollection::SetSelIndex(long _index) 
{ 
	ASSERT(_index>=0L && _index= count) Selected = count-1; 
}; 
 
template  
long CChooseCollection::Find(const char* _name) const 
{ 
	for (long i=0L; iGetName().Collate(_name)) == 0) 
		{ 
			return i; 
		} 
	} 
	return -1L; 
} 
 
template  
void CChooseCollection::SetSelIndex(const char* _name) 
{ 
	long i = Find(_name); 
	if (i>=0) Selected = i; 
}; 
 
template  
bool CChooseCollection::ChooseSelected(const char* /*dialogtitle*/, CWnd* parent) 
{ 
	CChooseCollDialog dlg(*this, parent); 
	if (dlg.DoModal() && dlg.Selected >= 0) 
	{ 
		Selected = dlg.Selected; 
		return true; 
	} 
	return false; 
}; 
 
template  
long* CChooseCollection::MultiSelection(const char* dialogtitle) 
{ 
	return NULL; 
}; 
 
template 
void CChooseCollDialog::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	DDX_Control(pDX, IDC_CHOOSECOLLDIALOG_LIST1, m_ctlListBox); 
	DDX_LBIndex(pDX, IDC_CHOOSECOLLDIALOG_LIST1, Selected); 
}; 
 
template 
BOOL CChooseCollDialog::OnInitDialog() 
{ 
	BOOL ret = CDialog::OnInitDialog(); 
	if (Coll.IsEmpty()) return false; // nothing to choose 
	for (long i=0; iGetName()); 
	} 
	m_ctlListBox.SetCurSel(Coll.GetSelIndex()); 
	return ret; 
}; 
 
template 
BOOL CChooseCollDialog::OnCommand(WPARAM wParam, LPARAM lParam) 
{ 
	if ((int)HIWORD(wParam)==LBN_DBLCLK && (int) LOWORD(wParam)==IDC_CHOOSECOLLDIALOG_LIST1) 
	{ 
		wParam = IDOK; 
		lParam = 0; 
	} 
	return CDialog::OnCommand(wParam, lParam); 
} 
 
/* 
template 
void CChooseCollection::Serialize(CArchive& ar) 
{ 
	if (ar.IsStoring()) 
	{ 
		CCollection::Serialize(ar); 
	} 
	else 
	{ 
		CCollection::Serialize(ar); 
		Selected = 0; // ist beim Speichern verlorengegangen 
	} 
} 
*/