/*********************************************************
 * Time Disk Bestellungsprogramm für die Time.guide		*
 *				(Mein allererstes C Programm)						*
 *********************************************************
 * Autor:					Manfred Tremmel						*
 * Programmiersprache:	C											*
 * Compilier:				Maxon C++ (ANSI-C-Modus)			*
 *********************************************************/

/* Versionsstring festlegen (fürs Shellkomando Version)	*/ 
char VersionID[] = "$VER: T_Bestellen 1.55 (28.10.95)";

/* C-Include für String-Operationen								*/
#include <string.h>
#include <stdlib.h>
/* C-Include für Dateioperationen (laden, speichern)		*/
#include <stdio.h>

/* AMIGA-Includes für die Exec.library							*/
#include <clib/exec_protos.h>
#include <exec/memory.h>
/* AMIGA-Include für die AmigaGuide.library					*/
#include <clib/amigaguide_protos.h>
/* AMIGA-Include für die graphics.library						*/
#include <clib/graphics_protos.h>
/* AMIGA-Include für die intuition.library					*/
#include <clib/intuition_protos.h>
/* AMIGA-Include für die gadtools.library						*/
#include <clib/gadtools_protos.h>
/* AMIGA-Include für die asl.library							*/
#include <clib/asl_protos.h>
/* AMIGA-Include für die locale.library						*/
#include <clib/locale_protos.h>
/* AMIGA-Include für die icon.library							*/
#include <clib/icon_protos.h>
/* AMIGA-Include für die commodities.library					*/
#include <clib/commodities_protos.h>
#include <clib/alib_protos.h>
/* AMIGA-Include für die dos.library zur Dateiüberwachung*/
#include <dos/notify.h>

/* AMIGA-Include, das die ganzen pragma/#? included		*/
#include <pragma/all_lib.h>

/* AMIGA-Include, daß das Programm WB-Startfähig macht	*/
#include <workbench/startup.h>
#include <wbstartup.h>

/* Texte, die der User zu Gesicht kriegt (via Local-lib.)*/
#include "T_Locale.h"

/* Structur für die Intuition.library							*/
struct IntuitionBase	*IntuitionBase		= NULL;
/* Structur für die graphics.library							*/
struct GfxBase			*GfxBase				= NULL;
/* Structur für die gadtools.library							*/
struct Library			*GadToolsBase		= NULL;
/* Structur für die AmigaGuide.library							*/
struct Library			*AmigaGuideBase	= NULL;
/* Structur für die Asl.library									*/
struct Library			*AslBase				= NULL;
/* Structur für die locale.library								*/
struct LocaleBase		*LocaleBase			= NULL;
/* Structur für die icon.library									*/
struct IconBase		*IconBase			= NULL;
/* Structur für die commodities.library						*/
struct CxBase			*CxBase				= NULL;
CxObj	*broker, *filter, *sender, *translate;
#define EVT_HOTKEY 1L

/* Notify-Structur zur Überwachung der Disk-Datei			*/
struct NotifyRequest	*nr;
struct MsgPort			*nmp;
struct NotifyMessage	*nm;

/* Signal-Flag-Variablen für die Abfrag eingehender		*/
/* Nachrichten (Window und Commodity)							*/
ULONG wndsigflag, cxsigflag;

/* Structur für den Asl-Filerequester							*/
struct FileRequester	*fr;
/* Structur für einen einfachen Info-Requester				*/
struct EasyStruct		es;

/* Dient dazu, eine neue Liste anzulegen						*/
void NewList(struct List *);

/* OS 3.x indikator NOS (New Operating System)				*/
BOOL NOS = TRUE;
/* Anzahl sichtbarer Einträge im Listview-Gadget			*/
/* Unter OS 2.x sind es nur 11 unter 3.x 12 Einträge     */
int  LVSicht = 12;

/* Globale Variablen definieren									*/
/* Einstellungen:														*/
struct Einst {
	char AName[30];			/* Absender:	Name				*/
	char AStrasse[30];		/* Absender:	Straße			*/
	char AOrt[30];				/* Absender:	Ort				*/
	char EName[30];			/* Empfänger:	Name				*/	
	char EStrasse[30];		/* Empfänger:	Straße			*/
	char EOrt[30];				/* Empfänger:	Ort				*/
	long Abstand;				/* Druckbeginnabstand			*/
	UWORD Versart;				/* Versandart						*/
	char KundNr[30];			/* Absender:	Kundennummer	*/
};

struct Einst P1;				/* Konkrete Strukt. festlegen	*/

/* Struktur der Diskettenliste (nur der Diskettenname)	*/
struct VDB{
	char Name[16];				/* Diskettennamen					*/
};

/* Structur zur Verwaltung der Diskettenliste anlegen		*/
struct VDBnode{
	struct	Node n;
	struct	VDB  d;
};

/* erzeugt eine Liste, in die die einzelen VDBs kommen	*/
struct List vdblist;

/* vdblist enthält den aktuellen Eintrag oder NULL			*/
struct VDBnode *currentvdb;

/* Dateiname des Einstellungs-Files								*/
char Einst_File[128] = "T_Best.dat";

/* Datei zwischengemerkter Disketten							*/
char T_Remember[128] = "T:Time_Remember.dat";

/* Variablen für das Einbinden als Commodity					*/
BYTE CX_Priority = 0;
BOOL CX_Popup = TRUE;
char CX_Popkey[30] = "ctrl alt t";

/* Titel des Fensters												*/
char WinTitel[50];
/* Funktion GetString holt einen Text aus dem Puffer		*/
#define GetString( g )	((( struct StringInfo * )g->SpecialInfo )->Buffer  )
/* Funktion GetNumber holt eine Nummer aus dem Puffer		*/
#define GetNumber( g )	((( struct StringInfo * )g->SpecialInfo )->LongInt )

/* Die Nummern der Gadgets mit konkreten Bezeichnung		*/
#define GD_Diskliste		0		/* Diskettenliste				*/
#define GD_NeueDisk		1		/* Neu Button					*/
#define GD_DiskLoeschen	2		/* Löschen Button				*/
#define GD_Zahlart		3		/* Zahlart MX-Button			*/
#define GD_Drucken		4		/* Drucken Button				*/
#define GD_Abbrechen		5		/* Abbrechen Button			*/
#define GD_AName			6		/* Absender: Name				*/
#define GD_AStrasse		7		/* Absender: Strasse			*/
#define GD_AOrt			8		/* Absender: Ort				*/
#define GD_KundNr			9		/* Kundennummer				*/
#define GD_EName			10		/* Empfänger: Name			*/
#define GD_EStrasse		11		/* Empfänger: Strasse		*/
#define GD_EOrt			12		/* Empfänger: Ort				*/
#define GD_DiskAender	13		/* Disk ändern					*/
#define GD_Abstand		14		/* Abstand zum Druckbeginn	*/

/* Anzahl der Gadgets definieren (0 bis 14 = 15)			*/
#define Bestellen_CNT									15

/* Die Nummern der Menus mit Konkreten Bezeichnungen		*/
#define MENU_FOO_OPA		1		/* Öffnen - Einstellungen	*/
#define MENU_FOO_OPB		2		/* Öffnen - Diskliste		*/
#define MENU_FOO_SPA		3		/* Speichern - Einstell.	*/
#define MENU_FOO_SPB		4		/* Speichern - Diskliste	*/
#define MENU_FOO_SAA		5		/* Speichern als -Einstell.*/
#define MENU_FOO_SAB		6		/* Speichern als -Diskliste*/
#define MENU_FOO_DRU		7		/* Drucken						*/
#define MENU_FOO_INF		8		/* Information					*/
#define MENU_FOO_HID		9		/* Verbergen					*/
#define MENU_FOO_END		10		/* Ende							*/	

/* Screenstruktur löschen											*/
struct Screen			*Scr = NULL;
/* Public Screen Name löschen										*/
UBYTE						*PubScreenName = NULL;
/* DrawInfo deklarieren und löschen								*/
struct DrawInfo		*dri = NULL;
/* VisualInfo löschen												*/
APTR						VisualInfo = NULL;
/* Window Struktur löschen											*/
struct Window			*BestellenWnd = NULL;
/* Gadget Struktur löschen											*/
struct Gadget			*BestellenGList = NULL;
/* Menu Struktur löschen											*/
struct Menu				*BestellenMenus = NULL;
/* NewBroker Structur (zur Einbindung als Commodity)		*/
struct NewBroker		newbroker = {NULL, NULL, NULL, NULL,
									NULL, NULL, NULL, NULL, NULL};

/* Anzahl GadgetStrukturen festlegen (15)						*/
struct Gadget			*BestellenGadgets[15];
/* Breite des Fensters (wird nach Fontbreite umgerechnet)*/
UWORD						BestellenWidth = 460;
/* Höhe des Fenster (wird nach Fonthöhe umgerechnet)		*/
UWORD						BestellenHeight = 250;
/* Struktur Textatribute mit Fontinformationen definieren*/
struct TextAttr		*Font, Attr;
/* Definiere Felder für die Fontbreite und Höhe				*/
UWORD						FontX, FontY;
/* Definiere Felder für den minimalabstand des Fensters	*/
UWORD						OffX, OffY;
/* Definiere Felder für tatsächliche Pos. des Fensters	*/
UWORD						WinX = 0;
UWORD						WinY = 0;
/* Position im Listview-Gadget									*/
long						ListPos = 0;

/* Textatribrute für das Fenster									*/
struct TextFont		*BestellenFont = NULL;

/* Texte für das Zahlungsform-MX-Gadget						*/
UBYTE *Gadget300Labels[] = {
	NULL,
	NULL,
	NULL,
	NULL };

/* Zusätzliche Texte und deren Position						*/
struct IntuiText BestellenIText[] = {
	1, 0, JAM1,45, 014, NULL, NULL, NULL,
	1, 0, JAM1,45, 132, NULL, NULL, NULL };

/* Anzahl zusätzlicher Texte										*/
#define Bestellen_TNUM 2

/* MenuStruktur füllen												*/
struct NewMenu BestellenNewMenu[] = {
	NM_TITLE, NULL, NULL,	0, 0L, NULL,
	 NM_ITEM, NULL, NULL,	0, 0L, NULL,
	  NM_SUB, NULL, NULL,	0, 0L, (void *)(MENU_FOO_OPA),
	  NM_SUB, NULL, NULL,	0, 0L, (void *)(MENU_FOO_OPB),
	 NM_ITEM, NULL, NULL,	0, 0L, NULL,
	  NM_SUB, NULL, NULL,	0, 0L, (void *)(MENU_FOO_SPA),
	  NM_SUB, NULL, NULL,	0, 0L, (void *)(MENU_FOO_SPB),
	 NM_ITEM, NULL, NULL,	0, 0L, NULL,
	  NM_SUB, NULL, NULL,	0, 0L, (void *)(MENU_FOO_SAA),
	  NM_SUB, NULL, NULL,	0, 0L, (void *)(MENU_FOO_SAB),
	 NM_ITEM, NULL, NULL,	0, 0L, (void *)(MENU_FOO_DRU),
	 NM_ITEM, (STRPTR)NM_BARLABEL, NULL,	0, 0L, NULL,
	 NM_ITEM, NULL, NULL,	0, 0L, (void *)(MENU_FOO_INF),
	 NM_ITEM, (STRPTR)NM_BARLABEL, NULL,	0, 0L, NULL,
	 NM_ITEM, NULL, NULL,	0, 0L, (void *)(MENU_FOO_HID),
	 NM_ITEM, NULL, NULL,	0, 0L, (void *)(MENU_FOO_END),
	  NM_END, NULL, NULL,	0, 0L, NULL
};

/* Gadgettypen definieren											*/
UWORD BestellenGTypes[] = {
	LISTVIEW_KIND,
	BUTTON_KIND,
	BUTTON_KIND,
	MX_KIND,
	BUTTON_KIND,
	BUTTON_KIND,
	STRING_KIND,
	STRING_KIND,
	STRING_KIND,
	STRING_KIND,
	STRING_KIND,
	STRING_KIND,
	STRING_KIND,
	STRING_KIND,
	INTEGER_KIND
};

