OWL - Listview-Kontrollelemente unter Win32

Willemers Informatik-Ecke

Das ListView ist mit Win32 erschienen. In der OS/2 OWL ist ein solches Element nicht vorgesehen, obwohl es mit dem Container-Element vermutlich zu realisieren wäre.

Zunächst muß der Header eingebunden werden.

#include <owl\listwind.h>

Es wird die Klasse für das Fenster definiert, das das Listview-Element aufnehmen soll.

class tTaskListWin: public TMDIChild
{
public:
	// Konstruktor
	tTaskListWin(TMDIClient &AParent, char *title);

	...
	void ColClick(TLwNotify& nmHdr);
	TListWindow *Liste;
private:
	DECLARE_RESPONSE_TABLE(tTaskListWin);
};

DEFINE_RESPONSE_TABLE1(tTaskListWin, TMDIChild)
	EV_LVN_DELETEITEM(LIST_ID, DelItem),
	EV_LVN_COLUMNCLICK(LIST_ID, ColClick),
END_RESPONSE_TABLE;

EV_LVN_COLUMNCLICK ist das Ereignis, das auftritt, wenn in der Spalte geklickt wird. Es ruft die Funktion ColClick.

Das Erzeugen des Elements im Konstruktor erfolgen.

tTaskListWin::tTaskListWin(TMDIClient &AParent, char *title)
	 : TMDIChild(AParent, title)
{
	Liste = new TListWindow(this, LIST_ID, 10, 10, 100, 100);
	Liste->Attr.Style |= LVS_REPORT;

Mit LVS_REPORT wird festgelegt, daß es sich um eine Detailansicht handelt. Anschließend müssen die Spalten definiert werden, da man ohne Spalten nichts sieht. Die Spalten können erst angelegt werden, wenn das Kontrollelement erzeugt wurde (Create). Dieser Moment ist im OWL erst im SetupWindow erreicht.

void tTaskListWin::SetupWindow()
{

	TWindow::SetupWindow();
	TListWindColumn column0("ID", 100);
	Liste->InsertColumn(0, column0);
	TListWindColumn column1("Bezeichnung", 200, TListWindColumn::Left, 1);
	Liste->InsertColumn(1, column1);
	ShowAll(Liste);
}

ShowAll ist die Funktion, die die Liste mit Daten füllt. Sie ruft für jedes gefundene Element die Funktion ShowTask auf:

static ShowTask(TListWindow *Liste, tTask *pTask)
{
char str[256];
int index;

	tTask *newTask = new tTask;
	*newTask = *pTask;
	if (pTask==0) return 0;
	// zunaechst das Element der Hauptspalte
	TListWindItem item(pTask->GetID());
	item.SetItemData((LPARAM)newTask);
	index = Liste->InsertItem(item);
	// Dann die weitere Spalte
	TListWindItem sub(pTask->GetBez(), 1);
	Liste->SetItemText(index, sub);
}

SetItemData erfolgt genau einmal bei der Spalte 0. Damit wird der eigentliche Datenzeiger dem Listenelement zugeordnet.

Um zu erreichen, daß die hinterlegten Daten auch wieder frei gegeben werden, wird die Funktion DelItem definiert, die auf das Ereignis EV_LVN_DELETEITEM reagiert. Nach Doku die einzige Ereignisfunktion, in der das lParam-Element des TLwNotify gültig ist.

void tTaskListWin::DelItem(TLwNotify& nmHdr)
// wird aufgerufen, wenn ein Item geloescht wird
{
tTask *t = (tTask *)nmHdr.lParam;
	delete t;
}

Reaktion auf das Anklicken der Spalten

Wird auf die Spalte eines Reports geklickt, erwartet der Anwender meist die Sortierung der Daten nach dieser Spalte. Um dies zu erreichen, wird eine Klasse von TLwComparator abgeleitet, die in ihrem Member Compare die Strategie der Sortierung festlegt. Dabei gibt Compare nur das Ergebnis des Vergleichs zweier Elemente zurück. Die ersten beiden Parameter sind Zeiger auf die Daten, der dritte ist die Nummer der Spalte.

// ------ Comparator soll die Sortierung ueber die Knoepfe realisieren -------

class TMyLwComparator : public TLwComparator
{
public:
	int Compare(uint32 item1, uint32 item2, uint32 lParam) const;
};

int TMyLwComparator::Compare(uint32 item1, uint32 item2, uint32 pSort) const
{
tTask *t1, *t2;

   t1 = (tTask *)item1; t2 = (tTask *)item2;
   switch(pSort) {
   case 0:
      return strcmp(t1->GetID(), t2->GetID());
   case 1:
      return strcmp(t1->GetBez(), t2->GetBez());
   default:
      return 0;
   }
}

const TMyLwComparator MyCompare;

Eingebunden wird der Comparator durch Aufruf von SortItem im Falle, dass der Headerbutton gedrückt wurde.

void tTaskListWin::ColClick(TLwNotify& nmHdr)
{
	Liste->SortItems(MyCompare, (uint32)nmHdr.iSubItem);
}


Homepage - OWL-Programmierung (C) Copyright 1999 Arnold Willemer