Conditional Menu:itemSelected,beginMenu,endMenu

Eigentlich ist mir die Frage peinlich, aber es kann sonst niemand helfen ... :)

Moderator: Moderatoren

Antworten
GrillenHirni
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 116
Registriert: Do, 18. Jul 2013 11:56
Kontaktdaten:

Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von GrillenHirni »

Liebe Xbase-Gurus, Freunde der inkrementellen Rekursion, des Blues und von Iron Maiden...!

Ich bastle immer noch an meiner GUI herum - ich krieg es nicht hin.

Ich habe pro Menu eine Funktion, die das Menu aufbaut - das ist bei mir eine Grundvoraussetzung,
bei der ich gerne bleiben würde, damit ich meine Sources aus 25 Jahren Entwicklung nicht alle
wegschmeissen muss...

Das funktioniert soweit ganz gut.

Erst kommt die MenuBar, dann die Menus in der Leiste und dann die SubMenus.

Ab und zu hab ich aber Menus, die nur unter dem Vorbehalt zugänglich sein sollen, wenn
eine dem Menu zugeordnete Funktion den Wert .T. zurück gibt: die Funktion FncMenuInit.

Dabei kann es sich beispielsweise um eine Funktion handeln, welche Dateien öffnet.

Schlimmstenfalls habe ich dazu noch eine Funktion, die als Prolog ausgeführt werden soll - wenn
diese .F. zurück gibt, soll das Menu ebenfalls nicht zugänglich sein: die Funktion FncProlog.

Ab und zu soll nach Ausführung eines Menus eine Funktion als Epilog ausgeführt werden:
die Funktion FncEpilog.

Die Funktion FncEpilog soll nur ausgeführt werden, wenn die Funktion FncProlog den Wert
.T. zurück gegeben hat.

Ich habe versucht mit oMenu:itemSelected, dann auch mit den Slots oMenu:beginMenu und
oMenu:endMenu. Diese Slots werden bisher in meinen Prototypen nicht ausgeführt. Ich habe
die verschiedenen Diskussionen hier im Forum verfolgt, komme aber leider nicht zu einer Lösung.

Falls ich hier im falschen Forum bin oder was falsch gepostet hab, bitte ich um Entschuldigung
und einen entsprechenden Hinweis - ich möchte niemand verärgern, weil ich auch das Handling
hier im Forum nicht beherrsche.

Folgend ein Muster von der Funktion MenuEins, welche das oMenuEins aufbauen sollte.

Code: Alles auswählen

FUNCTION MenuEins(oMenuBar,Par2)

LOCAL nItem

LOCAL lInit

LOCAL aDatei
LOCAL oMenuEins


aDbf:={}

lInit:=.T.


oMenuEins:=XBPMENU():NEW(oMenuBar)
oMenuEins:TITLE:="MenuEins"

oMenuEins:CREATE()

nItem:=oMenuBar:ADDITEM({oMenu,NIL})

/*
 ::itemSelected wird nicht ausgeführt - 
die Funktion DateienOeffnen müsste  lInit zurückgeben und die 
MenuOptionen SubMenuEins oder SubMenuZwei nur ausführen, 
wenn lInit=.T.

Wird der Slot nur für die MenuLeiste oMenuBar ausgeführt?
*/
oMenuEins:itemSelected:={¦nItem,mp1,obj¦DateienOeffnen(aDbf,Par2)}

/*
 ::beginMenu wird nicht ausgeführt.
*/
oMenuEins:beginMenu:={¦¦FncProlog()}

/*
 ::endMenu wird nicht ausgeführt.
*/
oMenuEins:endMenu:={¦¦FncEpilog()}


oMenuEins:ADDITEM{"Eins ausführen",FunktionEins()}
oMenuEins:ADDITEM{"Zwei ausführen",FunktionZwei()}

RETURN(.T.)

Kann jemand helfen?

Herzliche Grüsse!
Grilli
DelUser01

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von DelUser01 »

Hallo Grilli,

vermutlich wirst Du nicht darum herum kommen Dich einigermaßen detailliert mit dem Xbase++ Menüaufbau zu beschäftigen. Wer außer Dir kann Deine alten Menü-Funktionen mit den aktuellen Möglichkeiten in Einklang bringen? Das geht schon aus Deinen Bedingungen hervor:
Ich habe pro Menu eine Funktion, die das Menu aufbaut - das ist bei mir eine Grundvoraussetzung, bei der ich gerne bleiben würde, damit ich meine Sources aus 25 Jahren Entwicklung nicht alle wegschmeissen muss...
Es gibt bestimmt sehr viele Entwickler die Ihren "Uralt"-Menü-Code im Laufe der Zeit erweitert und angepasst haben (so wie ich).