/* Gadgets festlegen													*/
struct NewGadget BestellenNGad[] = {
	242,  24, 115, 156, NULL, NULL, GD_Diskliste, PLACETEXT_ABOVE, NULL, NULL,
	242, 195,  47,  20, NULL, NULL, GD_NeueDisk, PLACETEXT_IN, NULL, NULL,
	289, 195,  68,  20, NULL, NULL, GD_DiskLoeschen, PLACETEXT_IN, NULL, NULL,
	361,  52,  17,   9, NULL, NULL, GD_Zahlart, PLACETEXT_RIGHT, NULL, NULL,
	  4, 225,  88,  20, NULL, NULL, GD_Drucken, PLACETEXT_IN, NULL, NULL,
	366, 225,  88,  20, NULL, NULL, GD_Abbrechen, PLACETEXT_IN, NULL, NULL,
	 71,  28, 161,  20, NULL, NULL, GD_AName, PLACETEXT_LEFT, NULL, NULL,
	 71,  50, 161,  20, NULL, NULL, GD_AStrasse, PLACETEXT_LEFT, NULL, NULL,
	 71,  72, 161,  20, NULL, NULL, GD_AOrt, PLACETEXT_LEFT, NULL, NULL,
	 71,  94, 161,  20, NULL, NULL, GD_KundNr, PLACETEXT_LEFT, NULL, NULL,
	 71, 147, 161,  20, NULL, NULL, GD_EName, PLACETEXT_LEFT, NULL, NULL,
	 71, 169, 161,  20, NULL, NULL, GD_EStrasse, PLACETEXT_LEFT, NULL, NULL,
	 71, 191, 161,  20, NULL, NULL, GD_EOrt, PLACETEXT_LEFT, NULL, NULL,
	242, 174, 115,  20, NULL, NULL, GD_DiskAender, 0, NULL, NULL,
	361,  24,  86,  20, NULL, NULL, GD_Abstand, PLACETEXT_ABOVE, NULL, NULL
};

/* Tags zu den Gadgets												*/
ULONG BestellenGTags[] = {
	(GTLV_ShowSelected), 0, (GT_Underscore), '_', (TAG_DONE),
	(GT_Underscore), '_', (TAG_DONE),
	(GT_Underscore), '_', (TAG_DONE),
	(GTMX_Labels), (ULONG)&Gadget300Labels[ 0 ], (GT_Underscore), '_', (TAG_DONE),
	(GT_Underscore), '_', (TAG_DONE),
	(GT_Underscore), '_', (TAG_DONE),
	(STRINGA_ExitHelp), TRUE, (GTST_MaxChars), 29, (GT_Underscore), '_', (TAG_DONE),
	(STRINGA_ExitHelp), TRUE, (GTST_MaxChars), 29, (GT_Underscore), '_', (TAG_DONE),
	(STRINGA_ExitHelp), TRUE, (GTST_MaxChars), 29, (GT_Underscore), '_', (TAG_DONE),
	(STRINGA_ExitHelp), TRUE, (GTST_MaxChars), 29, (GT_Underscore), '_', (TAG_DONE),
	(STRINGA_ExitHelp), TRUE, (GTST_MaxChars), 29, (GT_Underscore), '_', (TAG_DONE),
	(STRINGA_ExitHelp), TRUE, (GTST_MaxChars), 29, (GT_Underscore), '_', (TAG_DONE),
	(STRINGA_ExitHelp), TRUE, (GTST_MaxChars), 29, (GT_Underscore), '_', (TAG_DONE),
	(STRINGA_ExitHelp), TRUE, (GTST_MaxChars), 14, (TAG_DONE),
	(STRINGA_ExitHelp), TRUE, (GTIN_Number), 0, (GTIN_MaxChars), 3, (GT_Underscore), '_', (TAG_DONE)
};

/* Vordefinieren sämtlicher im Programm vorkommender		*/
/* Unterprogramme														*/

/* Positionen nach Fontbreite umrechnen						*/
static UWORD ComputeX( UWORD value );

/* Positionen nach Fonthöhe umrechnen							*/
static UWORD ComputeY( UWORD value );

/* Computerbreite und -höhe Bestimmen							*/
static void ComputeFont( UWORD width, UWORD height );

/* Voreinstellungen fürs Fenster (Screen vorbereiten)		*/
int SetupScreen( void );

/* Sreen wieder zurücksetzen										*/
void CloseDownScreen( void );

/* Texte und BevelBoxes aufs Fenster zeichnen				*/
void BestellenRender( void );

/* Fenster öffenen													*/
int OpenBestellenWindow( void );

/* Fenster wieder dicht machen									*/
void CloseBestellenWindow( void );

/*	Gadtools-Gadget einschalten 									*/
void gt_OnGadget( struct Gadget 	*gad, struct Window		*w );

/*	...und wieder aus...												*/
void gt_OffGadget( struct Gadget 	*gad, struct Window	*w );

/*  String-Gadgets mit nem string füllen						*/
void gt_SetString( struct Gadget	*gad,
				   struct Window	*w,
				   char				*string );

/* und nachschaun, welcher drinnen steckt						*/
char * gt_GetString( struct Gadget	*gad );

/* Integer-Gadgets mit ner Zahl füllen							*/
void gt_SetInteger( struct Gadget	*gad,
				    struct Window	*w,
				    LONG			value );

/* und nachschaun, welche drinnen steckt						*/
LONG gt_GetInteger( struct Gadget	*gad );

/* Liste anhängen														*/
void gt_AttachList(	struct Gadget 	*lv,
					struct Window 	*w,
				 	struct List 	*list );

/* Aktuellen Eintrag setzen										*/
void gt_SetLV( struct Gadget	*gad,
			   struct Window	*w,
			   ULONG			value);

/* x-ten Eintrag aus einer Exec-Liste holen */
struct Node * gt_GetListEntry( struct List *l,
							   int num );

/* Nummer einer Node aus einer Liste feststellen			*/
int gt_GetListEntryNum(	struct List *l,
						struct Node *n );

/* Anzahl Einträge einer Liste zählen							*/
int gt_GetListNumEntries( struct List *l );

/* Gadgets ein oder Ausschalten									*/
void checkonoff( void );

/* Neuer Eintrag in die Liste	aufnehmen						*/
void newvdb( void );

/* Libraries öffnen													*/
BOOL OpenAll();

/* Libraries schließen												*/
void CloseAll();

/* Unterprogramm zum Einlesen der Einstellungen				*/
void EinstLesen();

/* Unterprogramm zum Schreiben der Einstellungen			*/
void EinstSchreiben();

/* Sortiert einen neuen Eintrag in die Liste ein.			*/
long NeuerEintrag(char *Eintrag);

/* Einen Eintrag aus der Liste entfernen						*/
void EintragLoeschen();

/* Unterprogramm zum Einlesen der Time-Diskettendaten		*/
void DatenLesen();

/* Unterprogramm zum Schreiben der Time-Diskettendaten	*/
void DatenSchreiben( struct List *l);

/* Die Bestellung auf eine Postkarte Drucken					*/
void Drucken( struct List *l );

/* Window mit den Voreingestellten Daten füllen				*/
void Winfuell();

/* Wenn jemand versucht ein Gadget zu erdrücken				*/
BOOL Abfrage_Gadgetup( struct Gadget *gad, long code);

/* Jemand hat das Menu benutzt									*/
BOOL Abfrage_Menuepick( UWORD code);

/* Eine handelsübliche Taste wurde gedrückt					*/
BOOL Abfrage_Vanillakey( struct Gadget *gad, UWORD code);

/* eine der Tasten die nix aufm Bildschirm hinterlassen	*/
void Abfrage_Rawkey( struct Gadget *gad, UWORD code, struct Gadget *gd);

/* eine der Tasten die nix aufm Bildschirm hinterlassen	*/
void Abfrage_Menuhelp( UWORD code);

/* Localisierte Texte einlesen (wenn vorhanden)				*/
void LocaleLesen();


/* Positionen nach Fontbreite umrechnen						*/
static UWORD ComputeX( UWORD value )
{
	return(( UWORD )((( FontX * value ) + 3 ) / (UWORD)7 ));
}

/* Positionen nach Fonthöhe umrechnen							*/
static UWORD ComputeY( UWORD value )
{
	return(( UWORD )((( FontY * value ) + 6 ) / (UWORD)12 ));
}

/* Computerbreite und -höhe Bestimmen							*/
static void ComputeFont( UWORD width, UWORD height )
{
	/* Voreingestellten Font benutzen							*/
	Font = &Attr;
	/* Fontname bestimmen											*/
	Font->ta_Name = (STRPTR)Scr->RastPort.Font->tf_Message.mn_Node.ln_Name;
	/* Fonthöhe bestimmen											*/
	Font->ta_YSize = FontY = Scr->RastPort.Font->tf_YSize;
	/* Fontbreite bestimmen											*/
	FontX = Scr->RastPort.Font->tf_XSize;

	/* minimaler horizontaler Abstand							*/
	OffX = Scr->WBorLeft;
	/* minimaler vertikaler Abstand								*/
	OffY = Scr->RastPort.TxHeight + Scr->WBorTop + 1;

	/* Überprüfen, ob das Fenster nicht zu groß wird		*/ 
	if ( width && height ) {
		/* Wenn es horizontal zu groß wird, oder				*/
		if (( ComputeX( width ) + OffX + Scr->WBorRight ) > Scr->Width )
			goto UseTopaz;
		/* vertikal, dann benutze den Topas 8 Font			*/
		if (( ComputeY( height ) + OffY + Scr->WBorBottom ) > Scr->Height )
			goto UseTopaz;
	}
	return;

/* Topas Font verwenden, weils Fenster sonst zu groß wird*/
UseTopaz:
	Font->ta_Name = (STRPTR)"topaz.font";
	FontX = FontY = Font->ta_YSize = 8;
}

/* Voreinstellungen fürs Fenster (Screen vorbereiten)		*/
int SetupScreen( void )
{
	/* Schaun, ob wir nen PubScreen verwenden können		*/
	if ( ! ( Scr = LockPubScreen( PubScreenName )))
		return( 1L );

	/* Schrifthöhe und -breit bestimmen							*/
	ComputeFont( 0, 0 );

	/* Visualinfo setzen (Zeiger, wo es sichtbar wird)		*/
	if ( ! ( VisualInfo = GetVisualInfo( Scr, TAG_DONE )))
		return( 2L );

	/* wenn alles glatt gegangen ist, 0 zurückgeben			*/
	return( 0L );
}

/* Sreen wieder zurücksetzen										*/
void CloseDownScreen( void )
{
	/* falls wir ein VisualInfo gekriegt haben, freigeben	*/
	if ( VisualInfo ) {
		FreeVisualInfo( VisualInfo );
		VisualInfo = NULL;
	}

	/* PubScreen wieder zurücksetzen								*/
	if ( Scr        ) {
		UnlockPubScreen( NULL, Scr );
		Scr = NULL;
	}
}

/* Texte und BevelBoxes aufs Fenster zeichnen				*/
void BestellenRender( void )
{
	struct IntuiText	it;
	UWORD			cnt;

	/* Font berechnen													*/
	ComputeFont( BestellenWidth, BestellenHeight );

	/* Absenderumrandende BevelBox zeichnen					*/
	DrawBevelBox( BestellenWnd->RPort, OffX + ComputeX( 10 ),
					OffY + ComputeY( 24 ),
					ComputeX( 227 ),
					ComputeY( 94 ),
					GT_VisualInfo, VisualInfo, GTBB_Recessed, TRUE, TAG_DONE );
	/* Empfängerumrandende BevelBox zeichnen					*/
	DrawBevelBox( BestellenWnd->RPort, OffX + ComputeX( 10 ),
					OffY + ComputeY( 143 ),
					ComputeX( 227 ),
					ComputeY( 72 ),
					GT_VisualInfo, VisualInfo, GTBB_Recessed, TRUE, TAG_DONE );
		/* Allumrandende BevelBox zeichnen							*/
	DrawBevelBox( BestellenWnd->RPort, OffX + ComputeX( 2 ),
					OffY + ComputeY( 3 ),
					ComputeX( 453 ),
					ComputeY( 218 ),
					GT_VisualInfo, VisualInfo, TAG_DONE );

	/* Texte ausgeben													*/
	for ( cnt = 0; cnt < Bestellen_TNUM; cnt++ ) {
		/* Text aufbereiten											*/
		CopyMem(( char * )&BestellenIText[ cnt ], ( char * )&it, (long)sizeof( struct IntuiText ));
		/* Font festlegen												*/
		it.ITextFont = Font;
		/* horizontale Position festlegen						*/
		it.LeftEdge  = OffX + ComputeX( it.LeftEdge ) - ( IntuiTextLength( &it ) >> 1 );
		/* vertikale Position festlegen							*/
		it.TopEdge   = OffY + ComputeY( it.TopEdge ) - ( Font->ta_YSize >> 1 );
		/* Text ausgeben												*/
		PrintIText( BestellenWnd->RPort, &it, 0, 0 );
	}
}

