amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Designfrage [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

01.06.2005, 15:39 Uhr

Reth
Posts: 1858
Nutzer
Hallo mal wieder,

hier mal ein Problem, das sich mir häufiger stellt und nicht nur Geschackssache ist.

Ich habe mir gerade 4 Kleine Klassen in C++ geschrieben, welche für ein einfaches Öffnen und Schließen für Screens und Windows verwendet werden können.

Dabei werden sämtliche Attribute, welche in den enstprechenden Strukturen Verwendung finden (WA_... bzw. SA_...) über getter/setter Methoden gesetzt.

Das Ganze ist nun ziemlich starr, entbindet den verwendenden Entwickler jedoch von der Kenntnis der Syntax der WA_... bzw. SA_... Attribute.
Er muss nur noch setWidth(), setHeight() etc. mit den entsprechenden Werten rufen (oder eine Variable der Klasse anlegen und diese der Fenster- bzw. Screenklasse übergeben, wenn er mit den Defaultwerten leben kann).

Die Alternative stelle ich mir als eine HashMap vor, in der unter den Schlüsseln WA_... bzw. SA_... die jeweiligen Werte eingetragen werden müssen. Diese Map wird dann an die entsprechende Open-Methode für Fenster oder Screen übergeben und aus ihnen werden dann die entsprechenden Werte übernommen.

Was meint ihr dazu? Oder ist ein ganz anderer Ansatz empfehlenswerter?

[ - Antworten - Zitieren - Direktlink - ]

01.06.2005, 16:09 Uhr

thomas
Posts: 7717
Nutzer

Abgesehen davon, daß ich dir keine Antwort auf deine eigentliche Frage stellen kann, wüßte ich gerne mal, was genau du mit "Syntax der Attribute" meinst. Wo ist der Unterschied zwischen bildschirm.setWidth(640) und bildschirm.setAttr(SA_Width,640) oder so ? Ob du nun set oder SA_ davor schreibst, das Attribut heist immer noch Width. Man muß höchstens zweimal nachschlagen, nämlich einmal bei Intuition, wie z.B. LikeWorkbench gemacht wird und dann in deiner Doku, wie es denn bei dir heißt.

Vielleicht solltest du dir überlegen, deine HashMap intern zu speichern und dem Programmierer erlauben, dir Tag-Listen zu übergeben.

z.B. so:

{
Bildschirm bs;
Fenster fr;

bs.setAttr(WA_Width,640,WA_Height,480,WA_Depth,8,TAG_END);
bs.open();

fr.setAttr(WA_CustomScreen,bs.GetScreenPtr(),TAG_END);
fr.open();

// und so weiter

fr.close();
bs.close(); // eigentlich unnötig, das sollte der Destruktor automatisch machen.
}

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

01.06.2005, 16:39 Uhr

Reth
Posts: 1858
Nutzer
Hi Thomas,

Zitat:
Original von thomas:

Wo ist der Unterschied zwischen bildschirm.setWidth(640) und bildschirm.setAttr(SA_Width,640) oder so ?


Als verwendender Entwickler muss ich nicht mehr wissen, was es alles für SA_-Attribute gibt. Ich sehe den Umfang der angebotenen Methoden und entscheide welche Werte ich ihnen gebe (z.B. für AutoScroll, Overscan, etc.).
Die Klassen mit den Gettern/Settern hab ich so angelegt, dass man sie nach einer Instanziierung direkt verwenden kann, ohne irgendwelche Werte eintragen zu müssen (dann werden Voreinstellungen genommen).

Zitat:
Vielleicht solltest du dir überlegen, deine HashMap intern zu speichern und dem Programmierer erlauben, dir Tag-Listen zu übergeben.

Von den Tag-Listen etc. wollte ich ja gerade wegkommen, da ich momentan selber merke, wie oft ich nachschlagen muss, um zu wissen, welche SA_- und WA_-Attribute es alles gibt und was sie tun.
Das umgehe ich mit dem starren Gebilde aus Gettern und Settern. Wenn sich der Umfang der Attribute aber irgendwann mal ändern sollte (AOS4? oder läufts dort ganz anders?), dann muss man die Implementierung anpassen.
Wenn man ne HashMap übergibt, muss der verwendende Programmierer die WA_- bzw. SA_-Attribute wieder kennen, aber kann beliebige eintragen (wobei man bei einer Erweiterung des Umfanges die Auswertungslogik der HashMap ja auch anpassen muss).

Denke daher, dass ich ersteinmal bei den Gettern/Settern bleibe.

Zitat:
fr.close();
bs.close(); // eigentlich unnötig, das sollte der Destruktor automatisch machen.


Wird er auch prüfen, aber man sollte m.M. nach die explizite Schließmöglichkeit auch erlauben.

[ - Antworten - Zitieren - Direktlink - ]

01.06.2005, 16:41 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von thomas:
Abgesehen davon, daß ich dir keine Antwort auf deine eigentliche Frage stellen kann, wüßte ich gerne mal, was genau du mit "Syntax der Attribute" meinst. Wo ist der Unterschied zwischen bildschirm.setWidth(640) und bildschirm.setAttr(SA_Width,640) oder so ?

Der Unterschied liegt darin, daß man einer Methode mit der Signatur setWidth(int) keinen pointer oder boolean übergeben kann, zumindest nicht ohne Warnung. In C++ sollte es IMHO gar nicht gehen.
Die in der Programmiersprache eingebauten Schutzmechanismen einzusetzen ist der offensichtliche Vorteil dieser Vorgehensweise. Keine neuen, der Klasse unbekannten Attribute benutzen zu können, ist der offensichtliche Nachteil.

Ein anderer Ansatz, der der beide Vorteile miteinander verbindet, besteht darin, die Attribute selber ebenfalls in Klassen zu verpacken, die ihrerseits erweiterbar sind, aber trotzdem typsichere Methoden der Komponentenklassen ermöglichen.
Der damit verbundene Nachteil ist, daß ermal alles viel komplizierter wird und man schon eine ziemlich große Klassenbibliothek entwickeln muß, bis sich das relativiert, bzw. die Vorteile überwiegen.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

01.06.2005, 18:00 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Reth:
Als verwendender Entwickler muss ich nicht mehr wissen, was es alles für SA_-Attribute gibt. Ich sehe den Umfang der angebotenen Methoden und entscheide welche Werte ich ihnen gebe (z.B. für AutoScroll, Overscan, etc.).

Das kann ich nicht nachvollziehen. In beiden Fällen mußt Du eine Dokumentation konsultieren. In dem einen Fall ist es die Dokumentation einer Klasse, im anderen Fall die der vordefinierten Konstanten.
Natürlich ist es bei einer Klasse leichter, den Bezug von der Methode zu den möglichen Werten herzustellen, insb. in Verbindung mit assistierenden Entwicklungstools, aber das sollte nicht allein den Ausschlag geben. Insbesondere wenn Du durch Verlagerung der Konstanten aus den #define's der OS-includes in statische member Deiner Klassen das gleiche erreichen kannst.

Interessant wird's allerdings, wenn man den Klassen ein wenig Hierarchie verpaßt. Wenn man einem Screen, Window oder Gadget mit der gleichen set-Methode eine Größe verpassen kann, hat das durchaus seine Vorteile. Und reduziert auch den Nachschlage- und Lernaufwand, wenn man es konsequent auf alle Attribute anwendet.
Warum der Programmierer einmal SA_Width, dann WA_Width und dann wieder GA_Width benutzen muß, ist wohl kaum befriedigend zu erklären...

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ Dieser Beitrag wurde von Holger am 01.06.2005 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

01.06.2005, 20:32 Uhr

Reth
Posts: 1858
Nutzer
Hi Holger,

Zitat:
Original von Holger:

Das kann ich nicht nachvollziehen. In beiden Fällen mußt Du eine Dokumentation konsultieren. In dem einen Fall ist es die Dokumentation einer Klasse, im anderen Fall die der vordefinierten Konstanten.
Natürlich ist es bei einer Klasse leichter, den Bezug von der Methode zu den möglichen Werten herzustellen, insb. in Verbindung mit assistierenden Entwicklungstools, aber das sollte nicht allein den Ausschlag geben.


Naja, durch ne entsprechende Namensgebung muss man kaum noch Doku konsultieren. Wenn man da z.B. an das API-Doc von Java denkt.

Zitat:
Insbesondere wenn Du durch Verlagerung der Konstanten aus den #define's der OS-includes in statische member Deiner Klassen das gleiche erreichen kannst.

Das kann ich nun wiederum nicht nachvollziehen. Was gewinnt man damit (kann mir das Ganze wie Du es meinst gerad nicht so recht vorstellen)?

Zitat:
Interessant wird's allerdings, wenn man den Klassen ein wenig Hierarchie verpaßt. Wenn man einem Screen, Window oder Gadget mit der gleichen set-Methode eine Größe verpassen kann, hat das durchaus seine Vorteile. Und reduziert auch den Nachschlage- und Lernaufwand, wenn man es konsequent auf alle Attribute anwendet.
Warum der Programmierer einmal SA_Width, dann WA_Width und dann wieder GA_Width benutzen muß, ist wohl kaum befriedigend zu erklären...


Das hab ich nun (noch) nicht gemacht, da die Gemeinsamkeiten zw. Screen und Window sich auf ca. 5 Attribute beschränken. Ist aber dennoch sinnvoll, wenn man z.B. an das Depth-Arrangement und andere Fähigkeiten der beiden denkt (dazu dann noch Gadgets).

Das mit der Namensgebung der Konstanten ist wohl nur dazu da, dass man sieht, was man gerade verwendet (WA=WindowAttribute, SA=ScreenAttribute, GA=GadgetAttribute; zumindest so meine Vermutung).


Mal ne ganz andere Frage (bin gerad zu faul nen neuen Thread zu starten):
Kann man in einer initialisierten struct screen den Title ändern und wird dieser Dann sofort sichtbar, oder muss man RethinkDisplay() o.ä. aufrufen?

Ciao

[ - Antworten - Zitieren - Direktlink - ]

02.06.2005, 13:13 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Reth:
Das kann ich nun wiederum nicht nachvollziehen. Was gewinnt man damit (kann mir das Ganze wie Du es meinst gerad nicht so recht vorstellen)?

Statische Konstanten findest Du eben genauso leicht wie eine setXYZ() Methode: In dem Du in der Klasse suchst, deren Objekt Du manipulieren willst. Im Gegensatz zu den Preprozessor-Makros, die in den Standard-Includes verwendet werden. Insbesondere eben bei der Verwendung von Tools hilft das natürlich, weil das Durchsuchen einer Klasse nach einer Konstante ein naheliegender Algorithmus ist, während die Information, daß für window.set... nach WA_* gesucht werden muß und für screen.set... nach SA_* erst einmal dem Tool beigebracht werden müßte.
Wenn Du das mit einer Typisierung der Tags verbindest, gewinnst Du auch den Vorteil der Typsicherheit, die ein Kombinieren von TAG-Keys mit falschen Wert-Typen verhindert.
Beispiel:
code:
#include <iostream>

template<class T> class Attr
{
  const int tag;
public:
  Attr(const int tagvalue):tag(tagvalue){}
  const int tagValue() const { return tag; }
};

class Window
{
  public:
    static const Attr<int> WIDTH;
    static const Attr<int> HEIGHT;
    static const Attr<const char*> TITLE;
    static const Attr<bool> CLOSE_GADGET;
    template<class T> void setAttr(Attr<T> key, T value)
    {
      const int ivalue=(int)value;
      std::cout<<"setting { 0x"<<std::hex<<key.tagValue()<<", "
        <<std::dec<<ivalue<<" }"<<std::endl;
    }
};
const Attr<int> Window::WIDTH(0x80001001);
const Attr<int> Window::HEIGHT(0x80001002);
const Attr<const char*> Window::TITLE(0x80001003);
const Attr<bool> Window::CLOSE_GADGET(0x80001004);

int main(int x, char**y)
{
  Window win;

  win.setAttr(Window::WIDTH, 200);
  win.setAttr(Window::HEIGHT, 200);
  win.setAttr(Window::TITLE, "Hallo");
  win.setAttr(Window::CLOSE_GADGET, true);
}

Hier kann man keine falschen Datentypen mehr für ein Attribut verwenden. Weil ich gerade keine Amiga-includes hier habe, habe ich auf Amiga-Datentypen ala ULONG verzichtet und nix mit TagList implementiert, aber den Code hast Du ja eh schon selber.
Und die TAG-keys sind natürlich willkürliche Werte, die müssen durch die echten ersetzt werden. Da kann man natürlich die WA_... Makros verwenden.
Zitat:
Das hab ich nun (noch) nicht gemacht, da die Gemeinsamkeiten zw. Screen und Window sich auf ca. 5 Attribute beschränken. Ist aber dennoch sinnvoll, wenn man z.B. an das Depth-Arrangement und andere Fähigkeiten der beiden denkt (dazu dann noch Gadgets).
Muß man natürlich aufpassen und genau überlegen, wo Vererbung wirklich sinnvoll ist. Insbesondere das Verarbeiten von TagLists sollte man eher in eine eigene Klasse packen und über Delegation verwenden.
Zitat:
Kann man in einer initialisierten struct screen den Title ändern und wird dieser Dann sofort sichtbar, oder muss man RethinkDisplay() o.ä. aufrufen?
Normalerweise sieht man in der Screen-Titelleiste den Screen-Titel, der für das aktive Fenster definiert wurde. Diesen setzt man über setWindowTitle(...). Wie das mit dem default screen-Titel aussieht, weiß ich nicht aus dem Kopf.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

02.06.2005, 20:46 Uhr

Reth
Posts: 1858
Nutzer
Danke für Deinen Post.

Mein C++ steckt noch vor den Anfängen, darum hier noch ein paar Fragen:

[quote]
Original von Holger:
Zitat:
Wenn Du das mit einer Typisierung der Tags verbindest, gewinnst Du auch den Vorteil der Typsicherheit, die ein Kombinieren von TAG-Keys mit falschen Wert-Typen verhindert.
Beispiel:
code:
#include <iostream>

template<class T> class Attr
{
  const int tag;
public:
  Attr(const int tagvalue):tag(tagvalue){}
  const int tagValue() const { return tag; }
};



Den Teil hab ich verstanden! :D

Zitat:
code:
class Window
{
  public:
    static const Attr<int> WIDTH;
    static const Attr<int> HEIGHT;
    static const Attr<const char*> TITLE;
    static const Attr<bool> CLOSE_GADGET;
    template<class T> void setAttr(Attr<T> key, T value)
    {
      const int ivalue=(int)value;
      std::cout<<"setting { 0x"<<std::hex<<key.tagValue()<<", "
        <<std::dec<<ivalue<<" }"<<std::endl;
    }
};



Das versteh ich auch noch, wobei ich nicht sehe, wie die setAttr-Methode das Attribut wirklich setzt (welches ja beim Aufruf des Konstruktors mittels Initialisierungsliste gesetzt wird)?
Wieso muss die Methode vor dem void ein template<class T> haben?

Zitat:
code:
const Attr<int> Window::WIDTH(0x80001001);
const Attr<int> Window::HEIGHT(0x80001002);
const Attr<const char*> Window::TITLE(0x80001003);
const Attr<bool> Window::CLOSE_GADGET(0x80001004);



Ist das eine Standardvorbelegung? Wieso kann man beim BOOL so nen Hexwert eintragen?

Zitat:
code:
int main(int x, char**y)
{
  Window win;

  win.setAttr(Window::WIDTH, 200);
  win.setAttr(Window::HEIGHT, 200);
  win.setAttr(Window::TITLE, "Hallo");
  win.setAttr(Window::CLOSE_GADGET, true);
}



Hier sollten ja die eigenen Werte gesetzt werden, nur blick ich nicht, wie die setAttr-Methode das macht (müsste ja ein Aufruf der Art WIDTH(200); o.ä. innerhalb der Methode sein!?

Ich seh schon, klinge wie ein C++ Analphabet (bin auch einer).
Wo ich herkomm sieht man an meiner Implementierung bisher.
Da gibt es für jedes angebotene Attribut nen Setter und nen Getter, also setWidth, setHeight, setAutoScroll(BOOL), setDragBar(BOOL), ...

[ - Antworten - Zitieren - Direktlink - ]

03.06.2005, 10:54 Uhr

Holger
Posts: 8116
Nutzer
@Reth:
Nein, Du unterliegst nur einem kleinen Mißverstandnis. Die Attr-Klasse kapselt nicht die Werte, sondern nur die Tag-Keys. Die setAttr Methode ist nix anderes als eine Funktion der Art: setAttribute(WA_KEYNAME, value), nur mit einem wesentlichen Unterschied: die Keys sind typisierte Konstanten und als value sind demzufolge nur Werte des Keys-Typparameters möglich.
Die Implementierung muß die Konstante aus dem Key auslesen (der Methodenname tagValue war wohl mißverständlich) und den Wert nach int konvertieren. Der Besipielcode macht genau das, nur das er keine TagList erzeugt, sondern das key-value Paar auf der Konsole ausgibt.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

03.06.2005, 10:58 Uhr

Holger
Posts: 8116
Nutzer
Also am Besten, die Attr Klasse ändern:
code:
template<class T> class Attr
{
  const int key;
public:
  Attr(const int keyvalue):key(keyvalue){}
  const int keyValue() const { return key; }
};


mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

03.06.2005, 11:03 Uhr

Holger
Posts: 8116
Nutzer
code:
const Attr<int> Window::WIDTH(0x80001001);
const Attr<int> Window::HEIGHT(0x80001002);
const Attr<const char*> Window::TITLE(0x80001003);
const Attr<bool> Window::CLOSE_GADGET(0x80001004);

müßte natürlich so aussehen:
code:
const Attr<int> Window::WIDTH(WA_Width);
const Attr<int> Window::HEIGHT(WA_Height);
const Attr<const char*> Window::TITLE(WA_Title);
const Attr<bool> Window::CLOSE_GADGET(WA_CLOSEGADGET);

damit definiert man die Konstanten und eben den Typen, der in der setAttr-Methode für den Wert erlaubt ist. Wie gesagt, ich habe hier keine AmigaOS-includes zur Hand und deswegen willkürliche Werte eingesetzt, um den Code kompilieren und testen zu können.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

03.06.2005, 21:55 Uhr

Reth
Posts: 1858
Nutzer
@Holger

Vielen Dank für die Erläuterungen!

Wenn ich das also richtig sehe, dann sorgt

code:
template<class T> void setAttr(Attr<T> key, T value)


das T vor Value dafür, dass nur derselbe Typ übergeben werden kann, der auch in Attr<T> enthalten ist, oder?

Aber wieso steht vor der Methode ein template<class T> void?
Und wieso kann innerhalb der Methode alles auf int gecastet werden (doch nur, weil alle Werte auch char * und BOOL auf int basieren, oder was anderes)?

[ - Antworten - Zitieren - Direktlink - ]

04.06.2005, 16:58 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Reth:
Wenn ich das also richtig sehe, dann sorgt
code:
template<class T> void setAttr(Attr<T> key, T value)

das T vor Value dafür, dass nur derselbe Typ übergeben werden kann, der auch in Attr<T> enthalten ist, oder?
Richtig. Aber
Zitat:
Aber wieso steht vor der Methode ein template<class T> void?
template<class T> muß vor der Methode stehen, weil die gesamte Methode den Typparameter T besitzt. void ist nur der ganz normale Rückgabetyp.
Wenn man dieser Methode eine Object z.B. vom Type Attr<bool> übergibt, erkennt der Compiler automatisch, daß jetzt für T bool eingesetzt werden muß. Deshalb muß man nicht win.setAttr<bool>(Window::CLOSE_GADGET, true); schreiben.
Aber formal gesehen besitzt die Methode einen Typparameter, der erstmal nichts mit dem Typparameter der Klasse Attr zu tun hat.
Zitat:
Und wieso kann innerhalb der Methode alles auf int gecastet werden (doch nur, weil alle Werte auch char * und BOOL auf int basieren, oder was anderes)?
Basieren ist der falsche Ausdruck. Sie können nach int konvertiert werden, das ist genau die Operation, die man bei der Verwendung von TagItems grundsätzlich durchführen muß.
Prinzipiell kann setAttr jetzt mit jeden Datentyp T ausgerufen werden, für den ein cast-Operator nach int existiert. Andere Datentypen werden von TagItems sowieso nicht unterstützt.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ Dieser Beitrag wurde von Holger am 04.06.2005 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

04.06.2005, 20:01 Uhr

Reth
Posts: 1858
Nutzer
@Holger

Vielen Dank für die Erläuterungen! Das TagItems nur int vertragen wusste ich nun noch nicht (hab mir die Definition der entsprechenden Strukturen noch nicht angesehen)!

Mit den Konstanten muss man sich ja auch für jeden verwendeten Wert innerhalb der NewWindow-Struktur ne eigene Konstante machen.
Was hältst Du/ihr denn von dem Ansatz:

code:
void setLeft(const ULONG left = 0) { windowLeft = left; }
void setTop(const ULONG top = 0) { windowTop = top; }
void setWidth(const ULONG width = STDSCREENWIDTH) { windowWidth = width; }
void setHeight(const ULONG height = STDSCREENHEIGHT) { windowHeight = height; }
void setTitle(const string title = "") { windowTitle = title; }
void setDragBar(const BOOL setDragBar = TRUE) { dragBar = setDragBar; }
void setBorderless(const BOOL setBorderless = FALSE) { borderless = setBorderless; }
void setReportMouse(const BOOL setReportMouse = TRUE) { reportMouse = setReportMouse; }
void setNewLookMenus(const BOOL setNewLookMenus = TRUE) { newLookMenus = setNewLookMenus; }
void setSizeGadget(const BOOL setSizeGadget = TRUE) { sizeGadget = setSizeGadget; }
void setDepthGadget(const BOOL setDepthGadget = TRUE) { depthGadget = setDepthGadget; }
void setCloseGadget(const BOOL setCloseGadget = TRUE) { closeGadget = setCloseGadget; }
void setActivate(const BOOL setActivate = TRUE) { activate = setActivate; }
void setNoCareRefresh(const BOOL setNoCareRefresh = TRUE) { noCareRefresh = setNoCareRefresh; }
void setBackdrop(const BOOL setBackdrop = FALSE) { backdrop = setBackdrop; }
void setRMBTrap(const BOOL setRMBTrap = FALSE) { trapRMB = setRMBTrap; }
void setGimmeZeroZero(const BOOL setGimmeZeroZero = FALSE) { gimmeZeroZero = setGimmeZeroZero; }
void setAutoAdjust(const BOOL setAutoAdjust = TRUE) { autoAdjust = setAutoAdjust; }
void setMenuHelp(const BOOL setMenuHelp = TRUE) { menuHelp = setMenuHelp; }
void setNotifyDepth(const BOOL setNotifyDepth = TRUE) { notifyDepth = setNotifyDepth; }
void notifyNewSize() { setIDCMPFlag(IDCMP_NEWSIZE); }
void notifyRefreshWindow() { setIDCMPFLag(IDCMP_REFRESHWINDOW); }
void notifyMouseButtons() { setIDCMPFLag(IDCMP_MOUSEBUTTONS); }
void notifyMouseMove() { setIDCMPFLag(IDCMP_MOUSEMOVE); } // nur wenn ReportMouse gesetzt wurde
void notifyGadgetDown() { setIDCMPFLag(IDCMP_GADGETDOWN); }
void notifyGadgetUp() { setIDCMPFLag(IDCMP_GADGETUP); }
void notifyMenuPick() { setIDCMPFLag(IDCMP_MENUPICK); }
void notifyCloseWindow() { setIDCMPFLag(IDCMP_CLOSEWINDOW); }
void notifyIntuiTicks() { setIDCMPFLag(IDCMP_INTUITICKS); }
void notifyActiveWindow() { setIDCMPFLag(IDCMP_ACTIVEWINDOW); }
void notifyInactiveWindow() { setIDCMPFLag(IDCMP_INACTIVEWINDOW); }
void notifyChangeWindow() { setIDCMPFLag(IDCMP_CHANGEWINDOW); }
void notifyMenuHelp() { setIDCMPFLag(IDCMP_MENUHELP); }
void notifiyIDMCP(ULONG flags = 0) { setIDCMPFlag(flags); }


Dasselbe nochmal mit Gettern (ausser für die IDCMP-Flags).

[ Dieser Beitrag wurde von Reth am 04.06.2005 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

04.06.2005, 20:26 Uhr

Holger
Posts: 8116
Nutzer
Damit hast Du ja noch nicht viel gewonnen. Du schreibst ja bisher nur in die Struktur und mußt ja immer noch den code hinzufügen, der die Änderungen herbeiführt.
Ich nehme mal an, Du hast bisher nur code, der diese Attribute beim Öffnen des Fensters in eine TagList verpackt und übergibt. Aber wenn man schon ein Fenster in einem Objekt kapselt, sollte man als Nutzer der Klasse für das Setzen eines Attributs nicht mehr darüber nachdenken müssen, ob das Fenster gerade offen ist oder nicht.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

04.06.2005, 20:35 Uhr

Holger
Posts: 8116
Nutzer
Ach so
Zitat:
Original von Reth:
Mit den Konstanten muss man sich ja auch für jeden verwendeten Wert innerhalb der NewWindow-Struktur ne eigene Konstante machen.
Was hältst Du/ihr denn von dem Ansatz:

vergiß die NewWindow-Struktur. Ich bin davon ausgegangen, daß Du sowieso nur mit TagList arbeitest. Wenn Du alle Attribute unterstützen willst, mußt Du sowieso TagLists unterstützen, also ist es nur konsequent, dafür dann auf die NewWindow-Struktur zu verzichten. Für alle Attribute der NewWindow-Struktur gibt es auch ein gleichwertiges TAG, umgekehrt gilt das nicht.
Also laß die NewWindow Struktur weg. Und implementiere alle set... Methode so, daß sie ein TagItem erzeugen/verändern. Dazu kannst Du wiederverwendbare Hilfsmethoden schreiben und sparst eine Menge Code.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

04.06.2005, 22:35 Uhr

Reth
Posts: 1858
Nutzer
[quote]
Original von Holger:
Ach so
Zitat:
vergiß die NewWindow-Struktur. Ich bin davon ausgegangen, daß Du sowieso nur mit TagList arbeitest. Wenn Du alle Attribute unterstützen willst, mußt Du sowieso TagLists unterstützen, also ist es nur konsequent, dafür dann auf die NewWindow-Struktur zu verzichten. Für alle Attribute der NewWindow-Struktur gibt es auch ein gleichwertiges TAG, umgekehrt gilt das nicht.
Also laß die NewWindow Struktur weg. Und implementiere alle set... Methode so, daß sie ein TagItem erzeugen/verändern. Dazu kannst Du wiederverwendbare Hilfsmethoden schreiben und sparst eine Menge Code.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.


Oh, da hab ich wohl ein wenig fehlerhaft gepostet. Ich verwende ja Tags, bezog mich auf die WA_... Sachen und hab das in nen Zusammenhang mit der NewWindow-Struktur gesetzt. Sorry!

Durch die Setter sieht das Ganze bei mir sehr starr aus. Habe bei OpenWindowTags und OpenScreenTags für jeden Setter ein Tag gesetzt.
Durch die Defaultwerte kann man Objekte der Klasse ohne Setter-Aufrufe verwenden, wenn man damit auskommt.

Durch diese Konstruktion verliert man leider die Flexibilität. Wenn man Deinen Ansatz mit den Konstanten mit ner Liste o.ä. kombiniert, kann man sehr flexibel die TagItems für ein OpenWindowTags zusammenstellen, oder nich?!

Überlege mir gerad ne halbwegs vernünftige Lösung für das Problem, dass ich einmal ne Methode habe, die ein Fenster anhand eines solchen Datenobjektes öffnet ohne PubScreen und einmal mit. Beide Methoden erhalten ein Objekt, welches diese Werte enthält und über Getter zur Verfügung stelllt. Die 2. Methode erhält zusätzlich noch die notwendige screen-Struktur (bzw. nen Zeiger drauf gekapselt in nem Objekt).
Hab mir überlegt, dass ich ne private Methode mach, die TagItem-Strukturen zusammenstellt, wobei die Methode mit dem PubScreen schon nen TagItem-Eintrag erhält (ist die Reihenfolge der TagItems von
Bedeuting?).
Da ich in C++ sehr unerfahren bin, fehlen mir hier die Fertigkeiten die Möglichkeiten effizient auszunutzen.
Hast Du nen guten Vorschlag!? ?(
Ne Lösung wäre zwar schön, ne Idee oder nen Link, wo man erfährt, wie man die C++ Möglichkeiten clever einsetzt (so wie Du mit Deiner Attr-Klasse) aber noch viel besser!
Warte gerade auf die Neuauflage von "Thinking in C++"!

Ciao

[ Dieser Beitrag wurde von Reth am 04.06.2005 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

05.06.2005, 13:36 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Reth:
Durch die Setter sieht das Ganze bei mir sehr starr aus. Habe bei OpenWindowTags und OpenScreenTags für jeden Setter ein Tag gesetzt.
Durch die Defaultwerte kann man Objekte der Klasse ohne Setter-Aufrufe verwenden, wenn man damit auskommt.

Du kannst meinen Attr-Entwurf so abändern, daß Du für jedes Attribut einen default-Wert in der Deklaration angeben kannst. Ich halte es auch für sinnvoll, für oft benötigte Attribute eine einfache Methode anzubieten, diese kann dann einfach an die zugehörige setAttr(Konstante, parameter) delegieren. Man sollte nur sorgfältig auswählen, zuviele Methoden erleichtern nicht unbedingt das Verständnis.
Zitat:
Überlege mir gerad ne halbwegs vernünftige Lösung für das Problem, dass ich einmal ne Methode habe, die ein Fenster anhand eines solchen Datenobjektes öffnet ohne PubScreen und einmal mit. Beide Methoden erhalten ein Objekt, welches diese Werte enthält und über Getter zur Verfügung stelllt. Die 2. Methode erhält zusätzlich noch die notwendige screen-Struktur (bzw. nen Zeiger drauf gekapselt in nem Objekt).
Am besten ist es, dem Window-Objekt ein Screen-Attribut zu verpassen, das auch das Locken des pubscreens mit übernimmt. Also z.B. auch mit dem Namen des gewünschten pubscreens initialisiert werden kann.
Dieses Attribute kann nämlich mit dem Rückgabewert von GetDefaultPubScreen() initialisiert werden, somit brauchst Du dann später keine Fallunterscheidung, ob das Attribute gesetzt wurde oder nicht.
Zitat:
Hab mir überlegt, dass ich ne private Methode mach, die TagItem-Strukturen zusammenstellt, wobei die Methode mit dem PubScreen schon nen TagItem-Eintrag erhält (ist die Reihenfolge der TagItems von
Bedeuting?).

Meistens nicht.
Am betsen machst Du Dir nicht nur ne private Methode, sondern eine eigene Klasse, die TagLists kapselt und verwaltet. Du wirst diese ja in möglicherweise in völlig unterschiedlichen Klassen benötigen.
Zitat:
Da ich in C++ sehr unerfahren bin, fehlen mir hier die Fertigkeiten die Möglichkeiten effizient auszunutzen.
Ich muß darauf hinweisen, daß ich auch kein erfahrener C++-Programmierer bin. Ich muß auch immer überlegen, wie ich die Möglichkeiten von C++ am Besten ausnutze und kann nicht garantieren, daß das Resultat "best C++ practice" ist. Und ich brauche immer ein wenig Zeit, um einen Vorschlag machen zu können, weil ich immer selber ausprobieren muß, ob das überhaupt funktioniert wie gedacht.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

05.06.2005, 15:27 Uhr

Reth
Posts: 1858
Nutzer
Zitat:
Original von Holger:
Damit hast Du ja noch nicht viel gewonnen. Du schreibst ja bisher nur in die Struktur und mußt ja immer noch den code hinzufügen, der die Änderungen herbeiführt.
Ich nehme mal an, Du hast bisher nur code, der diese Attribute beim Öffnen des Fensters in eine TagList verpackt und übergibt. Aber wenn man schon ein Fenster in einem Objekt kapselt, sollte man als Nutzer der Klasse für das Setzen eines Attributs nicht mehr darüber nachdenken müssen, ob das Fenster gerade offen ist oder nicht.


Hier mal die ganze Klasse, so wie sie momentan aussieht aber nicht compiliert wird (GCC meckert immer bei der 2. Notify...-Methode rum, dass er die setIDCMPFlag nicht kennt egal welche von den Notifymethoden ich dahinstelle!).
Die Windowklasse bekommt dann eine Referenz auf ein Objekt dieser Klasse und ruft in OpenWindowTags einen getter nach dem anderen auf. Wie gesagt: Ziemlich starr und unflexibel (aber intuitiver m.M. nach):

code:
#ifndef WINDOWDATA_H
#define WINDOWDATA_H

#include <string>
#include <intuition/intuition.h>
 
class WindowDataC
{
    private:
		ULONG windowLeft, windowTop, windowWidth, windowHeight, flagsIDCMP;
		BOOL dragBar, borderless, reportMouse, newLookMenus, sizeGadget, depthGadget, closeGadget, activate,
			 noCareRefresh, backdrop, trapRMB, gimmeZeroZero, autoAdjust, menuHelp, notifyDepth;
		string windowTitle;
	
		inline void setIDCMPFlag(ULONG flag) { flagsIDCMP = flagsIDCMP | flag; }
	
	public:
		WindowDataC() : flagsIDCMP(0) {}
		~WindowDataC() {}
					   
		void setLeft(const ULONG left = 0) { windowLeft = left; }
		void setTop(const ULONG top = 0) { windowTop = top; }
        void setWidth(const ULONG width = STDSCREENWIDTH) { windowWidth = width; }
		void setHeight(const ULONG height = STDSCREENHEIGHT) { windowHeight = height; }
		void setTitle(const string title = "") { windowTitle = title; }
		void setDragBar(const BOOL setDragBar = TRUE) { dragBar = setDragBar; }
		void setBorderless(const BOOL setBorderless = FALSE) { borderless = setBorderless; }
		void setReportMouse(const BOOL setReportMouse = TRUE) { reportMouse = setReportMouse; }
		void setNewLookMenus(const BOOL setNewLookMenus = TRUE) { newLookMenus = setNewLookMenus; }
		void setSizeGadget(const BOOL setSizeGadget = TRUE) { sizeGadget = setSizeGadget; }
		void setDepthGadget(const BOOL setDepthGadget = TRUE) { depthGadget = setDepthGadget; }
		void setCloseGadget(const BOOL setCloseGadget = TRUE) { closeGadget = setCloseGadget; }
		void setActivate(const BOOL setActivate = TRUE) { activate = setActivate; }
		void setNoCareRefresh(const BOOL setNoCareRefresh = TRUE) { noCareRefresh = setNoCareRefresh; }
		void setBackdrop(const BOOL setBackdrop = FALSE) { backdrop = setBackdrop; }
		void setRMBTrap(const BOOL setRMBTrap = FALSE) { trapRMB = setRMBTrap; }
		void setGimmeZeroZero(const BOOL setGimmeZeroZero = FALSE) { gimmeZeroZero = setGimmeZeroZero; }
		void setAutoAdjust(const BOOL setAutoAdjust = TRUE) { autoAdjust = setAutoAdjust; }
		void setMenuHelp(const BOOL setMenuHelp = TRUE) { menuHelp = setMenuHelp; }
		void setNotifyDepth(const BOOL setNotifyDepth = TRUE) { notifyDepth = setNotifyDepth; }
		void notifyNewSize() { setIDCMPFlag(IDCMP_NEWSIZE); }
		void notifyRefreshWindow() { setIDCMPFLag(IDCMP_REFRESHWINDOW); }
		void notifyMouseButtons() { setIDCMPFLag(IDCMP_MOUSEBUTTONS); }
		void notifyMouseMove() { setIDCMPFLag(IDCMP_MOUSEMOVE); }	// nur wenn ReportMouse gesetzt wurde
		void notifyGadgetDown() { setIDCMPFLag(IDCMP_GADGETDOWN); }
		void notifyGadgetUp() { setIDCMPFLag(IDCMP_GADGETUP); }
		void notifyMenuPick() { setIDCMPFLag(IDCMP_MENUPICK); }
		void notifyCloseWindow() { setIDCMPFLag(IDCMP_CLOSEWINDOW); }
		void notifyIntuiTicks() { setIDCMPFLag(IDCMP_INTUITICKS); }
		void notifyActiveWindow() { setIDCMPFLag(IDCMP_ACTIVEWINDOW); }
		void notifyInactiveWindow() { setIDCMPFLag(IDCMP_INACTIVEWINDOW); }
		void notifyChangeWindow() { setIDCMPFLag(IDCMP_CHANGEWINDOW); }
		void notifyMenuHelp() { setIDCMPFLag(IDCMP_MENUHELP); }
		void notifiyIDMCP(ULONG flags = 0) { setIDCMPFlag(flags); }

		ULONG getLeft() const { return windowLeft; }
		ULONG getTop()const { return windowTop; }
		ULONG getWidth() const { return windowWidth; }
		ULONG getHeight()const { return windowHeight; }
		string getTitle() const { return windowTitle; }
		BOOL hasDragBar() const { return dragBar; }
		BOOL isBorderless() const { return borderless; }
		BOOL hasReportMouse() const { return reportMouse; }
		BOOL hasNewLookMenus() const { return newLookMenus; }
		BOOL hasSizeGadget() const { return sizeGadget; }
		BOOL hasDepthGadget() const { return depthGadget; }
		BOOL hasCloseGadget() const { return closeGadget; }
		BOOL isActivate() const { return activate; }
		BOOL hasNoCareRefresh() const { return noCareRefresh; }
		BOOL isBackdrop() const { return backdrop; }
		BOOL hasRMBTrap() const { return trapRMB; }
		BOOL isGimmeZeroZero() const { return gimmeZeroZero; }
		BOOL isAutoAdjust() const { return autoAdjust; }
		BOOL hasMenuHelp() const { return menuHelp; }
		BOOL hasNotifyDepth() const { return notifyDepth; }
};
#endif


[ Dieser Beitrag wurde von Reth am 05.06.2005 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

05.06.2005, 15:41 Uhr

Reth
Posts: 1858
Nutzer
Zitat:
Original von Holger:
Du kannst meinen Attr-Entwurf so abändern, daß Du für jedes Attribut einen default-Wert in der Deklaration angeben kannst. Ich halte es auch für sinnvoll, für oft benötigte Attribute eine einfache Methode anzubieten, diese kann dann einfach an die zugehörige setAttr(Konstante, parameter) delegieren. Man sollte nur sorgfältig auswählen, zuviele Methoden erleichtern nicht unbedingt das Verständnis.


Hm, dann sollt ichs evtl. nochmal abändern (s. vorigen Post).

Zitat:
Am besten ist es, dem Window-Objekt ein Screen-Attribut zu verpassen, das auch das Locken des pubscreens mit übernimmt. Also z.B. auch mit dem Namen des gewünschten pubscreens initialisiert werden kann.
Dieses Attribute kann nämlich mit dem Rückgabewert von GetDefaultPubScreen() initialisiert werden, somit brauchst Du dann später keine Fallunterscheidung, ob das Attribute gesetzt wurde oder nicht.


Hatte mir das so gedacht, dass ich die Windowklasse bei der Screenklasse als Friend setze und eine Openmethode mit Screen und eine ohne angebe (in letzterer wird dann einfach OpenWindowTags ohne screen-Struktur gerufen).
Muss man vor OpenWindow* immer einen LockPubScreen machen (denn dann würde ich auch bei der bisherigen Methode ohne screen-Struktur ne screen-Struktur brauchen).
Werde die Windowklasse so ändern, dass immer eine screen-Struktur benutze, dann spar ich mir das Überlegen einer cleveren Alternative für variable TagItems erstmal :D )

Zitat:
Meistens nicht.
Am betsen machst Du Dir nicht nur ne private Methode, sondern eine eigene Klasse, die TagLists kapselt und verwaltet. Du wirst diese ja in möglicherweise in völlig unterschiedlichen Klassen benötigen.


Stimmt eigentlich! Die TagItem-Klasse kann man ja dann so anlegen wie Deine Templateklasse mit setTagItem(<T>tagItem, T value) <= hier nur unvollständig.
Bleibt immer noch das Problem wie man die Tags aus einer Liste in den OpenWindowTags-Aufruf bekommt, da man ja dort jedes Tag einzeln angeben muss (oder?) und ich schon gern ne variable TagItemanzahl nehmen möchte!

Zitat:
Ich muß darauf hinweisen, daß ich auch kein erfahrener C++-Programmierer bin. Ich muß auch immer überlegen, wie ich die Möglichkeiten von C++ am Besten ausnutze und kann nicht garantieren, daß das Resultat "best C++ practice" ist. Und ich brauche immer ein wenig Zeit, um einen Vorschlag machen zu können, weil ich immer selber ausprobieren muß, ob das überhaupt funktioniert wie gedacht.

Kommt mir aber reichlich erfahren vor (zumindest im Vgl. zu mir!). Immer wieder vielen Dank für die wertvolle Hilfe!

Ciao

[ Dieser Beitrag wurde von Reth am 05.06.2005 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

05.06.2005, 17:45 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Reth:
Bleibt immer noch das Problem wie man die Tags aus einer Liste in den OpenWindowTags-Aufruf bekommt, da man ja dort jedes Tag einzeln angeben muss (oder?) und ich schon gern ne variable TagItemanzahl nehmen möchte!

Nein, Du übergibst ein Array, genauer gesagt einen Pointer auf das erste TagItem. Das letzte item muß als Tag-Key den Wert TAG_DONE haben (IMHO ==0 ) und der Tag-Value ist egal.
Interessant ist in diesem Zusammenhang, daß man eine TagList auch mit TAG_NEXT (oder so ähnlich) beenden kann, wobei dessen Tag-Value einen Pointer auf eine weitere Liste hat. Man kann also statisch alloziierte Blöcke mit oft benutzten oder konstanten Werten mit dynamisch angelegten Listen mischen, ohne die Listen kopieren zu müssen.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

06.06.2005, 18:23 Uhr

Reth
Posts: 1858
Nutzer
@Holger:

Das klingt doch sehr flexibel!

Hab folgendes Bsp. in den Autodocs gefunden:

code:
struct Screen	*
OpenScreenTags( ns, tag1 )
struct NewScreen	*ns;
ULONG			tag1;
{
    struct Screen	*OpenScreenTagList();
    return ( OpenScreenTagList( ns, (struct TagItem *) &tag1 ) );
}


Komm damit aber nicht ganz klar!
Es wird ein ULONG übergeben, aber ist das nun der TagWert oder der TagKey (wenn man so will). Zu allem Überfluss wird die Adresse dieses ULONG auch noch in nen struct TagItem * gecastet! ?(

Verstehen würd ich ne Übergabe wie folgt:

code:
struct TagItem items[];
...

OpenWindowTagList(NULL, &items[0]);


Oder geht das nicht so (so hab ich zumindest Deinen letzten Post verstanden)?

[ - Antworten - Zitieren - Direktlink - ]

06.06.2005, 22:47 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Reth:
Komm damit aber nicht ganz klar!
Es wird ein ULONG übergeben, aber ist das nun der TagWert oder der TagKey (wenn man so will). Zu allem Überfluss wird die Adresse dieses ULONG auch noch in nen struct TagItem * gecastet! ?(

Die Code-Beispiele kannst Du knicken. Commodore-Entwickler lieben es, Daten grundlos falsch zu deklarieren, um sie dann später nur noch mit type-casts benutzen zu können. Das findet sich leider teilweise auch in den includes selber, so daß auch andere Amiga-Programmierer gezwungen werden, type-casts zu benutzen, die vermeidbar wären.
Wie Du ja am Aufruf siehst, ist der benötigte Parameter-Typ "struct TagItem *".
Zitat:
Verstehen würd ich ne Übergabe wie folgt:
code:
struct TagItem items[];
...

OpenWindowTagList(NULL, &items[0]);

Oder geht das nicht so (so hab ich zumindest Deinen letzten Post verstanden)?
Vollkommen richtig. Du kannst noch zur Vereinfachung auch "items" statt "&items[0]" schreiben. Aber richtig ist beides.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

07.06.2005, 16:23 Uhr

Reth
Posts: 1858
Nutzer
@Holger:

Au klasse! Danke schön! :rotate:

Kann man in C++ auch so was machen:

code:
setAttr(T key, T value);


Oder geht das nicht?

Darf ich noch fragen wie Du (oder andere) die ganze Sache mit Window, WindowData, Screen und ScreenData aufziehen würdest?

Brauch gar kein Code, nur die Idee würde mich interessieren!

[ Dieser Beitrag wurde von Reth am 07.06.2005 um 20:49 Uhr editiert. ]

[ Dieser Beitrag wurde von Reth am 07.06.2005 um 21:36 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

08.06.2005, 16:26 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Reth:
Kann man in C++ auch so was machen:

code:
setAttr(T key, T value);


Du meinst vermutlich etwas in der Art von
code:
template<class KeyType,class ValueType>
  void setAttr(KeyType key, ValueType value);

Oder?
Zitat:
Darf ich noch fragen wie Du (oder andere) die ganze Sache mit Window, WindowData, Screen und ScreenData aufziehen würdest?
Klar darfst Du fragen. Ich habe auch noch ein bißchen am Code-Beispiel rumgebastelt. Mit Deiner Erlaubnis schicke ich Dir mal ne mail, weil das sonst hier den Rahmen sprengen würde.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ Dieser Beitrag wurde von Holger am 08.06.2005 um 16:26 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

09.06.2005, 16:37 Uhr

Reth
Posts: 1858
Nutzer
Zitat:
Original von Holger:
Du meinst vermutlich etwas in der Art von
code:
template<class KeyType,class ValueType>
  void setAttr(KeyType key, ValueType value);

Oder?

In der Art. Eine Templatemethode, die sicher stellt, dass beide Parameter vom gleichen Typ sind. So ähnlich wie Deine Klasse. Deine Klasse hat in Verbindung mit der setAttr-Methode ja dafür gesorgt, dass der Typ, der beim Anlegen des Klassenobjektes verwendet wurde auch der gleiche ist, wie der Wert in der set-Methode. Zumindest hab ich das so verstanden.

Hab das hier in nem Tutorial gesehen:

code:
template <class T>;
T max(T a, T b)
{
	return a > b ? a : b ;
}


Das müsste doch auch sicherstellen, dass beide übergebene Parameter vom gleichen Typ sind.

Frage das im Hinblick auf die Kapselung der TagItems in einer eigenen Klasse. Da müssen ja Tag und Wert auch vom gleichen Typ sein.
Mit der von Dir vorgeschlagenen Attributklasse kann man das ja auch erreichen, dazu ist mir aber noch nicht das Richtige eingefallen bzw. wenn man eh intern mit den WA_, GA_, SA_ Konstanten irgendwo arbeiten muss, dachte ich, ich mach lauter setter (s.o.) und intern werden dann TagItem-Strukutren in eine Liste geschrieben, welche dann ebenfalls intern über friend-Mechanismus bei OpenWindowTags verwendet wird.
Wenn ichs fertig hab, schick ich Dir den Source mal, falls Du Interesse hast.

Zitat:
Klar darfst Du fragen. Ich habe auch noch ein bißchen am Code-Beispiel rumgebastelt. Mit Deiner Erlaubnis schicke ich Dir mal ne mail, weil das sonst hier den Rahmen sprengen würde.

Na klar aber gern doch!
Vielleicht interessiert andere aber Deine Idee zu dem Ganzen!?

[ - Antworten - Zitieren - Direktlink - ]

10.06.2005, 14:11 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Reth:
Hab das hier in nem Tutorial gesehen:

...

Das müsste doch auch sicherstellen, dass beide übergebene Parameter vom gleichen Typ sind.

Richtig, funktioniert genau so, wie Du es Dir vorstellst.
Zitat:
Vielleicht interessiert andere aber Deine Idee zu dem Ganzen!?
Mag sein. Ich glaube nur, dass die mögliche Aufmerksamkeit ziemlich schnell sinkt, wenn der Thread mit ellenlangen source-code geflutet wird. Über prinzipielle Konzepte kann man ja trotzdem hier diskutieren.
Mitleser dürfen natürlich gerne ihr Interesse hier bekunden.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

10.06.2005, 15:11 Uhr

Reth
Posts: 1858
Nutzer
Hi Holger,

Zitat:
Original von Holger:
Zitat:
Vielleicht interessiert andere aber Deine Idee zu dem Ganzen!?
Mag sein. Ich glaube nur, dass die mögliche Aufmerksamkeit ziemlich schnell sinkt, wenn der Thread mit ellenlangen source-code geflutet wird. Über prinzipielle Konzepte kann man ja trotzdem hier diskutieren.
Mitleser dürfen natürlich gerne ihr Interesse hier bekunden.


Ich meinte ja auch nur das Konzept! :D

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Designfrage [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.