Habe vor langer Zeit mein Menüsystem über ein Array-System aufgebaut. Damit kann per Xbp vermutlich vieles gemacht werden was Du brauchst (wie gesagt - vermutlich). Das sichtbare Menü ist aber nur der eine Teil - der andere ist wie Du die vom User angeklickte Menüfunktion weiterverarbeitest - also in Dein bisheriges Steuersystem einbindest. wer soll sich da außer Dir "kostenlos" einarbeiten? Selber machen oder Auftrag vergeben... :roll:
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von Herbert »

GrillenHirni hat geschrieben:Erst kommt die MenuBar, dann die Menus in der Leiste und dann die SubMenus.
Ab und zu hab ich aber Menus, die nur unter dem Vorbehalt zugänglich sein sollen, wenn
eine dem Menu zugeordnete Funktion den Wert .T. zurück gibt: die Funktion FncMenuInit.
Ein GUI Programm bietet den Anwendern zum Glück nicht mehr nur ein Menü, sondern, Symbolleisten, Doppelklicks, Drag und Drop usw. Die aus Office bekannte Ribbonbar gewinnt auch immer mehr Liebhaber. Daher ist ein starr vorgegebener Ablauf erlaubter oder sichtbarer Menüpunkte, die den Benutzer führen sollten, unter einem modernen GUI meiner Meinung nach nicht mehr zeitgemäss. Der Weg zu einer bestimmten Prozedur kann oder soll sogar über verschiedenste Wege führen.
Selbstverständlich sollen Optionen nicht anklickbar sein, wenn dies nicht erforderlich ist.

Code: Alles auswählen

    oMnu:enableItem(i)
    oMnu:disableItem(i)
Deine Sorge versehe ich nicht. Weshalb sollen denn deine Prozeduren nicht mehr taugen? Der Weg zu dessen Aufruf ändert sich doch nur.

Ein GUI-Programm ermöglicht viel mehr. Auch programmtechnisch. Daher verändert sich dein Code ohnehin, indem er sich auf die vielen Events aufteilen beginnt.
Da ist doch eine Veränderung eines Menüs nur ein minimaler Teil davon.
Grüsse Herbert
Immer in Bewegung...
GrillenHirni
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 116
Registriert: Do, 18. Jul 2013 11:56
Kontaktdaten:

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von GrillenHirni »

Lieber, Roland, lieber Herbert

Von Euren Hinweisen hab ich schon einiges gelernt...

Das Problem ist wahrscheinlich, dass ich weder die Dokumentation im allgmeinen
noch die Syntax des Codeblocks im speziellen verstehe...

Die Doku verstehe ich so, dass nach Anwählen des Menus der CodeBlock im Slot
oMenu:itemselected ausgeführt wird.

Tut es aber nicht...

Also verstehe ich die Doku nicht.

Genauso bei ::beginMenu und ::endMenu...

Dann ist es mir nicht klar - wenn es funktionieren würde - wie könnte ich
Zugang oder Ausführung des Menus von der Rückgabe der Funktion in ::itemselected
oder ::beginMenu abhängig machen.

Also wo könnte ich den zurückgegebenen Wert übernehmen und
versorgen, dass das Menu dann zugänglich oder nicht zugänglich ist...?

Da happert es am Verständnis des CodeBlocks und des MenuObjektes...

Oder gibt es einen ganz anderen Ansatz... Kann ich von XbpMenu eine
eigene Klasse ableiten und dort einen Pre- und einen PostBlock installieren?

Oder gibt es einen anderen Ansatz, der meinem GrillenHirni einfach nicht
einfällt...

Selbstverständlich würde ich für eine regelmässige Unterstützung einen
Auftrag vergeben - da hab ich aber schon jemanden wo gut ist und dann
müssten wir das glaube ich über das Forum JobBörse abhandeln...

Euch allen ein schönes WochenEnde...!
Grilli
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14641
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 87 Mal
Kontaktdaten:

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von Jan »

Nicht verzweifeln! Du bist nicht der Erste der an den Konzepten der GUI-Programmierung und der, nunja, zweifelhaften Doku von Alaska seine Nerven aufreibt. Ich selber gehöre eindeutig ebenfalls zu dieser Fraktion. Und manches bringt mich noch heute, nach über 10 Jahren mit Xbase++, schlichtweg zur Verzweiflung.