/* Fenster öffenen													*/
int OpenBestellenWindow( void )
{
	/* NewGadget Struktur konkret anlegen						*/
	struct NewGadget	ng;
	/* Gadget Struktur konkret anlegen							*/
	struct Gadget	*g;
	/* Zwei laufvariable definieren								*/
	UWORD		lc, tc;
	/* Für die horizontale und vertikale Größe				*/
	UWORD		ww, wh;

	/* Fontröße berechnen											*/
	ComputeFont( BestellenWidth, BestellenHeight );

	/* absolute Fenstergröße horizontal berechnen			*/
	ww = ComputeX( BestellenWidth );
	/* absolute Fenstergröße vertikal berechnen				*/
	wh = ComputeY( BestellenHeight );

	/* Font öffnen, wenns fehlschlägt, Fehler zurückgeben	*/
	if ( ! ( BestellenFont = OpenDiskFont( Font )))
		return( 5L );

	/* Liste fürs erstellen der Gadgets erstellen			*/
	if ( ! ( g = CreateContext( &BestellenGList )))
		return( 1L );

	/* wiederhole, bis alle Gadgets erstellt sind			*/
	for( lc = 0, tc = 0; lc < Bestellen_CNT; lc++ )
	{
		/* Speicherbereich in dem die Liste definiert ist	*/
		/* an die Liste ranhängen									*/
		CopyMem((char * )&BestellenNGad[ lc ], (char * )&ng, (long)sizeof( struct NewGadget ));

		/* VisualInfo an die Gadgetstructur übergeben		*/
		ng.ng_VisualInfo = VisualInfo;
		/* Font fürs Gadget festlegen								*/
		ng.ng_TextAttr   = Font;
		/* horizontale Position errechnen						*/
		ng.ng_LeftEdge   = OffX + ComputeX( ng.ng_LeftEdge );
		/* vertikale Position errechnen							*/
		ng.ng_TopEdge    = OffY + ComputeY( ng.ng_TopEdge );
		/* Breite berechnen											*/
		ng.ng_Width      = ComputeX( ng.ng_Width );
		/* und die Höhe berechnen									*/
		ng.ng_Height     = ComputeY( ng.ng_Height);

		/* Das ganze können wir jetzt mal herstellen			*/
		BestellenGadgets[ lc ] = g = CreateGadgetA((ULONG)BestellenGTypes[ lc ], g, &ng, ( struct TagItem * )&BestellenGTags[ tc ] );

		/* tc erhöhen													*/
		while( BestellenGTags[ tc ] ) tc += 2;
		tc++;

		/* Bei einem Fehler, brechen wir die Sache ab		*/
		if ( NOT g )
			return( 2L );
	}

	/* Menus noch vorbereiten										*/
	/* Unter OS 3.x 													*/
	if( NOS )
	{
		/* Verwenden wir die Prefs-Menü-Farben					*/
		dri = GetScreenDrawInfo( Scr );
		if ( ! ( BestellenMenus = CreateMenus( BestellenNewMenu, GTMN_FrontPen, dri->dri_Pens[BARDETAILPEN], GTMN_NewLookMenus, TRUE, TAG_DONE )))
			return( 3L );
	}
	/* unter OS 2.x													*/
	else
	{
		/* können wir standardmäßig die Farbe 0 verwenden	*/
		if ( ! ( BestellenMenus = CreateMenus( BestellenNewMenu, GTMN_FrontPen, 0L, TAG_DONE )))
			return( 3L );
	}

	/* und herstellen													*/
	LayoutMenus( BestellenMenus, VisualInfo, TAG_DONE );

	/* Abstand von Oben ermitteln									*/
	if (WinX > 0)
	{
		if ((WinX + ww + OffX + Scr->WBorRight) > Scr->Width)
		{
			WinX = (Scr->Width - (ww + OffX + Scr->WBorRight));
		}
	}
	else
	{
		WinX = (Scr->Width  - (ww + OffX + Scr->WBorRight )) / (UWORD)2;
	}

	/* Abstand von Oben ermitteln									*/
	if (WinY > 0)
	{
		if ((WinY + wh + OffY + Scr->WBorBottom) > Scr->Height)
		{
			WinY = (Scr->Height - (wh + OffY + Scr->WBorBottom));
		}
	}
	else
	{
		WinY = (Scr->Height - (wh + OffY + Scr->WBorBottom)) / (UWORD)2;
	}

	/* Schon können wir es wagen, das Fenster zu öffnen	*/
	if ( ! ( BestellenWnd = OpenWindowTags( NULL,
				WA_Left,				WinX,
				WA_Top,				WinY,
				WA_Width,			ww + OffX + Scr->WBorRight,
				WA_Height,			wh + OffY + Scr->WBorBottom,
				WA_IDCMP,			IDCMP_CLOSEWINDOW|IDCMP_GADGETUP|IDCMP_GADGETDOWN|IDCMP_MENUHELP|IDCMP_MENUPICK|IDCMP_VANILLAKEY|IDCMP_GADGETHELP|IDCMP_RAWKEY,
				WA_Flags,			WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_SMART_REFRESH|WFLG_ACTIVATE|WFLG_NEWLOOKMENUS,
				WA_Gadgets,			BestellenGList,
				WA_Title,			WinTitel,
				WA_ScreenTitle,	(UBYTE *)AppStrings[MSG_ScreenName],
				WA_PubScreen,		Scr,
				WA_MenuHelp,		TRUE,
				WA_NewLookMenus,	TRUE,
				TAG_DONE )))
	return( 4L );

	/* Signalbit des Fensters für abfrage merken				*/
	wndsigflag = 1L << BestellenWnd->UserPort->mp_SigBit;
	/* Hängen wir das Menu noch dran								*/
	SetMenuStrip( BestellenWnd, BestellenMenus );
	/* Kurzer refresh, sonst schmiert uns das Ding ab		*/
	GT_RefreshWindow( BestellenWnd, NULL );

	/* Die Bevel Boxen und ein wenig Text draufzeichnen	*/
	BestellenRender();

	/* Fenster ist offen!											*/
	CX_Popup = TRUE;

	/* Gadgets sperren oder öffnen, wenn nötigt				*/
	checkonoff();

	/* HelpControl unter 3.x starten, wegen der Hilfe		*/
	if( NOS )
	{
		HelpControl(BestellenWnd, HC_GADGETHELP);
	}

	/* Alles Klar Boss												*/
	return( 0L );
}

/* Fenster wieder dicht machen									*/
void CloseBestellenWindow( void )
{
	/* Hat das mit den Menus hingehaun?							*/
	if ( BestellenMenus      )
	{
		/* Vom Fenster abmontieren									*/
		ClearMenuStrip( BestellenWnd );
		/* und freigeben												*/
		FreeMenus( BestellenMenus );
		/* Vermerken, daß alles gelöscht wurde					*/
		BestellenMenus = NULL;
	}

	/* Konnte das Fenster geöffnet werden						*/
	if ( BestellenWnd        )
	{
		/* Position des Fensters festhalten						*/
		if( !(WinX = BestellenWnd->LeftEdge))
			WinX = 1;
		if( !(WinY = BestellenWnd->TopEdge))
			WinY = 1;
		if ( currentvdb );
			ListPos = gt_GetListEntryNum( &vdblist, (struct Node *) currentvdb );
		/* dann machen wir es wieder zu (wird kalt drausen)*/
		CloseWindow( BestellenWnd );
		/* und vermerken das mal eben								*/
		BestellenWnd = NULL;
		CX_Popup = FALSE;
	}

	/* Konnten die Gadgets erzeugt werden						*/
	if ( BestellenGList      )
	{
		/* Befreien wir sie wieder									*/
		FreeGadgets( BestellenGList );
		/* und vermerken auch dieses								*/
		BestellenGList = NULL;
	}

	/* Na, können Sie es sich denken? Konnte der Font...	*/
	if ( BestellenFont )
	{
		/* Dann schließen wir auch diesen						*/
		CloseFont( BestellenFont );
		/* und schreibens uns hinter die Löffel				*/
		BestellenFont = NULL;
	}
}

/*	Gadtools-Gadget einschalten 									*/
void gt_OnGadget( struct Gadget 	*gad,
				  struct Window		*w )
{
	GT_SetGadgetAttrs( gad, w, NULL, GA_DISABLED, FALSE, TAG_DONE );
}

/*	...und wieder aus...												*/
void gt_OffGadget( struct Gadget 	*gad,
				   struct Window	*w )
{
	GT_SetGadgetAttrs( gad, w, NULL, GA_DISABLED, TRUE, TAG_DONE );
}

/*  String-Gadgets mit nem string füllen						*/
void gt_SetString( struct Gadget	*gad,
				   struct Window	*w,
				   char				*string )
{
	GT_SetGadgetAttrs( gad, w, NULL, GTST_String, string, TAG_DONE );
}

/* und nachschaun, welcher drinnen steckt						*/
char * gt_GetString( struct Gadget	*gad )
{
	struct StringInfo *si = gad->SpecialInfo;

	if( si )
		return( ( char * ) si->Buffer );
	else
		return( NULL );
}

/* Integer-Gadgets mit ner Zahl füllen							*/
void gt_SetInteger( struct Gadget	*gad,
				    struct Window	*w,
				    LONG			value )
{
	GT_SetGadgetAttrs( gad, w, NULL, GTIN_Number, value, TAG_DONE );
}

/* und nachschaun, welche drinnen steckt						*/
LONG gt_GetInteger( struct Gadget	*gad )
{
	struct StringInfo *si = gad->SpecialInfo;

	if( si )
		return( si->LongInt );
	else
		return( NULL );

}

/* Listenverwaltung für Listview-Gadgets						*/

/* Liste anhängen
 * "list" kann ~0 (-1) sein, dann ist kein Listenzugriff möglich
 */

void gt_AttachList(	struct Gadget 	*lv,
					struct Window 	*w,
				 	struct List 	*list )
{
	GT_SetGadgetAttrs( lv, w, NULL, GTLV_Labels, list, TAG_DONE );
}

/* Aktuellen Eintrag setzen
 * incl. Automatischem Positionieren, wenn der Eintrag außerhalb
 * des sichtbaren Bereichs ist (maximal 12 Einträge darstellbar)
 */
void gt_SetLV( struct Gadget	*gad,
			   struct Window	*w,
			   ULONG			value)
{
	ULONG i;
	/* sollte ein Eintrag ausgewählt sein,						*/
	if( value >= 0 )
	{
		/* schau nach, welcher ganz oben in der Liste steht*/
		GT_GetGadgetAttrs( gad, w, NULL, GTLV_Top, &i, TAG_DONE );
		/* ist er größer als der gewählte,						*/
		if(value < i)
		{
			/* dann rutschen wir ein wenig hoch in der Liste*/
			i = value;
			GT_SetGadgetAttrs( gad, w, NULL, GTLV_Top, i, TAG_DONE );
		}
		/* sollte er zu hoch sein,									*/
		else if((value - i) > (LVSicht - 2))
		{
			/* müssen wir die Liste ein wenig runterblätten	*/
			i = value - (LVSicht - 1);
			GT_SetGadgetAttrs( gad, w, NULL, GTLV_Top, i, TAG_DONE );
		}
	}
	/* Nun können der Eintrag ausgewählt werden.				*/
	GT_SetGadgetAttrs( gad, w, NULL, GTLV_Selected, value, TAG_DONE );
}

/* x-ten Eintrag aus einer Exec-Liste holen */
struct Node * gt_GetListEntry( struct List *l,
							   int num )
{
	int count = 0;
	struct Node *n = l->lh_Head;

	while( n->ln_Succ )
	{
		if( num==count ) return( n );
		n = n->ln_Succ;
		count++;
	}
	return( NULL );
}

/* Nummer einer Node aus einer Liste feststellen
 * -1 falls nicht in Liste
 */
int gt_GetListEntryNum(	struct List *l,
						struct Node *n )
{
	int count = 0;
	struct Node *r = l->lh_Head;

	while( r->ln_Succ )
	{
		if( r==n ) return( count );
		r = r->ln_Succ;
		count++;
	}
	return( -1 );
}

/* Anzahl Einträge einer Liste zählen							*/
int gt_GetListNumEntries( struct List *l )
{
	int count = 0;
	struct Node *n = l->lh_Head;

	while( n->ln_Succ )
	{
		n = n->ln_Succ;
		count++;
	}

	return( count );
}

/* Gadgets ein oder Ausschalten									*/
void checkonoff( void )
{
	/* Wenn ein Eintrag aus der Liste angewählt ist,		*/
	if( currentvdb ) 
	{
		/* schalte die Gadgets ein									*/
		gt_OnGadget( BestellenGadgets[ GD_DiskLoeschen ], BestellenWnd );
		gt_OnGadget( BestellenGadgets[ GD_DiskAender ], BestellenWnd );
	}
	else
	{
		/* ansonsten brauchen wir sie gerade mal nicht		*/
		gt_OffGadget( BestellenGadgets[ GD_DiskLoeschen ], BestellenWnd );
		gt_OffGadget( BestellenGadgets[ GD_DiskAender ], BestellenWnd );
	}
}