Codeblocks sind ein unglaublich mächtige Programmiertool. Aber in der Tat manchmal nicht so einfach zu vestehen. Hat man das aber erstmal begriffen, dann laufen zumindest relativ einfache Sachen wie die Menüs recht einfach damit.

Und ich kann Dir sagen, das :itemSelected() selbstverständlich ganz korrekt funktioniert. Klappt es bei Dir nicht dann liegt es sicher an dem von Dir erwähnten mangelndenen Syntax-Verständnis. Was erstmal kein Problem ist, dafür gibt es ja dieses Forum. Genau solche Fragen und Probleme gehören hierher.

Wenn Du Probleme mit dem Verständnis der Codeblocks und der Menu-Klasse hast solltest Du sicher nicht gleich damit anfangen, da eine eigene Klasse von abzuleiten. Du kannst mit der Standard-Klasse schon sehr viel erreichen, auch karierte Maiglöckchen wenn es denn sein soll. Nur vieleicht nicht bunt-karierte Maiglöckchen :badgrin:

Ich schlage vor das Du Dir mal die mitgelieferten Smaples anschaust. Es gibt da mehrere mit einem Menü. Die kannst Du gut als Besipiel übernehmen. Das hilft oftmals mehr als die Onlinehilfe.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von Koverhage »

Hallo Grilli,

wie Herbert schreibt, pder wenn die Bedingung beim Erstellen schon bekannt ist:

oSubMenu:addItem( { "TestProgramm", { || progxyz(.f.) },,IstZugrifferlaubt(Param) }, BMP_XYZ )

Hier gibt die Function IstZugrifferleubt (Param) .t. zurück wenn ja, sonst .f.
Gruß
Klaus
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von georg »

Hallo,


es sei ein Zwischenruf erlaubt.

Es gibt drei Möglichkeiten.

a) nur zulässige Menüpunkte sind auch sichtbar;
b) nicht zulässige Menüpunkte sind sichtbar, aber in grau dargestellt und nicht auswählbar;
c) alle Menüpunkte sind sicht- und auswählbar, aber die (aktuell) nicht zulässigen "reagieren" nicht.

b) ist das Standardverhalten, wie es unter Windows "erlebt" wird.

c) lässt sich mit der Abfrage, ob dieser Menüeintrag jetzt verfügbar ist, darstellen, kann aber zu Irritationen beim Anwender führen, wenn der nicht erkennt, wieso dieser Menüpunkt jetzt "nicht funktioniert".
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von brandelh »

Ich halte c) so für fehlerhaft ;-)
Ein Menüpunkt der sichtbar und nicht disabled (ausgegraut) ist, muss reagieren wenn man darauf klickt. Eventuell mit einer Info warum es jetzt nicht möglich ist, die Funktion auszuführen.

Bei b) weiß jeder woran er ist, a) kann schon sehr verwirrend sein, wenn man nicht weiß warum jetzt diese Möglichkeit fehlt, wo sie doch gestern noch da war ...

c) also alle Menüpunkte sind sichtbar UND reagieren, wobei jetzt ungültige Menüpunkte mit einer INFO versehen sind, warum es aktuell nicht möglich ist ...
Das finde ich immer noch als die beste Variante für unerfahrene Anwender, aber sie ist nicht Standardkonform !

Ich hatte in einem Programm einmal einen Schalter eingebaut wo man zwischen c) = Anfängermodus und b) = Standard umschalten konnte (natürlich über einen Menüpunkt der in einer INI gespeichert wurde).

PS: im MDI-Beispiel wird gezeigt wie man Menüpunkte ausblenden (als verstecken kann => Bearbeiten Menü wenn kein Child Fenster da ist) oder disablen kann (wie oben schon beschrieben).
Im Beispiel werden das Bearbeiten und Fenstermenü auch per Funktionen erstellt, dieses Beispiel habe ich für meine Zwecke angepaßt. Alle meine GUI Anwendungen beruhen darauf.
Gruß
Hubert
GrillenHirni
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 116
Registriert: Do, 18. Jul 2013 11:56
Kontaktdaten:

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von GrillenHirni »

Hallo Ihr Lieben...

Also eigentlich würde ich gerne die Variante c) umsetzen und selbstverständlich,
wenn das Menu nicht verfügbar ist, weil beispielsweise die notwendigen Dateien
nicht geöffnet werden können, mit einer entsprechenden Meldung reagieren.

Dadurch ist der MenuPunkt nicht einfach grau, sondern der Benutzer weiss auch,
warum die Option nicht ausgeführt werden kann...

Aber ob a), b) oder c) - mein Problem ist, wie mach ich das....?

Das MDI-Demo aus den Samples arbeitet mit ziemlich zusätzlichen Klassen - da
müsste ich die komplette Philosophie und die betreffenden Klassen übernehmen...
Trotzdem werde ich das Sample nochmal genau angucken...

Den Vorschlag von Klaus möchte ich trotzdem unbedingt in meinem Prototypen ausprobieren:

oSubMenu:addItem( { "TestProgramm", { || progxyz(.f.) },,IstZugrifferlaubt(Param) }, BMP_XYZ )

Auf den ersten Dreh kann ich wegen GrillenHirni die Verschachtelung nicht durchschauen und meine
Partnerin ist gleich mit Essen kochen fertig...

Code: Alles auswählen

oSubMenu:additem({TestProgramm",;
                              {¦¦ progxyz(.f.)};
                               ,,;                          // was wär das für ein Parameter zwischen den Komma? 
                                                            // Guck ich nach dem Essen in der Dokumentation - die
                                                            // Partnerin ist schon sauer mit den warmen Kartoffeln und
                                                            // der Klaus ist schuld...
                               IstZugrifferlaubt(Param),;   // wird progxyz(.f.) tatsächlich nur ausgeführt, 
                                                            // wenn (IstZugrifferlaubt(Param)=.T.)?
                               BMP_XYZ)                     // was zum Henker ist BMP_XYZ...? ein AutoModell?
Probier ich später alles aus - ich wollte mich nur möglichst rasch für die wertvollen Tipps bedanken...!

Am liebsten wüsste ich, wie man ein Menu, das selber gar keine Funktion ausführen
soll, sondern nur Optionen zum ausführen enthält, am Ausführen der Optionen hindern
kann, wenn eine dem Menu zugeordnete Funktion (z.B. DateiOeffnen("Datei.Dbf")) den
Wert .F. zurück gibt.

Ich bin ja nicht der Einzige, der dieses Problem hat - unter dem Link

http://www.xbaseforum.de/viewtopic.php? ... enu#p37989

beschreibt Gerd König ein ähnliches Problem und man kommt zum Schluss, dass oMenu:endMenu
und oMenu:beginMenu möglicherweise nur in der MenuBar und nicht in abgeleiteten MenuObjekten
funktionieren.

Das kann ich einfach nicht glauben, dass es keine entsprechende Möglichkeit gibt und anscheinend
glaubt nicht einmal Jan dies in seinem obigen Beitrag, der auch hilfreich war für mich.

Der Gerd hat dann in dem Thread aufgegeben - es würde mich schon wunder nehmen, wie er sein
Problem schliesslich gelöst hat...

Es kommt aber noch schlimmer - in meinem Prototypen wird eben auch oMenu:itemSelected
nicht ausgeführt.

Grilli
Benutzeravatar
Hans Zethofer
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 278
Registriert: Fr, 27. Jan 2006 8:29
Wohnort: 2700 Wiener Neustadt
Hat sich bedankt: 1 Mal
Kontaktdaten:

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von Hans Zethofer »

Code: Alles auswählen

BMP_XYZ...? ein AutoModell?
:lol:
damit kannst ein Bitmap vor den Menütext anzeigen lassen!

Code: Alles auswählen

zB.
   oFMenu:addItem( {"~Buchen"+Chr(9)+"Alt+B",;
                   {|| Material_Buchen(), PostAppEvent(xbeP_Keyboard, xbeK_ALT_A)},,      ;   // BUCHEN.PRG
                       XBPMENUBAR_MIA_OWNERDRAW }, 144 )
das Bitmap mit der Nr. 144 ist im ARC-File definiert

Code: Alles auswählen

//////////////////////////////////////////////////////////////////////
//
//  FAKT.ARC
//
//  Inhalt:
//      Resource Definition für FAKTXPPGUI.exe
//////////////////////////////////////////////////////////////////////


VERSION
      "CompanyName"      = "Hans ZETHOFER"
      "LegalCopyright"   = "© CEDRA-EDV 2007-2014"
      "ProductName"      = "Auftragsverwaltung Betriebsloesung mit Alaska Xbase++"

      "ProductVersion"   = "Xbase++ 1.90.355"
      "FileDescription"  = "Xbase++ Auftragsverwaltung"
      "FileVersion"         = "1.90.7.1016"   
      "OriginalFilename" = "FAKTXPPGUI.EXE"


ICON
   7666   = "ico\user.ico"
   7667   = "ico\Invoice.ico"
   7668   = "ico\Invitem.ico"
   8000   = "ico\faktapp.ico"


BITMAP
    142   = "bmp\notepad.bmp"
    143   = "bmp\linegraph.bmp"
    144   = "bmp\buchen.bmp"
_____________
lg
Hans
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von AUGE_OHR »

hi,

bringt Grilli nicht durcheinander mit den beiden Menu Beispielen.

c:\ALASKA\XPPW32\Source\samples\basics\MENU\MENUDEMO.EXE ist ein "normales" Menu
c:\ALASKA\XPPW32\Source\samples\basics\OWNERDRW\OWNERDRW.EXE ist ein "Ownerdraw" Menu.

NUR das "Ownerdraw" Menu kann ein Icon/Bitmap darstellen und hat als 4th Parameter (nAttribute) XBPMENUBAR_MIA_OWNERDRAW.
Problem : der 4th Parameter kann dann nicht gleichzeitig XBPMENUBAR_MIA_DISABLED sein.

was das enable/disable angeht ein Tip : verwenden o:SetName()

Code: Alles auswählen

   oMenu := XbpImageMenu() :new( oMenuBar )
   oMenu:title := "~Yiu Gmbh"
   oMenu:create()
   oMenu:setName( ID_YIU )
...
irgendwo in einem anderen PRG

Code: Alles auswählen

  oXbpPB:activate := { || oDlg:childFromName( ID_YIU ) :disableItem( 1 ), ;
                          machwas() ,;
                          oDlg:childFromName( ID_YIU ) :enableItem( 1 ) }
Note : auch eine "Horizontale Trennlinie" (XBPMENUBAR_MIS_SEPARATOR) ist ein Item also mit zählen.
gruss by OHR
Jimmy
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von brandelh »

Ob a) b) oder c) es geht kein Weg daran vorbei auch die grundlegenden Hilfethemen sorgfältig durchzulesen.
Die Beispiele (siehe Jimmys links) sind gut zum probieren und wir können hier Tips geben,
aber ohne die Grundlagen gelesen zu haben kann man das nicht verstehen.