/* Neuer Eintrag in die Liste	aufnehmen						*/
void newvdb( void )
{
	/* Neue Sturktur anlegen										*/
	struct VDBnode *new;

	/* Speicher dafür reservieren									*/
	new = AllocVec( sizeof( *new ), MEMF_CLEAR );

	/* Nur weitermachen, wenn es geklappt hat					*/
	if( !new )
		return;

	/* den neuen Satz zum aktuellen machen						*/
	currentvdb = new;
	new->n.ln_Name = new->d.Name;

	/* der neue Satz lautet vorrübergehend "- ??? -"		*/
	strcpy( new->d.Name, "- ??? -" );

	/* Liste abhängen													*/
	gt_AttachList( BestellenGadgets[GD_Diskliste], BestellenWnd, (struct List *) ~0 );

	/* Priorität = ASCII-Wert des ersten Buchstaben			*/
	new->n.ln_Pri	 = - new->d.Name[0];

	/* an die Liste nach Prioritäten sortiert anhängen		*/	
	Enqueue( &vdblist, (struct Node *) new );

	/* geänderte Liste wieder anhängen							*/
	gt_AttachList( BestellenGadgets[GD_Diskliste], BestellenWnd, &vdblist );

	/* im ListviewGadget aktivieren								*/
	gt_SetLV(BestellenGadgets[GD_Diskliste], BestellenWnd, gt_GetListEntryNum(&vdblist, (struct Node *) new));

	/* Wenn die Gadgets abgeschaltet sind, einschalten		*/
	checkonoff();

	/* den "- ??? -" ins String Gadget schreiben und zur	*/
	gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, currentvdb->d.Name );

	/* Änderung aktivieren, oder wollen Sie eine Test Disk*/
	ActivateGadget( BestellenGadgets[GD_DiskAender], BestellenWnd, NULL );
}

/* Libraries öffnen													*/
BOOL OpenAll()
{
	/* Kick 2.0 muß vorhanden sein								*/
	/* Library-Versionen mind. 37									*/

	/* Intuition.library in der 37er Version öffnen (3.x)	*/
	IntuitionBase = (struct IntuitionBase *)
	    OpenLibrary("intuition.library",37L);

	/* Graphics.library öffnen										*/
	GfxBase = (struct GfxBase *)
	    OpenLibrary("graphics.library",37L);

	/* GadTools.library öffnen										*/
   GadToolsBase = (struct Library *)
		OpenLibrary("gadtools.library",37L);

	/* Wenn das geklappt hat										*/
	if( GadToolsBase )
	{
		/* OS 3.0 (V39) oder höher vorhanden?					*/
		if( (GadToolsBase->lib_Version) > 38U )
		{
			NOS = TRUE;
			LVSicht = 12;
		}
		else
		{
			NOS = FALSE;
			LVSicht = 11;
		}
	}

	/* Asl.library öffnen (nicht zwindend notwendig)		*/
	AslBase       =
		OpenLibrary("asl.library", 37L);

	/* AmigaGuide.library (nicht zwingend notwendig)		*/
	AmigaGuideBase =
		OpenLibrary("amigaguide.library", 0L);

	/* Locale.library (nicht zwingend notwendig)				*/
	LocaleBase = (struct LocaleBase *)
		OpenLibrary("locale.library", 38L);

	/* Icon.library (nicht zwingend notwendig)				*/
	IconBase = (struct IconBase *)
		OpenLibrary("icon.library", 37L);

	/* Commodities.library öffnen									*/
	CxBase = (struct CxBase *)
		OpenLibrary("commodities.library", 37L);

	/* Hat es nicht geklappt, Fehler zurückgeben				*/
	if(! CxBase			||
		! GadToolsBase	||
		! GfxBase		||
		! IntuitionBase)
		return FALSE;
	return TRUE;
}

/* Libraries schließen												*/
void CloseAll()
{
	/* locale.library schließen, wenn sie offen ist			*/
	if( CxBase )
		CloseLibrary( ( struct Library *)CxBase );
	/* Icon.library schließen, wenn sie offen ist			*/
	if( IconBase )
		CloseLibrary( ( struct Library *)IconBase );
	/* locale.library schließen, wenn sie offen ist			*/
	if( LocaleBase )
		CloseLibrary( ( struct Library *)LocaleBase );
	/* AmigaGuide.library schließen, wenn sie offen ist	*/
	if( AmigaGuideBase )
		CloseLibrary( ( struct Library *)AmigaGuideBase );
	/* Asl.library schließen, wenn sie offen ist				*/
	if( AslBase )
		CloseLibrary( ( struct Library *)AslBase );
	/* GadTools.library schließen, wenn sie offen ist		*/
	if( GadToolsBase )
		CloseLibrary( ( struct Library *)GadToolsBase );
	/* Graphics.library schließen, wenn sie offen ist		*/
	if( GfxBase )
		CloseLibrary( ( struct Library *)GfxBase );
	/* Intuition.library schließen, wenn sie offen ist		*/
	if( IntuitionBase )
		CloseLibrary( ( struct Library *)IntuitionBase );
	return;
}

/* Unterprogramm zum Einlesen der Einstellungen				*/
void EinstLesen()
{
	/* Datei öffnen													*/
	BPTR is;
	is = Open(Einst_File,MODE_OLDFILE);
	/* Wenn das geklappt hat,										*/
	if(is)
	{
		/* lies die Einstellungen									*/
		Read(is, &P1, sizeof( P1 ));
		/* Schließ die Datei wieder								*/
		Close(is);
	}
}

/* Unterprogramm zum Schreiben der Einstellungen			*/
void EinstSchreiben()
{
	/* Datei öffnen													*/
	BPTR os;
	os = Open(Einst_File, MODE_NEWFILE);
	/* Wenn das geklappt hat,										*/
	if(os)
	{
		/* schreib die Einstellungen								*/
		Write(os, &P1, sizeof( P1 ));
		/* Schließ die Datei wieder								*/
		Close(os);
	}
}

/* Sortiert einen neuen Eintrag in die Liste ein.			*/
long NeuerEintrag(char *Eintrag)
{
	long Entries;
	long i;
	struct VDBnode *n;
	struct VDBnode *m;

	/* Anzahl der bereits existierenden Eintragungen		*/
	Entries = gt_GetListNumEntries( &vdblist );

	/* Schleife vom Ende bis zum Anfang der Liste			*/
	for( i = Entries-1; i >= 0; i--) 
	{
		/* Eintrag aus der Liste Holen							*/
		m = (struct VDBnode *) gt_GetListEntry( &vdblist, i );

		/* Der Eintrag ist bereits vorhanden -> ignorieren	*/
		if(strcmp(m->d.Name, Eintrag)==0)
			return i;

		/* Die richtige Stelle wurde gefunden -> Einfügen	*/
		if(strcmp(m->d.Name, Eintrag)<0)
		{
			/* Speicher alokieren									*/
			n = AllocVec( sizeof( *n ), MEMF_CLEAR );
			if( n )
			{
				/* die ganze Sache aufbereiten					*/
				strcpy(n->d.Name, Eintrag);
				n->n.ln_Name = n->d.Name;
				n->n.ln_Pri  = - n->d.Name[0];
				/* und dahinter anhängen							*/
				Insert( &vdblist, (struct Node *) n, (struct Node *) m );
			}
			/* Eingefügte Pos. = i+1, das geben wir zurück	*/
			return ++i;
		}
	}

	/* Kein kleinerer Eintrag gefunden?							*/
	n = AllocVec( sizeof( *n ), MEMF_CLEAR );
	if( n )
	{
		/* die ganze Sache aufbereiten							*/
		strcpy(n->d.Name, Eintrag);
		n->n.ln_Name = n->d.Name;
		n->n.ln_Pri  = - n->d.Name[0];
		/* dann setz ihn vorne dran								*/
		AddHead( &vdblist, (struct Node *) n );
	}
	/* Eingefügte Position = 0, das geben wir zurück		*/
	return 0;
}

/* Einen Eintrag aus der Liste entfernen						*/
void EintragLoeschen()
{
	long i;
	/* Wenn ein Eintrag ausgewählt ist							*/
	if(currentvdb)
	{
		/* Die Nummer des Eintrags bestimmen					*/
		i = gt_GetListEntryNum(&vdblist, (struct Node *) currentvdb);
		/* Ist diese > 0, wird der nächste Eintrag eins kl.*/
		if(i > 0)
			i--;
		/* Ansonsten 0 (der Beginn der Liste)					*/
		else
			i = 0;
		/* Liste abhängen												*/
		gt_AttachList( BestellenGadgets[ GD_Diskliste ], BestellenWnd, (struct List *) ~0 );
		/* Den Eintrag entfernen									*/
		Remove( (struct Node *) currentvdb );
		/* ebenso den passenden Vektor							*/
		FreeVec( currentvdb );
		/* Liste wieder anhängen									*/
		gt_AttachList( BestellenGadgets[ GD_Diskliste ], BestellenWnd, &vdblist );
		/* Neuer aktueller Eintrag (wenn Liste nicht leer)	*/
		if (IsListEmpty( &vdblist ))
		{
			currentvdb = NULL;
			/* Feld darunter löschen								*/
			gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, "");
		}
		else
		{
			currentvdb = (struct VDBnode *) gt_GetListEntry( &vdblist, i );
			/* Neuen aktuellen Eintag in der Liste auswählen*/
			gt_SetLV( BestellenGadgets[ GD_Diskliste ], BestellenWnd, i );
			/* und im Feld darunter anzeigen						*/
			gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, currentvdb->d.Name );
		}
		/* Wenn keiner mehr drinnen ist, Gad. abschalten	*/
		checkonoff();
	}
}

/* Unterprogramm zum Einlesen der Time-Diskettendaten		*/
void DatenLesen()
{
	FILE *is;
	char lespuf[16];

	/* Liste initialisieren											*/
	NewList( &vdblist );
	/* Bei Beginn noch keinen aktuellen Eintrag				*/
	currentvdb = NULL;

	/* Datei öffnen zum lesen (read -> "r")					*/
	is = fopen(T_Remember, "r");
	if(is)
	{
		/* Solange was in der Datei steckt, lesen				*/
		while(fgets(lespuf, 15, is))
		{
			/* und an die Liste dranhängen						*/
			NeuerEintrag(lespuf);
		}
		/* Hinterher die Datei wieder dicht machen			*/
		fclose(is);
	}
}

/* Unterprogramm zum Schreiben der Time-Diskettendaten	*/
void DatenSchreiben( struct List *l )
{
	int i = 0;
	struct Node *n = l->lh_Head;
	struct VDBnode *a;
	FILE *os;

	/* Datei zum Schreiben öffnen (write -> "w")				*/
	os = fopen(T_Remember, "w");
	/* Hat das öffnen hingehauen									*/
	if(os)
	{
		/* Die Liste von Anfang bis Schluß durchackern	*/
		while( n->ln_Succ )
		{
			n = n->ln_Succ;
			a = (struct VDBnode *) gt_GetListEntry( &vdblist, i );
			i++;
			/* Disknamen reinschreiben							*/
			fputs( a->d.Name, os );
			fputc( '\n', os);
		}
		/* Wenns öffnen geklappt hat, dann Datei schließ*/
		fclose(os);
	}
}