Eine der Grundlagen ist z.b. dass ein Windowsmenü zwar verschiedene Möglichkeiten hat (verschachtelt, einfach, enabled, disabled, markiert etc.) aber eben doch Regeln hat, die man beachten muss. Eine der Erfolgsrezepte war doch, dass eben nicht jeder Programmierer SEINE Philosophie der Programmbedienung einbaut, sondern sich an die Microsoft Regeln hält.
Diese haben die dann recht häufig selbst über den Haufen geworfen, aber das ist eine andere Geschichte.

in der 1.90.355 Hilfe:

- Grundlagen der Programmierung
-- Benutzeroberfläche und Dialogkonzepte
--- GUI

- alles was nicht reagieren soll, muss disabled werden !
- alle möglichen Reaktionen (außer vorhandenes Standardverhalten) muss man Programmieren und z.B. in den CallBack-Slots hinterlegen.
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von Tom »

a) nur zulässige Menüpunkte sind auch sichtbar;
b) nicht zulässige Menüpunkte sind sichtbar, aber in grau dargestellt und nicht auswählbar;
c) alle Menüpunkte sind sicht- und auswählbar, aber die (aktuell) nicht zulässigen "reagieren" nicht.
"a)" nutzt man vor allem, wenn die Funktionalität der Applikation im jeweiligen Kontext eingeschränkt ist. Üblicherweise wird durch die Art der Lizenzierung festgelegt, welche Anteile einer Applikation genutzt werden können. Die, die aus solchen Gründen nicht verwendbar sind, lässt man dann eben weg. Umgekehrt kann es sinnvoll sein, solche Anteile trotzdem (disabled) anzuzeigen, um die Kunden zu locken, also das Interesse für Erweiterungen zu wecken.

Wir nutzen das auch, wenn die Benutzerrechte den Zugang zu den jeweiligen Komponenten nicht erlauben, aber wir tun das ungerne, weil unsichtbare Funktionen eben auch nicht wahrgenommen werden. Wenn also der Administrator den Zugang zu bestimmten Auswertungen vor einer Weile verboten hat, aber mit der Zeit der Bedarf entsteht, genau diese Auswertungen zu erhalten, gerät man u.U. in die unschöne Situation, dass die Anwender glauben, sie wären nicht vorhanden - und sich nach einem Konkurrenzprodukt umschauen. Ähnliches gilt bei der ebenfalls vorhandenen Möglichkeit, den sichtbaren Funktionsumfang einzuschränken, weil die vielen Möglichkeiten Verwirrung stiften, und einige davon nicht zu den individuellen Prozessen des Kunden passen. Auch hier kann man bei uns Menüpunkte "abwählen", aber auch diese Möglichkeit kommunizieren wir nicht aktiv, aus den bereits genannten Gründen.

"b)" nutzt man vor allem, wenn Menüpunkte üblicherweise zur Verfügung stehen, in der aktuellen Situation aber aus bestimmten Gründen nicht. So lässt sich beispielsweise keine Umsatzstatistik abrufen, während an einem anderen Arbeitsplatz soeben die Abrechnung stattfindet (kein sehr gutes Beispiel, und auch kein realistisches, aber es ist ja auch nur ein Beispiel).

Auf "c)" würde ich grundsätzlich verzichten. Ein Menüpunkt, der nicht genutzt werden kann, sollte das auch nicht vortäuschen. Er sollte dann mindestens anzeigen "Die Umsatzstatistik kann derzeit nicht abgerufen werden, weil an Arbeitsplatz XY die Abrechnung stattfindet". Alles andere würde ein Anwender als Fehler interpretieren.

Ich würde um ein "e)" ergänzen, nämlich dynamische Menüs. In unserer Mehrmandantenversion beispielsweise gibt es - je nach aktivem Mandanten - unterschiedlich viele Adressdateien, die über Menüs angesprochen werden können. Beim Mandantenwechsel und/oder bei Veränderungen in diesem Bereich (Löschen oder hinzufügen von Adressdateien) verändert sich das entsprechende Untermenü natürlich.
Herzlich,
Tom
GrillenHirni
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 116
Registriert: Do, 18. Jul 2013 11:56
Kontaktdaten:

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von GrillenHirni »

Lieber Jimmy, lieber Hubert, lieber Tom...

An den Ansatz mit setName hatte ich noch nicht gedacht...!! Damit komm ich der
Sache hoffentlich näher - ich brauch jetzt ein bisschen Zeit, um an meinem
Prototypen herum zu wursteln...

Jimmy - Du warst es, wo in dem obenerwähnten Thread

http://www.xbaseforum.de/viewtopic.php? ... enu#p37989

schliesslich geschrieben hat:

"Dieter hat geschrieben:bei mir funktionieren beide Callback-Slots :beginMenu und :endMenu lediglich im Menusystem des Hauptdialogfensters.
Ja, genau die Callbacks sind von XbpMenuBar() und nicht von XbpMenu()"

Bedeutet das tatsächlich das was ich lese - in einem durch XppMenu():new() erzeugten Menu funktionieren weder ::itemselected noch
::beginMenu und ::endMenu?

Wenn Du das jetzt bestätigst, dann glaub ich es, obwohl es in meinem GrillenHirni den Vereinbarungen der objektorientierten Programmierung
im allgemeinen sowie den Dokumentationen von Alaska im speziellen wiederspricht...?

Hubert möchte ich recht geben, soweit ich ihn verstanden hab - der Inhalt in seinem Beitrag ist der Grund, dass ich nicht einfach das Sample von
Alaska übernehmen möchte - ich würde es dann in meinem Sinne nicht richtig verstehen und einsetzen können... Die Dokumentation darüber hab
ich schon gelesen - auch die Samples angeschaut - jetzt bin ich besonders dankbar für dieses Forum, weil mich zum Beispiel Klaus und Jimmy auf
Ansätze gebracht haben, auf die ich selber mangels Erfahrung einfach nicht gekommen bin...

Und Tom möchte ich sowieso recht geben - ich hab halt die Situation, dass ich zum Beispiel die Optionen eines Menus nicht ausführen lassen
möchte, wenn eine dem Menu zugeordnete Funktion DateiOeffnen("Datei.Dbf") die Datei "Datei.Dbf" nicht erfolgreich geöffnet werden konnte.

Die Funktion DateiOeffnen("Datei.Dbf") gibt dann dem Benutzer die Meldung aus, dass diese Datei nicht vorhanden ist oder nicht geöffnet
werden konnte und wieso und warum - ausserdem gibt sie in dem Fall den Wert .F. zurück.