/* Die Bestellung auf eine Postkarte Drucken					*/
void Drucken( struct List *l )
{
	/* Einen Schreibpuffer für die aufbereiten der Zeilen	*/
	char Schreibpuf[1000];
	char Zeilenpuf[60];
	char i;
	struct VDBnode *a;
	struct Node *n = l->lh_Head;

	FILE *os;
	/* Requester vorbereiten										*/
	es.es_StructSize	= sizeof(struct EasyStruct);
	es.es_Flags			= 0;

	/* Datei zum drucken oder speichern öffnen				*/
	os = fopen("PRT:", "w");
	/* Hats geklappt?													*/
	if(os)
	{
		/* Requester zur Aufford. die Postkarte einzul.		*/
		es.es_Title			= AppStrings[MSG_DruReqTitel];
		es.es_TextFormat	= AppStrings[MSG_DruReqText1];
		es.es_GadgetFormat= AppStrings[MSG_DruReqWahl];

		/* Wenn er mit Drucken bestätigt wurde	i > 0			*/
		i = EasyRequest(BestellenWnd, &es, NULL);

		/* Falls i > 0 drucken/speichern							*/
		if(i)
		{
			strcpy(Schreibpuf, '\0');
			/* Die Leerzeilen zu Beginn einfügen				*/
			for( i = 0; i < P1.Abstand; i++)
			{
				strcat(Schreibpuf, "\n")
			}
			/* Die Zeile mit dem Absendernamen drucken und	*/
			strcat(Schreibpuf, "  ");
			strcat(Schreibpuf, P1.AName);
			strcat(Schreibpuf, "\n\n");
			/* Die Zeile mit der Kundennummer drucken und	*/
			strcat(Schreibpuf, AppStrings[MSG_DruText0]);
			strcat(Schreibpuf, P1.KundNr);
			strcat(Schreibpuf, "\n\n");
			/* Die Zeile mit der Absenderstraße drucken und	*/
			strcat(Schreibpuf, "  ");
			strcat(Schreibpuf, P1.AStrasse);
			strcat(Schreibpuf, "\n\n");
			/* Die Zeile mit dem Absenderort drucken und		*/
			strcat(Schreibpuf, "  ");
			strcat(Schreibpuf, P1.AOrt);
			strcat(Schreibpuf, "\n\n");
			/* Die Zeile mit dem Empfängernamen drucken und	*/
			strcat(Schreibpuf, "                             ");
			strcat(Schreibpuf, P1.EName);
			strcat(Schreibpuf, "\n\n\n\n");
			/* Die Zeile mit der Empf.straße drucken und		*/
			strcat(Schreibpuf, "                             ");
			strcat(Schreibpuf, P1.EStrasse);
			strcat(Schreibpuf, "\n\n\n\n");
			/* zuguterletzt den Empfängerort drucken und		*/
			strcat(Schreibpuf, "                             ");
			strcat(Schreibpuf, P1.EOrt);
			strcat(Schreibpuf, "\f");
			if (fputs( Schreibpuf, os ) == DOSTRUE)
			{
				/* Schreiben klappte nicht							*/
				es.es_Title			= AppStrings[MSG_ErrorReqTitel];
				es.es_TextFormat	= AppStrings[MSG_ErrorReqText1];
				es.es_GadgetFormat= AppStrings[MSG_ErrorReqWahl];

				EasyRequest(BestellenWnd, &es, NULL);
				os = NULL;
			}
		}
		/* und schließe die Datei wieder							*/
		fclose(os);
	}

	/* Datei zum drucken oder speichern öffnen				*/
	os = fopen("PRT:", "w");
	/* Hats geklappt?													*/
	if(os)
	{
		/* Die Aufforderung, die Postkarte umzudrehen		*/
		es.es_Title			= AppStrings[MSG_DruReqTitel];
		es.es_TextFormat	= AppStrings[MSG_DruReqText2];
		es.es_GadgetFormat= AppStrings[MSG_DruReqWahl];

		/* Wenn er mit Drucken bestätigt wurde					*/
		i = EasyRequest(BestellenWnd, &es, NULL);

		/* Wenn i > 0													*/
		if(i)
		{
			strcpy(Schreibpuf, '\0');
			/* Die Leerzeilen zu Beginn einfügen				*/
			for( i = 0; i < P1.Abstand; i++)
			{
				strcat(Schreibpuf, "\n")
			}
			/* Ein Text, der klar macht, was wir wollen		*/
			strcat(Schreibpuf, AppStrings[MSG_DruText1]);
			/* Nachschaun, welche Zahlungsart aktuell ist	*/
			switch( P1.Versart )
			{
				/* Nachnahme,											*/
				case 0:
					strcat(Schreibpuf, AppStrings[MSG_DruText2]);
					break;
				/* Vorkasse oder										*/
				case 1:
					strcat(Schreibpuf, AppStrings[MSG_DruText3]);
					break;
				/* gegen Rechnung										*/
				default:
					strcat(Schreibpuf, AppStrings[MSG_DruText4]);
					break;
			}
			strcpy(Zeilenpuf, "  ");
			i = 0;
			/* Nun zu den Disketten selbst						*/
			while( n->ln_Succ )
			{
				/* Zunächst holen wir mal die Diskbezeichn.,	*/
				n = n->ln_Succ;
				a = (struct VDBnode *) gt_GetListEntry( &vdblist, i );
				i++;
				/* schaun ob in der Zeile noch Platz ist,		*/
				if((strlen(a->d.Name) + strlen(Zeilenpuf)) > 52 )
				{
					/* wenn nicht, drucken wir die alte und	*/
					strcat( Schreibpuf, Zeilenpuf );
					strcat( Schreibpuf, "\n");
					/* beginnen eine neue							*/
					strcpy(Zeilenpuf, "  ");
				}
				/* nun können wir getrost die Diskettenbez.	*/
				strcat(Zeilenpuf, a->d.Name);
				/* gefolgt von einem Komma dranhängen			*/
				strcat(Zeilenpuf, ", ");
			}
			/* Da die letzte Zeile nicht gedruckt wurde,		*/
			/* holen wir das nach und								*/
			strcat( Schreibpuf, Zeilenpuf );
			/* hängen eine Leerzeile dran.						*/
			strcat( Schreibpuf, "\n\n" );
			/* In der Hoffnung das es auch wirklich flott	*/
			/* geht, danken wir dafür schon im Voraus,		*/
			strcat(Schreibpuf, AppStrings[MSG_DruText5]);
			if (fputs( Schreibpuf, os ) == DOSTRUE)
			{
				/* Schreiben klappte nicht							*/
				es.es_Title			= AppStrings[MSG_ErrorReqTitel];
				es.es_TextFormat	= AppStrings[MSG_ErrorReqText1];
				es.es_GadgetFormat= AppStrings[MSG_ErrorReqWahl];

				EasyRequest(BestellenWnd, &es, NULL);
			}
		}
		/* und schließen die Datei wieder						*/
		fclose(os);
	}
	/* Konnte die Datei jedoch nicht geöffnet werden,		*/
	else
	{
		/* wird der Benuter per Requester Informiert			*/
		es.es_Title			= AppStrings[MSG_ErrorReqTitel];
		es.es_TextFormat	= AppStrings[MSG_ErrorReqText2];
		es.es_GadgetFormat= AppStrings[MSG_ErrorReqWahl];

		EasyRequest(BestellenWnd, &es, NULL);
	}
}

/* Window mit den Voreingestellten Daten füllen				*/
void Winfuell()
{
	/* Daten in das ListView Gadget einbauen					*/
	gt_AttachList( BestellenGadgets[GD_Diskliste], BestellenWnd, &vdblist );

	/* Voreinstellungen einbauen									*/
	GT_SetGadgetAttrs( BestellenGadgets[ GD_Zahlart ], BestellenWnd, NULL, 
								GTMX_Active, P1.Versart,
								TAG_DONE);
	gt_SetString( BestellenGadgets[ GD_AName ], BestellenWnd, P1.AName );
	gt_SetString( BestellenGadgets[ GD_AStrasse ], BestellenWnd, P1.AStrasse);
	gt_SetString( BestellenGadgets[ GD_AOrt ], BestellenWnd, P1.AOrt);
	gt_SetString( BestellenGadgets[ GD_KundNr ], BestellenWnd, P1.KundNr );

	gt_SetString( BestellenGadgets[ GD_EName ], BestellenWnd, P1.EName );
	gt_SetString( BestellenGadgets[ GD_EStrasse ], BestellenWnd, P1.EStrasse);
	gt_SetString( BestellenGadgets[ GD_EOrt ], BestellenWnd, P1.EOrt);

	gt_SetInteger( BestellenGadgets[ GD_Abstand ], BestellenWnd, P1.Abstand);
	/* momentan nicht benötigte Gadgets sperren				*/
	checkonoff();
}

/* Wenn jemand versucht ein Gadget zu erdrücken				*/
BOOL Abfrage_Gadgetup( struct Gadget *gad, long code)
{
	char Merken[15];
	long i = 0;
	BOOL terminated = FALSE;	

	/* Wenn die Help-Taste der Grund fürs Beenden des G.	*/
	if(code==95)
	{
		/* Rufen wir die Rawkey-Abfrage auf (HELP-Behandl.)*/
		Abfrage_Rawkey(gad,code,gad);
		/* mehr gibts nicht zu tun, also ab nach Hause		*/
		return terminated;
	}

	/* mal sehen, auf welches G. der User es abgesehen hat*/
	switch( gad->GadgetID )
	{
		/* Jemand hat auf die Liste geklickt					*/
		case GD_Diskliste:
			/* dann gibts einen neuen aktuellen Eintrag		*/
			currentvdb = (struct VDBnode *) gt_GetListEntry( &vdblist, code );
			/* eventuell gesperrte Gadgets freigeben			*/
			checkonoff();
			/* Stringgadget unter der Liste füllen				*/
			gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, currentvdb->d.Name );
			/* und aktivieren											*/
			ActivateGadget( BestellenGadgets[GD_DiskAender], BestellenWnd, NULL );
			break;

		/* Jemand will ne neue Disk eingeben					*/
		case GD_NeueDisk:
			/* Dafür haben wir ein Unerprogramm					*/
			newvdb();
			break;

		/* Jemand will ne Disk löschen							*/
		case GD_DiskLoeschen:
			/* auch dafür gibts ein Unterprogramm				*/
			EintragLoeschen();
			break;
		/* Zahlart wurde geändert									*/
		case GD_Zahlart:
			/* einfach nur merken, das reicht schon			*/
			P1.Versart = code;
			break;
		/* Drucken														*/
		case GD_Drucken:
			/* Druckroutine aufrufen								*/
			Drucken(&vdblist);
			break;
		/* Abbrechen													*/
		case GD_Abbrechen:
			/* zurückgeben, daß der User keine Lust mer hat	*/
			terminated = TRUE;
			break;
		/* Absendername												*/
		case GD_AName:
			/* Einfach nur den neuen Namen merken				*/
			strcpy( P1.AName, gt_GetString( BestellenGadgets[ GD_AName ]) );
			break;
		/* Absenderstraße												*/
		case GD_AStrasse:
			/* Einfach nur die neue Straße merken				*/
			strcpy( P1.AStrasse, gt_GetString( BestellenGadgets[ GD_AStrasse ]) );
			break;
		/* Absenderort													*/
		case GD_AOrt:
			/* Einfach nur den Ort merken							*/
			strcpy( P1.AOrt, gt_GetString( BestellenGadgets[ GD_AOrt ]) );
			break;
		/* Kundennummer												*/
		case GD_KundNr:
			/* Einfach nur die Kundennummer merken				*/
			strcpy( P1.KundNr, gt_GetString( BestellenGadgets[ GD_KundNr ]) );
			break;
		/* Empfängername												*/
		case GD_EName:
			/* Einfach nur den Namen merken						*/
			strcpy( P1.EName, gt_GetString( BestellenGadgets[ GD_EName ]) );
			break;
		/* Empfängerstrasse											*/
		case GD_EStrasse:
			/* Einfach nur die Strasse merken					*/
			strcpy( P1.EStrasse, gt_GetString( BestellenGadgets[ GD_EStrasse ]) );
			break;
		/* Empfängerort												*/
		case GD_EOrt:
			/* Einfach nur den Ort merken							*/
			strcpy( P1.EOrt, gt_GetString( BestellenGadgets[ GD_EOrt ]) );
			break;
		/* Diskette neu angelegt oder alte ändern				*/
		case GD_DiskAender:
			/* Den neuen Namen Merken								*/
			strcpy(Merken, gt_GetString( BestellenGadgets[ GD_DiskAender ]) );
			/* Wenn er sich nicht geändert hat, ignorieren	*/
			if(strcmp(currentvdb->d.Name, Merken)==0) {}
			/* aber sonst												*/
			else
			{
				/* löschen wir den alten Eintrag					*/
				EintragLoeschen();
				/* Hängen die Liste ab								*/
				gt_AttachList( BestellenGadgets[GD_Diskliste], BestellenWnd, (struct List *) ~0 );
				/* den neuen Eintrag an (Position merken)		*/
				i = NeuerEintrag( Merken );
				/* hängen die Liste wieder dran					*/
				gt_AttachList( BestellenGadgets[GD_Diskliste], BestellenWnd, &vdblist );
				/* aktivieren den neuen Eintrag					*/
				gt_SetLV( BestellenGadgets[GD_Diskliste], BestellenWnd, i );
				/* merken ihn uns als aktuellen					*/
				currentvdb = (struct VDBnode *) gt_GetListEntry( &vdblist, i );
				/* schalten alle Gadgets an und					*/
				checkonoff();
				/* setzen den Namen ins Feld unter der Liste	*/
				gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, currentvdb->d.Name );
			}
			break;
		/* Abstand fürs Drucken										*/
		case GD_Abstand:
			/* Den Abstand einfach nur merken					*/
			P1.Abstand = gt_GetInteger( BestellenGadgets[ GD_Abstand ]);
			break;
		/* Dürfte nicht vorkommen, aber sicher ist sicher!	*/
		default:
			break;
	}
	/* Und ab nach Hause, mit Rückgabewert, ob Schluß ist	*/
	return(terminated);
}