Für mich ist in dem Fall dem Benutzer etwas mehr geholfen, wenn er weiss, warum die MenuOptionen nicht ausgeführt werden konnten,
als wenn sie dann plötzlich grau disabled sind. Ich kann sie ja dann trotzdem noch grau disabeln, wenn ich hier eine demokratische Mehrheit
dafür finde...

Mein Problem ist aber nicht die Reaktion - ich glaub, ich würde es eventuell schaffen, die MenuOptionen zu disabeln, wenn ich die Situation
überhaupt herstellen könnte, mit der GrundSyntax, die dafür zur Verfügung steht.

Ich habe oMenuBar und dann oMenu, das mit XppMenu():new() erzeugt worden ist. oMenu führt selber keine Aktion aus, enthält aber drei
oder vier Funktionen als MenuOptionen, welche mit oMenu:additem zugeordnet worden sind.

In oMenu müsste ich jetzt die Funktion DateiOeffnen unterbringen - wenn diese den Wert .F. zurück gibt, dann hat sie vorgängig eine
Meldung ausgegeben, warum sie .F. zurück gibt und die Items von oMenu sollten in dem Fall nicht ausgeführt werden - ich kann sie ja
in dem Fall auf allgemeinen Wunsch disabeln (das wäre dann weniger das Problem).

Herzliche Grüsse und einen guten Start in die Woche - mir haben sie grad mein WeihnachtsGeschenk - einen 65"-Fernseher geliefert -
da ist die Woche eigentlich für mich schon gelaufen, aber ich würd mir den gerne noch verdienen und dieses oMenu zum laufen respektive
zum disabeln bringen...

Grilli
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von brandelh »

Das MDI Beispiel ist auf jeden Fall schon ein Brummer, davon habe ich mir mein Framework in Jahrelanger verbesserung erstellt. #
Das ist weder schnell noch einfach machbar, du brauchst einfachere Beispiele, und eines davon steht in der 1.90 Hilfe zu XbpMenuBar() - Klassenfunktion der XbpMenuBar-Klasse direkt drinn:

Code: Alles auswählen

// Menüsystem mit Xbase Parts programmieren 
// Das Beispiel beinhaltet zwei verschiedene Ansätze, wie ein 
// Menü in Xbase++ programmiert werden kann. Es wird ein Menubar 
// in einem XbpCrt-Fenster installiert und dieser bekommt zwei 
// Untermenüs. Das erste Untermenü ist rein prozedural entworfen. 
// Die Steuerung erfolgt über den Callback-Codeblock :itemSelected. 
// Dieser Ansatz ist geeignet, bestehende Menüsysteme, die auf 
// der Kontrollstruktur DO..CASE aufbauen, mit Xbase++ in eine 
// GUI Anwendung zu portieren und dabei bestehenden Programmcode 
// so weit als möglich beizubehalten. Das zweite Submenü nutzt 
// die Fähigkeiten eines XbpMenu-Objekts, dem die Programm- 
// steuerung in Form von Codeblöcken bekannt ist. 

   #include "Appevent.ch" 
   PROCEDURE Main 
      LOCAL nEvent, mp1, mp2, oXbp 
      LOCAL oMenuBar, oSubMenu, aItem 

      Setcolor( "N/W") 

      CLS 

      // Shortcut Keys verwenden 

      SetAppWindow():useShortCuts := .T. 
      // Menüleiste im XbpCrt-Fenster installieren 
      oMenuBar := SetAppWindow():MenuBar() 

      // Untermenü im prozeduralen Stil entwerfen. 
      // Der numerische Index des gewählten Menüeintrags 
      // wird an den Callback-Codeblock übergeben -> mp1 

      oSubMenu       := XbpMenu():new(oMenuBar):create() 
      oSubMenu:title := "~Prozedural" 
      oSubMenu:addItem( { "Prozedur ~1", } ) 
      oSubMenu:addItem( { "Prozedur ~2", } ) 
      oSubMenu:itemSelected := {|mp1| MyMenuProcedure( 100+mp1 ) } 
      oMenuBar:addItem( { oSubMenu, NIL } ) 

      // Untermenü im funktionalen Stil entwerfen: 
      // Ein Menüeintrag führt einen Codeblock aus und ruft 
      // dadurch eine Funktion auf 
      // 
      oSubMenu       := XbpMenu():new(oMenuBar):create() 
      oSubMenu:title := "~Funktional" 
      oSubMenu:addItem( { "Funktion ~1", {|| MyFunction1() } } ) 
      oSubMenu:addItem( { "Funktion ~2", {|| MyFunction2() } } ) 
      oSubMenu:addItem( { "~Ende"      , {|| MyFunction3() } } ) 
      oMenuBar:addItem( { oSubMenu, NIL } ) 

      // Event loop = Programmsteuerung 
      nEvent := 0 
      DO WHILE nEvent <> xbeP_Close 
         nEvent := AppEvent( @mp1, @mp2, @oXbp ) 
         oXbp:HandleEvent( nEvent, mp1, mp2 ) 
      ENDDO 
   RETURN 
   // ************************************************************ 
   // Beispiel für die Integration bestehender Menüsysteme in die 
   // Ereignissteuerung von Xbase++ 
   // 
   PROCEDURE MyMenuProcedure( nMenuSelection ) 
      DO CASE                         // Herkömmliche Menü Indizes 
      CASE nMenuSelection == 101      // mit DO CASE verarbeiten 
           MyProcedure1() 
      CASE nMenuSelection == 102 
           MyProcedure2() 
      ENDCASE 
   RETURN 

   PROCEDURE MyProcedure1() 
      ? "MyProcedure1() wurde aufgerufen" 
   RETURN 

   PROCEDURE MyProcedure2() 
      ? "MyProcedure2() wurde aufgerufen" 
   RETURN 
   // ************************************************************ 
   // Diese Funktionen werden von einem Menü via Codeblock 
   // aufgerufen 
   // 
   FUNCTION MyFunction1() 
      ? "MyFunction1() wurde aufgerufen" 
   RETURN NIL 

   FUNCTION MyFunction2() 
      ? "MyFunction2() wurde aufgerufen" 
   RETURN NIL 

   FUNCTION MyFunction3() 
      ? "MyFunction3() wurde aufgerufen -> Programmende" 
      // Nachricht an das Programm versenden: 
      // Der Benutzer will abbrechen 
      PostAppEvent( xbeP_Close ) 
   RETURN NIL 
ich speichere wichtige Menüpunkte (also welche die ich später noch manipulieren will)
gerne auch in Instanzvariablen als einzelnes Objekt oder als Array mit Objekten im Hauptfenster.
So kann ich direkt darauf zugreifen oder per aEval() komplette Menüoperationen per Array erledigen (z.B. Menüs an Dateianfang, Dateiende, EOF anpassen etc.).

Aber zunächst gilt es in einem einfachen Beispiel wie oben zu probieren was wie funktioniert,
wie man sieht gibt es verschiedene Wege und man muss sich den Besten für sich selbst heraussuchen.

PS: beginMenu und endMenu habe ich noch nie verwendet, eventuell hast du dir etwas anderes darunter vorgestellt.
So wie ich das lese, werden die codeblocks ausgeführt, wenn man das Menü aktiviert bzw. wieder schließt, das ist aber eher für Spezialfälle ... im Moment fällt mir dazu nichts ein.
itemSelected() hingegen ist schon wichtiger wenn man das prozedurale Beispiel ansieht, ich nutze aber immer die funktionale Version.
Nicht zu verwechseln mit "selectItem()- Menüeintrag vorwählen", wobei dieses nichts bewirkt, da "Win32 - Windows unterstützt diese Methode nicht."



Man muss sich etwas gewöhnen, aber dann geht das eigentlich einfacher als meine Verrenkungen um mit MENU TO und ACHOICE unter Clipper :D
Gruß
Hubert
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Conditional Menu:itemSelected,beginMenu,endMenu

Beitrag von Herbert »

Tom hat geschrieben:Ich würde um ein "e)" ergänzen, nämlich dynamische Menüs. In unserer Mehrmandantenversion beispielsweise gibt es - je nach aktivem Mandanten - unterschiedlich viele Adressdateien, die über Menüs angesprochen werden können. Beim Mandantenwechsel und/oder bei Veränderungen in diesem Bereich (Löschen oder hinzufügen von Adressdateien) verändert sich das entsprechende Untermenü natürlich.
Bedingt einverstanden. Wenn du von Untermenüs sprichst, dann ja.
Ich selber benutze ein Programm, das je nach aktivierter Funktion ein Hauptmenüpunkt einbaut, was mich als Bediener sehr verwirrt, denn gemäss der Macht der Gewohnheit folgend ist der oft vorgenommene Mausklick plötzlich weiter rechts zu finden.

Ganz so nebenbei ist SetName() eine sehr hilfreiche Funktion auch für andere Dinge...
Grüsse Herbert
Immer in Bewegung...
Antworten