/* Jemand hat das Menu benutzt									*/
BOOL Abfrage_Menuepick( UWORD code)
{
	/* Struktur für den Requester, falls wir ihn brauchen	*/
	char Verzeichnis[128];
	struct MenuItem *item;
	struct VDBnode *n;
	unsigned i;
	BOOL terminated = FALSE;
	item = ItemAddress(BestellenMenus, code);

	/* Nichts ausgewählt, dann zurück							*/
	if( !item )
		return terminated;

	/* mal schaun, was ausgewählt wurde							*/
	switch ( (int)MENU_USERDATA(item) )
	{
		/* Menupunkt Öffnen Adressen/Einstellungen			*/
		case MENU_FOO_OPA:
			/* Wenn die Asl.library geöffnet werden konnte	*/
			if( AslBase )
			{
				/* Verzeichnis ermitteln							*/
				i = (unsigned)((STRPTR)PathPart(Einst_File) - (STRPTR)Einst_File);
				strncpy(Verzeichnis,Einst_File,i);
				Verzeichnis[i] = 0;
				/* Öffne einen einfachen Filerequester			*/
				if (fr = ( struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
																						ASL_Dir, Verzeichnis,
																						ASL_File, FilePart(Einst_File),
																						TAG_DONE))
				{
					if(AslRequest(fr,NULL))
					{
						/* Der neue Filerequester setzt sich	*/
						/* aus Drawer und File zusammen.			*/
						strcpy(Einst_File, fr->fr_Drawer);
						strcat(Einst_File, fr->fr_File);
						/* Gut, schreibe die Bestellung			*/
						EinstLesen();
						/* Und auf den Bildschirm damit			*/
						Winfuell();
					}
					FreeAslRequest(fr);
				}
			}
			break;

		/* Menupunkt Öffnen Diskettenliste						*/
		case MENU_FOO_OPB:
			/* Wenn die Asl.library geöffnet werden konnte	*/
			if( AslBase )
			{
				/* Verzeichnis ermitteln							*/
				i = (unsigned)((STRPTR)PathPart(T_Remember) - (STRPTR)T_Remember);
				strncpy(Verzeichnis,T_Remember,i);
				Verzeichnis[i] = 0;
				/* Öffne einen einfachen Filerequester			*/
				if (fr = ( struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
																						ASL_Dir, Verzeichnis,
																						ASL_File, FilePart(T_Remember),
																						TAG_DONE))
				{
					if(AslRequest(fr,NULL))
					{
						/* Der neue Filerequester setzt sich	*/
						/* aus Drawer und File zusammen.			*/
						strcpy(T_Remember, fr->fr_Drawer);
						strcat(T_Remember, fr->fr_File);
						/* Liste abhängen								*/
						gt_AttachList( BestellenGadgets[ GD_Diskliste ], BestellenWnd, (struct List *) ~0 );
						/* Alte Liste löschen						*/
						while( ( n = (struct VDBnode *) RemHead( &vdblist ) ) )
						{
							FreeVec(n);
						}
						/* Gut, schreibe die Bestellung			*/
						DatenLesen();
						/* Liste wieder dranhängen					*/
						gt_AttachList( BestellenGadgets[ GD_Diskliste ], BestellenWnd, &vdblist );
						/* Bearbeitungsgadget löschen				*/
						gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, "");
						/* Gadgets ausblenden						*/
						checkonoff();
					}
					FreeAslRequest(fr);
				}
			}
			break;

		/* Menupunkt Speichern Adressen/Einstellungen		*/
		case MENU_FOO_SPA:
			EinstSchreiben();
			break;

		/* Menupunkt Speichern Diskettenliste					*/
		case MENU_FOO_SPB:
			DatenSchreiben(&vdblist);
			break;

		/* Menupunkt Speichern als ... Adressen/Einstell.	*/
		case MENU_FOO_SAA:
			/* Wenn die Asl.library geöffnet werden konnte	*/
			if( AslBase )
			{
				/* Verzeichnis ermitteln							*/
				i = (unsigned)((STRPTR)PathPart(Einst_File) - (STRPTR)Einst_File);
				strncpy(Verzeichnis,Einst_File,i);
				Verzeichnis[i] = 0;
				/* Öffne einen einfachen Filerequester			*/
				if (fr = ( struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
																						ASL_Dir, Verzeichnis,
																						ASL_File, FilePart(Einst_File),
																						TAG_DONE))
				{
					if(AslRequest(fr,NULL))
					{
						/* Der neue Filerequester setzt sich	*/
						/* aus Drawer und File zusammen.			*/
						strcpy(Einst_File, fr->fr_Drawer);
						strcat(Einst_File, fr->fr_File);
						EinstSchreiben();
					}
					FreeAslRequest(fr);
				}
			}
			break;

		/* Menupunkt Speichern als ... Diskettenliste		*/
		case MENU_FOO_SAB:
			/* Wenn die Asl.library geöffnet werden konnte	*/
			if( AslBase )
			{
				/* Verzeichnis ermitteln							*/
				i = (unsigned)((STRPTR)PathPart(T_Remember) - (STRPTR)T_Remember);
				strncpy(Verzeichnis,T_Remember,i);
				Verzeichnis[i] = 0;
				/* Öffne einen einfachen Filerequester			*/
				if (fr = ( struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
																						ASL_Dir, Verzeichnis,
																						ASL_File, FilePart(T_Remember),
																						TAG_DONE))
				{
					if(AslRequest(fr,NULL))
					{
						/* Der neue Filerequester setzt sich	*/
						/* aus Drawer und File zusammen.			*/
						strcpy(T_Remember, fr->fr_Drawer);
						strcat(T_Remember, fr->fr_File);
						DatenSchreiben( &vdblist );
					}
					FreeAslRequest(fr);
				}
			}
			break;

		/* Menupunkt Drucken											*/
		case MENU_FOO_DRU:
			/* Unterprogramm zum Drucken starten				*/
			Drucken(&vdblist);
			break;

		/* Menupunkt Information									*/
		case MENU_FOO_INF:
			/* Starten wir nen kleinen Inforequester			*/
			es.es_StructSize	= sizeof(struct EasyStruct);
			es.es_Flags			= 0;
			es.es_Title			= AppStrings[MSG_InfoReqTitel];
			es.es_TextFormat	= AppStrings[MSG_InfoReqText];
			es.es_GadgetFormat= AppStrings[MSG_InfoReqWahl];

			EasyRequest(BestellenWnd, &es, NULL);
			break;

		/* Menupunkt Verbergen										*/
		case MENU_FOO_HID:
			/* Fenster schließen										*/
			CloseBestellenWindow();
			break;

		/* Menupunkt Programm beenden								*/
		case MENU_FOO_END:
			/* gut, Rückgabewert auf Ende setzen				*/
			terminated = TRUE;
			break;

		/* Sollte nicht vorkommen									*/
		default:
			break;
	}
	/* Rückgabewert, ob der User weitermachen will			*/
	return(terminated);
}

/* Eine handelsübliche Taste wurde gedrückt					*/
BOOL Abfrage_Vanillakey( struct Gadget *gad, UWORD code)
{
	BOOL terminated = FALSE;

	/* Wollen wir doch mal sehen, welche da benutzt wurde	*/
	if ((code == AppStrings[MSG_GadgetKey1a][0]) ||
		(code == AppStrings[MSG_GadgetKey1b][0]))
		{
			/* ist ein Eintrag in der liste ausgewählt?		*/
			if( currentvdb )
				/* ja, dann aktiviere das Feld unter der Liste*/
				ActivateGadget( BestellenGadgets[GD_DiskAender], BestellenWnd, NULL );
			else if(gt_GetListNumEntries( &vdblist ) > 0)
			{
				/* nein, dann selektiere den ersten Eintrag	*/
				currentvdb = (struct VDBnode *) gt_GetListEntry(&vdblist, 0);
				gt_SetLV(BestellenGadgets[GD_Diskliste], BestellenWnd, gt_GetListEntryNum(&vdblist, (struct Node *) currentvdb));
				/* aktiviere alle Gadgets							*/
				checkonoff();
				/* und setz den Disknamen ins String-Gadget	*/
				gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, currentvdb->d.Name );
			}
		}

		/* Neuer Listeneintrag										*/
	else if ((code == AppStrings[MSG_GadgetKey2a][0]) ||
		(code == AppStrings[MSG_GadgetKey2b][0]))
		{
			/* dafür haben wir doch ein Unterprogramm			*/
			newvdb();
		}

		/* Jemand will nen Diskeintrag löschen					*/
	else if ((code == AppStrings[MSG_GadgetKey3a][0]) ||
		(code == AppStrings[MSG_GadgetKey3b][0]))
		{
			/* Nur wenn ein Eintrag aktiviert ist löschen	*/
			if( currentvdb )
				EintragLoeschen();
		}

		/* Drucken														*/
	else if ((code == AppStrings[MSG_GadgetKey5a][0]) ||
		(code == AppStrings[MSG_GadgetKey5b][0]))
		{
			/* Druckroutine starten									*/
			Drucken(&vdblist);
		}

		/* Abbrechen													*/
	else if ((code == AppStrings[MSG_GadgetKey6a][0]) ||
		(code == AppStrings[MSG_GadgetKey6b][0]))
		{
			/* Wenn er nimmer will, halten wir ihn nicht auf*/
			terminated = TRUE;
		}

		/* Absendername												*/
	else if ((code == AppStrings[MSG_GadgetKey7a][0]) ||
		(code == AppStrings[MSG_GadgetKey7b][0]))
		{
			ActivateGadget( BestellenGadgets[GD_AName], BestellenWnd, NULL );
		}

		/* Absenderstraße												*/
	else if ((code == AppStrings[MSG_GadgetKey8a][0]) ||
		(code == AppStrings[MSG_GadgetKey8b][0]))
		{
			ActivateGadget( BestellenGadgets[GD_AStrasse], BestellenWnd, NULL );
		}

		/* Absenderort													*/
	else if ((code == AppStrings[MSG_GadgetKey9a][0]) ||
		(code == AppStrings[MSG_GadgetKey9b][0]))
		{
			ActivateGadget( BestellenGadgets[GD_AOrt], BestellenWnd, NULL );
		}

		/* Kundennummer												*/
	else if ((code == AppStrings[MSG_GadgetKey10a][0]) ||
		(code == AppStrings[MSG_GadgetKey10b][0]))
		{
			ActivateGadget( BestellenGadgets[GD_KundNr], BestellenWnd, NULL );
		}

		/* Empfängername												*/
	else if ((code == AppStrings[MSG_GadgetKey11a][0]) ||
		(code == AppStrings[MSG_GadgetKey11b][0]))
		{
			ActivateGadget( BestellenGadgets[GD_EName], BestellenWnd, NULL );
		}

		/* Empfängerstraße											*/
	else if ((code == AppStrings[MSG_GadgetKey12a][0]) ||
		(code == AppStrings[MSG_GadgetKey12b][0]))
		{
			ActivateGadget( BestellenGadgets[GD_EStrasse], BestellenWnd, NULL );
		}

		/* Empfänger Postleitzahl/Ort								*/
	else if ((code == AppStrings[MSG_GadgetKey13a][0]) ||
		(code == AppStrings[MSG_GadgetKey13b][0]))
		{
			ActivateGadget( BestellenGadgets[GD_EOrt], BestellenWnd, NULL );
		}

		/* Leerzeilen vorm Ausdruck								*/
	else if ((code == AppStrings[MSG_GadgetKey15a][0]) ||
		(code == AppStrings[MSG_GadgetKey15b][0]))
		{
			ActivateGadget( BestellenGadgets[GD_Abstand], BestellenWnd, NULL );
		}

		/* Zahlungsart Nachnahme									*/
	else if ((code == AppStrings[MSG_VerKey1a][0]) ||
		(code == AppStrings[MSG_VerKey1b][0]))
		{
			P1.Versart = 0;
			GT_SetGadgetAttrs( BestellenGadgets[ GD_Zahlart ], BestellenWnd, NULL, 
										GTMX_Active, P1.Versart,
										TAG_DONE);
		}

		/* Zahlungsart Vorkasse										*/
	else if ((code == AppStrings[MSG_VerKey2a][0]) ||
		(code == AppStrings[MSG_VerKey2b][0]))
		{
			P1.Versart = 1;
			GT_SetGadgetAttrs( BestellenGadgets[ GD_Zahlart ], BestellenWnd, NULL, 
										GTMX_Active, P1.Versart,
										TAG_DONE);
		}

		/* Zahlungsart Rechnung										*/
	else if ((code == AppStrings[MSG_VerKey3a][0]) ||
		(code == AppStrings[MSG_VerKey3b][0]))
		{
			P1.Versart = 2;
			GT_SetGadgetAttrs( BestellenGadgets[ GD_Zahlart ], BestellenWnd, NULL, 
										GTMX_Active, P1.Versart,
										TAG_DONE);
		}

		/* andere Eingaben interressieren uns nicht			*/
	else
		{
		}
	/* und der der obligatorische Rückgabewert				*/
	return(terminated);
}

/* eine der Tasten die nix aufm Bildschirm hinterlassen	*/
void Abfrage_Rawkey( struct Gadget *gad, UWORD code, struct Gadget *gd)
{
	int i;

	/* Ein paar Sachen für einen AmigaGuide aufruf			*/
	struct NewAmigaGuide sync = {NULL};
	static UBYTE *AG_ID[] = {
		"GD_Diskliste",
		"GD_NeueDisk",
		"GD_DiskLoeschen",
		"GD_Zahlart",
		"GD_Drucken",
		"GD_Abbrechen",
		"GD_AName",
		"GD_AStrasse",
		"GD_AOrt",
		"GD_KundNr",
		"GD_EName",
		"GD_EStrasse",
		"GD_EOrt",
		"GD_DiskAender",
		"GD_Abstand",
	};

	AMIGAGUIDECONTEXT MyHandle;

	switch ( code )
	{
		/* Cursor hoch (Listview hoch)							*/
		case 76:
			/* sollte überhaupt ein Eintrag aktiv sein		*/
			if( currentvdb )
			{
				/* kucken wir, welche Nummer der hat			*/
				i = gt_GetListEntryNum( &vdblist, (struct Node *) currentvdb );
				/* senken die Nummer um 1 und						*/
				i--;
				/* sollten wir noch nicht ganz oben sein		*/
				if(i >= 0)
				{
					/* haben wir einen neuen aktuellen Eintr.	*/
					currentvdb = (struct VDBnode *) gt_GetListEntry(&vdblist, i);	
					gt_SetLV(BestellenGadgets[GD_Diskliste], BestellenWnd, gt_GetListEntryNum(&vdblist, (struct Node *) currentvdb));
					/* ab damit ins Feld unter der Liste		*/
					gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, currentvdb->d.Name );
				}
			}
			else if(gt_GetListNumEntries( &vdblist ) > 0)
			{
				/* nein, dann selektiere den ersten Eintrag	*/
				currentvdb = (struct VDBnode *) gt_GetListEntry(&vdblist, 0);
				gt_SetLV(BestellenGadgets[GD_Diskliste], BestellenWnd, gt_GetListEntryNum(&vdblist, (struct Node *) currentvdb));
				/* aktiviere alle Gadgets							*/
				checkonoff();
				/* und setz den Disknamen ins String-Gadget	*/
				gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, currentvdb->d.Name );
			}
			break;

		/* Cursor hoch (Listview hoch)							*/
		case 77:
			/* sollte überhaupt ein Eintrag aktiv sein		*/
			if( currentvdb )
			{
				/* kucken wir, welche Nummer der hat			*/
				i = gt_GetListEntryNum( &vdblist, (struct Node *) currentvdb );
				/* erhöhen die Nummer um 1 und					*/
				i++;
				/* sollten wir noch nicht ganz unten sein,	*/
				if(i < gt_GetListNumEntries( &vdblist ))
				{
					/* haben wir einen neuen aktuellen Eintr.	*/
					currentvdb = (struct VDBnode *) gt_GetListEntry(&vdblist, i);	
					/* ab damit ins Feld unter der Liste		*/
					gt_SetLV(BestellenGadgets[GD_Diskliste], BestellenWnd, gt_GetListEntryNum(&vdblist, (struct Node *) currentvdb));
					gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, currentvdb->d.Name );
				}
			}
			else if(gt_GetListNumEntries( &vdblist ) > 0)
			{
				/* nein, dann selektiere den ersten Eintrag	*/
				currentvdb = (struct VDBnode *) gt_GetListEntry(&vdblist, gt_GetListNumEntries( &vdblist )-1 );
				gt_SetLV(BestellenGadgets[GD_Diskliste], BestellenWnd, gt_GetListEntryNum(&vdblist, (struct Node *) currentvdb));
				/* aktiviere alle Gadgets							*/
				checkonoff();
				/* und setz den Disknamen ins String-Gadget	*/
				gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, currentvdb->d.Name );
			}
			break;

		/* Help-Taste gedrückt										*/
		case 95:
			/* Ist die AmigaGuide Library geöffnet + OS 3.x	*/
			if( AmigaGuideBase != NULL )
			{
				/* Legen wir die Guide-Datei fest				*/
				sync.nag_Name	= "T_Bestellen.guide";

				/* steht der Mauszeiger über keinem Gadget,	*/
				if(gd == NULL)
					/* den defaultmäßigen Node setzen			*/
					sync.nag_Node	= "Window";
				/* steht der Mauszeiger über einem Gadget,	*/
				else
					/* wird dar passende Node gesetzt			*/
					sync.nag_Node = AG_ID[gd->GadgetID];

				/* Gut, öffnen wir die Guide Datei				*/
				MyHandle = OpenAmigaGuide( &sync, NULL );

				/* und schließen sie, wenn's öffnen klappte	*/
				if(MyHandle)
					CloseAmigaGuide( MyHandle);

			}
			/* Ist die AmigaGuide Library nicht zu öffnen,	*/
			else
			{
				/* gibts ne Message, daß ohne AmigaGuide nix	*/
				/* los ist mit der OnlineHilfe					*/
				es.es_StructSize	= sizeof(struct EasyStruct);
				es.es_Flags			= 0;
				es.es_Title			= AppStrings[MSG_ErrorReqTitel];
				es.es_TextFormat	= AppStrings[MSG_ErrorReqText3];
				es.es_GadgetFormat= AppStrings[MSG_ErrorReqWahl];

				EasyRequest(BestellenWnd, &es, NULL);
			}
			break;

		/* Sonstige Tasten jucken mich derzeit nicht			*/
		default:
			break;
	}
}

/* eine der Tasten die nix aufm Bildschirm hinterlassen	*/
void Abfrage_Menuhelp( UWORD code)
{
	/* Ein paar Sachen für einen AmigaGuide aufruf			*/
	struct NewAmigaGuide sync = {NULL};

	AMIGAGUIDECONTEXT MyHandle;

	/* Ist die AmigaGuide Library geöffnet + OS 3.x			*/
	if( AmigaGuideBase != NULL )
	{
		/* Legen wir die Guide-Datei fest						*/
		sync.nag_Name	= "T_Bestellen.guide";

		/* steht der Mauszeiger über einem Menüpunkt?		*/
		switch(code)
		{
			/* HELP beim Menü-Punkt Öffnen Adressen			*/
			case 0:
				sync.nag_Node	= "Menu_OPA";
				break;
			/* HELP beim Menü-Punkt Öffnen Diskliste			*/
			case 2048:
				sync.nag_Node	= "Menu_OPB";
				break;
			/* HELP beim Menü-Punkt Speichern Adressen		*/
			case 32:
				sync.nag_Node	= "Menu_SPA";
				break;
			/* HELP beim Menü-Punkt Speichern Diskliste		*/
			case 2080:
				sync.nag_Node	= "Menu_SPB";
				break;
			/* HELP beim Menü-Punkt Speichern als ... Adres.*/
			case 64:
				sync.nag_Node	= "Menu_SAA";
				break;
			/* HELP beim Menü-Punkt Speichern als... Diskl.	*/
			case 2112:
				sync.nag_Node	= "Menu_SAB";
				break;
			/* HELP beim Menü-Punkt Drucken						*/
			case 63584:
				sync.nag_Node	= "Menu_Dru";
				break;
			/* HELP beim Menü-Punkt Über T_Bestellen ...		*/
			case 63648:
				sync.nag_Node	= "Menu_Inf";
				break;
			/* HELP beim Menü-Punkt Speichern Adressen		*/
			case 63712:
				sync.nag_Node	= "Menu_HID";
				break;
			/* HELP beim Menü-Punkt Beenden						*/
			case 63744:
				sync.nag_Node	= "Menu_End";
				break;
			/* HELP außerhalb des Menüs, oder über Trennb.	*/
			default:
				sync.nag_Node	= "Window";
				break;
		}

		/* Gut, öffnen wir die Guide Datei						*/
		MyHandle = OpenAmigaGuide( &sync, NULL );

		/* und schließen sie, wenn's öffnen klappte			*/
		if(MyHandle)
			CloseAmigaGuide( MyHandle);

	}
	/* Ist die AmigaGuide Library nicht zu öffnen,			*/
	else
	{
		/* gibts ne Message, daß ohne AmigaGuide nix			*/
		/* los ist mit der OnlineHilfe							*/
		es.es_StructSize	= sizeof(struct EasyStruct);
		es.es_Flags			= 0;
		es.es_Title			= AppStrings[MSG_ErrorReqTitel];
		es.es_TextFormat	= AppStrings[MSG_ErrorReqText3];
		es.es_GadgetFormat= AppStrings[MSG_ErrorReqWahl];

		EasyRequest(BestellenWnd, &es, NULL);
	}
}

/* Verarbeiten der Commodity-Botschaften						*/
BOOL Cx_Message( CxMsg *msg )
{
	ULONG msgid, msgtype;
	BOOL terminated = FALSE;
	/* Message ID ermitteln											*/
	msgid = CxMsgID(msg);
	/* Ebenso den Typ													*/
	msgtype = CxMsgType(msg);
	/* Eine Botschaft sollte auch beantwortet werden		*/
	ReplyMsg((struct Message *)msg);
	/* Messagetyp auswerten											*/
	switch(msgtype)
	{
		/* Benutzerdefinierte Ereignisse							*/
		case CXM_IEVENT:
			switch( msgid )
			{
				/* HotKey wurde betätigt							*/
				case EVT_HOTKEY:
					if( CX_Popup )
						WindowToFront( BestellenWnd );
					else
					{
						OpenBestellenWindow();
						Winfuell();
						if( currentvdb )
						{
							gt_SetLV(BestellenGadgets[GD_Diskliste], BestellenWnd, ListPos);
							gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, currentvdb->d.Name );
						}
					}
					break;
				/* eigentlich wird sonst niemand erwartet		*/
				default:
					break;
			}
			break;
		/* Kommando, bekannt aus Exchange						*/
		case CXM_COMMAND:
			switch( msgid )
			{
				/* Commodity schlafen schicken					*/
				case CXCMD_DISABLE:
					ActivateCxObj(broker, 0L);
					break;
				/* und wieder aufwecken								*/
				case CXCMD_ENABLE:
					ActivateCxObj(broker, 1L);
					break;
				/* Keine Lust mehr? Beendet das Programm		*/
				case CXCMD_KILL:
					terminated = TRUE;
					break;
				/* Programm wurde nochmal gestartet				*/
				/* Fenster öffnen										*/
				case CXCMD_UNIQUE:
				case CXCMD_APPEAR:
					if( CX_Popup )
						WindowToFront( BestellenWnd );
					else
					{
						OpenBestellenWindow();
						Winfuell();
						if( currentvdb )
						{
							gt_SetLV(BestellenGadgets[GD_Diskliste], BestellenWnd, ListPos);
							gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, currentvdb->d.Name );
						}
					}
					break;
				/* Fenster verbergen									*/
				case CXCMD_DISAPPEAR:
					if( CX_Popup )
						CloseBestellenWindow();
					break;
				default:
					break;
			}
			break;
		default:
			break;
	}
	return terminated;
}


/* Lokalisierte Texte einlesen (wenn vorhanden)				*/
void LocaleLesen()
{
	if (LocaleBase) {
		struct	Catalog	*catalog = OpenCatalog (NULL,"T_Bestellen.catalog",OC_BuiltInLanguage,MSG_Language,TAG_DONE) ;
		if (catalog) {
			UBYTE	n ;
			for (n=0 ; n<=MSG_Max ; n++)
				AppStrings[n] = GetCatalogStr (catalog,n,AppStrings[n]) ;
			CloseCatalog (catalog) ;
		}
	}
	/* Hotkey-Vermerk an den Fenstertitel anhängen			*/
	strcpy(WinTitel, AppStrings[MSG_WindowName]);
	strcat(WinTitel, CX_Popkey);
	strcat(WinTitel, ">");

	/* MenuTexte übernehmen											*/
	BestellenNewMenu[0].nm_Label = AppStrings[MSG_MenuText1];
	BestellenNewMenu[1].nm_Label = AppStrings[MSG_MenuText2];
	BestellenNewMenu[2].nm_Label = AppStrings[MSG_MenuText2a];
	BestellenNewMenu[3].nm_Label = AppStrings[MSG_MenuText2b];
	BestellenNewMenu[4].nm_Label = AppStrings[MSG_MenuText3];
	BestellenNewMenu[5].nm_Label = AppStrings[MSG_MenuText2a];
	BestellenNewMenu[6].nm_Label = AppStrings[MSG_MenuText2b];
	BestellenNewMenu[7].nm_Label = AppStrings[MSG_MenuText4];
	BestellenNewMenu[8].nm_Label = AppStrings[MSG_MenuText2a];
	BestellenNewMenu[9].nm_Label = AppStrings[MSG_MenuText2b];
	BestellenNewMenu[10].nm_Label = AppStrings[MSG_MenuText5];
	BestellenNewMenu[12].nm_Label = AppStrings[MSG_MenuText6];
	BestellenNewMenu[14].nm_Label = AppStrings[MSG_MenuText7];
	BestellenNewMenu[15].nm_Label = AppStrings[MSG_MenuText8];

	/* Menu-ShortCuts übernehmen									*/
	BestellenNewMenu[2].nm_CommKey = AppStrings[MSG_MenuKey2];
	BestellenNewMenu[3].nm_CommKey = AppStrings[MSG_MenuKey2b];
	BestellenNewMenu[5].nm_CommKey = AppStrings[MSG_MenuKey3];
	BestellenNewMenu[6].nm_CommKey = AppStrings[MSG_MenuKey3b];
	BestellenNewMenu[8].nm_CommKey = AppStrings[MSG_MenuKey4];
	BestellenNewMenu[9].nm_CommKey = AppStrings[MSG_MenuKey4b];
	BestellenNewMenu[10].nm_CommKey = AppStrings[MSG_MenuKey5];
	BestellenNewMenu[12].nm_CommKey = AppStrings[MSG_MenuKey6];
	BestellenNewMenu[14].nm_CommKey = AppStrings[MSG_MenuKey7];
	BestellenNewMenu[15].nm_CommKey = AppStrings[MSG_MenuKey8];

	/* Gadget-Texte übernehmen										*/
	BestellenNGad[0].ng_GadgetText = AppStrings[MSG_GadgetText1];
	BestellenNGad[1].ng_GadgetText = AppStrings[MSG_GadgetText2];
	BestellenNGad[2].ng_GadgetText = AppStrings[MSG_GadgetText3];
	BestellenNGad[4].ng_GadgetText = AppStrings[MSG_GadgetText5];
	BestellenNGad[5].ng_GadgetText = AppStrings[MSG_GadgetText6];
	BestellenNGad[6].ng_GadgetText = AppStrings[MSG_GadgetText7];
	BestellenNGad[7].ng_GadgetText = AppStrings[MSG_GadgetText8];
	BestellenNGad[8].ng_GadgetText = AppStrings[MSG_GadgetText9];
	BestellenNGad[9].ng_GadgetText = AppStrings[MSG_GadgetText10];
	BestellenNGad[10].ng_GadgetText = AppStrings[MSG_GadgetText11];
	BestellenNGad[11].ng_GadgetText = AppStrings[MSG_GadgetText12];
	BestellenNGad[12].ng_GadgetText = AppStrings[MSG_GadgetText13];
	BestellenNGad[14].ng_GadgetText = AppStrings[MSG_GadgetText15];

	/* IText (Infotexte auf dem Screen)							*/
	BestellenIText[0].IText = AppStrings[MSG_IText1];
	BestellenIText[1].IText = AppStrings[MSG_IText2];

	/* MX-Gadget (Versandarten-Gadget)							*/
	Gadget300Labels[0] = AppStrings[MSG_Versandart1];
	Gadget300Labels[1] = AppStrings[MSG_Versandart2];
	Gadget300Labels[2] = AppStrings[MSG_Versandart3];
}

/* IconToolTypes einlesen											*/
void ToolTypesLesen(char *name)
{
	struct DiskObject		*diskobj;
	char *s;

	/* Icon.library geöffnet?										*/
	if ( IconBase )
	{
		diskobj = GetDiskObject( name );
		if (diskobj)
		{
			if (s = FindToolType((STRPTR *)diskobj->do_ToolTypes,"POSX"))
				WinX = atoi(s);
			if (s = FindToolType((STRPTR *)diskobj->do_ToolTypes,"POSY"))
				WinY = atoi(s);
			if (s = FindToolType((STRPTR *)diskobj->do_ToolTypes,"DISKFILE"))
				strcpy(T_Remember, s);
			if (s = FindToolType((STRPTR *)diskobj->do_ToolTypes,"ADDRFILE"))
				strcpy(Einst_File, s);
			if (s = FindToolType((STRPTR *)diskobj->do_ToolTypes,"CX_PRIORITY"))
				CX_Priority = atoi(s);
			if (s = FindToolType((STRPTR *)diskobj->do_ToolTypes,"CX_POPUP"))
				if(MatchToolValue(s,"NO"))
					CX_Popup = FALSE;
			if (s = FindToolType((STRPTR *)diskobj->do_ToolTypes,"CX_POPKEY"))
				strcpy(CX_Popkey, s);
			FreeDiskObject (diskobj);
		}		
	}
}

/* Einrichten des Programms als Commodity						*/
void StartCom()
{
	translate = NULL;
	if ( CxBase )
	{
		/* NewBroker Structur füllen:								*/
		/* Version der NewBroker strukt. (immer NB_Version)*/
		newbroker.nb_Version = NB_VERSION;
		/* Programmname, erscheint dann in der Exchange-L.	*/
		newbroker.nb_Name = (char *)AppStrings[MSG_MXName];
		/* Programmbezeich., erste Zeile Exchange B.			*/
		newbroker.nb_Title = (char *)AppStrings[MSG_MXInfoName];
		/* Programmbeschreibung, zweite Zeile Exchange B.	*/
		newbroker.nb_Descr = (char *)AppStrings[MSG_MXInfoText];
		/* Doppelten Start des PGMs verhindern und			*/
		/* Nachricht an das Laufende Programm, beim Versuch*/
		newbroker.nb_Unique = NBU_UNIQUE | NBU_NOTIFY;
		/* Fenster ist vorhanden!									*/
		newbroker.nb_Flags = COF_SHOW_HIDE;
		/* Priorität des Commodities (per ToolType wählb.)	*/
		newbroker.nb_Pri = CX_Priority;
		/* MsgPort, der muß aber erst eingerichtet werden	*/
		newbroker.nb_Port = CreateMsgPort();
		/* Der Rest ist für künftige Funktionen reserviert	*/
		newbroker.nb_ReservedChannel = NULL;

		/* Broker an Commodity-Lib zur Anmeldung übergeben	*/
		if( broker = CxBroker(&newbroker,NULL) )
		{
			/* Hotkey zu Filterobjekt verarbeiten				*/
			if (filter = CxFilter(CX_Popkey))
			{
				/* HotKey Filter an broker anhängen				*/
				AttachCxObj(broker, filter);
				if (sender = CxSender(newbroker.nb_Port, EVT_HOTKEY))
				{
					AttachCxObj(filter,sender);
					if (translate = CxTranslate(NULL))
					{
						AttachCxObj(filter,translate);
						if(!CxObjError(filter))
						{
							/* Broker aktivieren						*/
							ActivateCxObj(broker, 1L);
							/* Signal-Bit merken, für Abfrage	*/
							cxsigflag = 1L << newbroker.nb_Port->mp_SigBit;
						}
					}
				}
			}
		}
	}
}

/* Einrichten der Notify-Struktur								*/
void NotifyStarten()
{
	if(nr = (struct NotifyRequest*)AllocVec
	(sizeof(struct NotifyRequest),MEMF_PUBLIC|MEMF_CLEAR))
	{
		if(nmp = CreateMsgPort())
		{
			nr->nr_Name		= T_Remember;
			nr->nr_Flags	= NRF_SEND_MESSAGE | NRF_WAIT_REPLY | NRF_NOTIFY_INITIAL;
			nr->nr_stuff.nr_Msg.nr_Port = nmp;

			StartNotify(nr);
		}
	}
}

/* Hauptprogramm														*/
int main( int argc, char *argv[] )
{
	/* Hatt das öffnen der Libraries hingehauen?				*/
	if( OpenAll() == TRUE )
	{
		struct	VDBnode	*n;
		struct	IntuiMessage	*imsg;
		struct	Gadget	*gad;
		struct	Gadget	*gd = NULL;
		ULONG		imsgClass;
		UWORD		imsgCode;
		BOOL		Done	= FALSE;
		CxMsg		*msg;

		/* Einlesen der ToolTypes (für Benutzereinstell.)	*/
		/* In argv[0] steht übrigens der Programmname		*/
		ToolTypesLesen(argv[0]);

		/* Einlesen der Locale-Daten (für andere Sprachen)	*/
		LocaleLesen();

		/* Als Commodity einrichten								*/
		StartCom();
		if (!translate)
			exit(0);

		/* Einstellungen lesen										*/
		EinstLesen();

		/* Daten lesen													*/
		DatenLesen();

		/* Notify einrichten und starten							*/
		NotifyStarten();

		/* Bildschirm vorbereiten									*/
		SetupScreen();
		/* Fenster öffnen, wenn per ToolTypes so gewählt	*/
		if ( CX_Popup )
		{
			OpenBestellenWindow();
			/* Window mit Voreinstellungen füllen				*/
			Winfuell();
		}

		/* Hauptschleife												*/
		while( !Done )
		{
			/* Auf IntuiMassage warten								*/
			Wait( cxsigflag | wndsigflag | 1L << nmp->mp_SigBit );

			/* und Auswerten (Commodity)							*/
			if (cxsigflag)
			{
				while(msg = (CxMsg *)GetMsg(newbroker.nb_Port))
				{
					Done = Cx_Message(msg);
				}
			}

			/* Auswertung von Disk-Dateiveränderungen:		*/
			if( 1L << nmp->mp_SigBit )
			{
				while( nm = (struct NotifyMessage*)GetMsg(nmp))
				{
					switch(nm->nm_Class)
					{
						case NOTIFY_CLASS:
							/* Liste abhängen							*/
							if( CX_Popup )
								gt_AttachList( BestellenGadgets[ GD_Diskliste ], BestellenWnd, (struct List *) ~0 );
							/* Alte Liste löschen					*/
							while( ( n = (struct VDBnode *) RemHead( &vdblist ) ) )
							{
								FreeVec(n);
							}
							/* Gut, schreibe die Bestellung		*/
							DatenLesen();
							/* Liste wieder dranhängen				*/
							if( CX_Popup )
							{
								gt_AttachList( BestellenGadgets[ GD_Diskliste ], BestellenWnd, &vdblist );
								/* Bearbeitungsgadget löschen		*/
								gt_SetString( BestellenGadgets[GD_DiskAender], BestellenWnd, "");
								/* Gadgets ausblenden				*/
								checkonoff();
							}
							break;
						default:
							break;
					}
					ReplyMsg(&nm->nm_ExecMessage);
				}
			}

			/* Nachricht vom Fenster								*/ 
			while((CX_Popup) && (imsg = GT_GetIMsg(BestellenWnd->UserPort)))
			{
				imsgClass		= imsg->Class;
				imsgCode			= imsg->Code;
				gad = (struct Gadget *)imsg->IAddress;

				/* Jede empfangen Nachricht bestätigen			*/
				GT_ReplyIMsg(imsg);

				switch( imsgClass )
				{
					/* Windowschließsymbol gedrückt				*/
					case IDCMP_CLOSEWINDOW:
						CloseBestellenWindow();
						break;

					/* Gadget gedrückt								*/
					case IDCMP_GADGETUP:
					case IDCMP_GADGETDOWN:
						Done = Abfrage_Gadgetup(gad, imsgCode);
						break;

					/* Menupunkt ausgewählt							*/
					case IDCMP_MENUPICK:
						Done = Abfrage_Menuepick(imsgCode);
						break;

					/* gewähnliche Taste gedrückt					*/
					case IDCMP_VANILLAKEY:
						Done = Abfrage_Vanillakey( gad, imsgCode);
						break;

					/* Mauszeiger ruht kurze Zeit über			*/
					/* einem Gadget => Gadget merken				*/
					case IDCMP_GADGETHELP:
						if( imsg->IAddress == (APTR) BestellenWnd ) 
							gd = NULL;
						else
							gd = gad;
						break;

					/* Während der Menüauswahl wurde die		*/
					/* Help-Taste gedrückt							*/
					case IDCMP_MENUHELP:
						Abfrage_Menuhelp( imsgCode);
						break;

					/* Steuertaste gedrückt							*/
					case IDCMP_RAWKEY:
						Abfrage_Rawkey(gad,imsgCode,gd);
						break;

					/* Irgend was anderes, ignorieren			*/
					default:
						break;
				}
			}
		}

		/* Fenster und Bilschirm schließen						*/
		CloseBestellenWindow();
		CloseDownScreen();

		/* Notifycation wieder beenden							*/
		if( nr )
			EndNotify(nr);

		/* Messageport wieder dicht machen						*/
		if( nmp )
			DeleteMsgPort(nmp);

		/* Vector auch wieder freigeben							*/
		FreeVec(nr);

		/* Einstellungen speichern									*/
		EinstSchreiben();

		/* Daten speichern und freigeben							*/
		DatenSchreiben(&vdblist);
		while( ( n = (struct VDBnode *) RemHead( &vdblist ) ) )
		{
			FreeVec(n);
		}
		/* Als Commodity abmelden									*/
		if ( broker )
			DeleteCxObj( broker );
		/* Noch übrige Meldungen abarbeiten						*/
		while(msg = (CxMsg *)GetMsg(newbroker.nb_Port))
			ReplyMsg((struct Message *)msg);
		/* Commodity-Port freigeben								*/
		if (newbroker.nb_Port)
			DeletePort(newbroker.nb_Port);
	}
	/* Die Librareis konnten nicht (alle) geöffnet werden	*/
	else
	{
		/* Nachricht an den User, daß da was nicht stimmt	*/
		printf(AppStrings[MSG_OSError]);
	}
	/* geöffnete Libraries wieder schließen					*/
	CloseAll();

	/* 0 zurückgeben = alles glattgelaufen						*/
	return(0);
}
