Dynamisches Kontextmenu in xbpBrowse [Erledigt]

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Dieter
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 237
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen
Hat sich bedankt: 2 Mal
Danksagung erhalten: 3 Mal

Dynamisches Kontextmenu in xbpBrowse [Erledigt]

Beitrag von Dieter »

Hallo,

kann man eigentlich ein Kontextmenü in einem xbpBrowse dynamisch programmieren? Gemeint ist damit, dass sich das Kontextmenü in Abhängigkeit von der Browserfeldposition verändert? Hat das schon jemand gemacht?
Zuletzt geändert von Dieter am Mo, 06. Dez 2010 17:15, insgesamt 2-mal geändert.
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
Rolf
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 258
Registriert: Do, 27. Apr 2006 12:28
Wohnort: Görlitz

Re: Dynamisches Kontextmenu in xbpBrowse

Beitrag von Rolf »

Hallo Dieter

Das Grundgerüst ohne den "dynamischen" Faktor sieht so aus:
aus der initBorwse() d.h. Browser erzeugt Spalten hinzugefügt.

Code: Alles auswählen

    //-- Kontext Menue erzeugen
    ::oContextMenu := ::createContextMenu( oBrowse )
    //-- Kontext Menue öffnen
    oBrowse:itemRbDown:= {|aPos, aRC, obj|  obj:navigate( XBPBRW_Navigate_Skip, aRC[ 1 ] - obj:rowPos     ),; //-- Synchronisation von
                                            obj:navigate( XBPBRW_Navigate_SkipCols, aRC[ 2 ] - obj:colPos ),; //-- Click und Browser
                                            ::oContextMenu:popUp( obj, aPos )  }   //-- Popupmenu öffnen
Auszug aus createContextMenu

Code: Alles auswählen

METHOD dlgD:createContextMenu(oBrowse)
    //** DEC VAR
    LOCAL oMenu     := NIL

    //** Haupt-Menu
    oMenu := XbpMenu( oBrowse ):new():create()
    oMenu:addItem( { "Kopieren"             , {|| ::copyClipboard()         } } )
RETURN oMenu
Mit rowPos oder colPos hast du die aktuelle Zelle in der Tabelle und mit
::oContextMenu auch das Menu-Object und dies müsste man modifizieren können.

Liebe Grüße
Rolf
Dieter
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 237
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen
Hat sich bedankt: 2 Mal
Danksagung erhalten: 3 Mal

Re: Dynamisches Kontextmenu in xbpBrowse

Beitrag von Dieter »

Hallo Rolf,

vielen Dank für die schnelle Antwort. Mit einem oRightMenu:beginMenu-Codeblock ist die Lösung wirklich einfach. :D
Getrennt von den Kontextmenü-Funktionen kann man somit alle zusätzlichen Eigenschaften einer Browserzelle anzeigen lassen.
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12913
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: Dynamisches Kontextmenu in xbpBrowse

Beitrag von AUGE_OHR »

Rolf hat geschrieben:

Code: Alles auswählen

//-- Kontext Menue öffnen
oBrowse:itemRbDown:= {|aPos, aRC, obj|  obj:navigate( XBPBRW_Navigate_Skip, aRC[ 1 ] - obj:rowPos     ),; //-- Synchronisation von
                 obj:navigate( XBPBRW_Navigate_SkipCols, aRC[ 2 ] - obj:colPos ),; //-- Click und Browser
                                            ::oContextMenu:popUp( obj, aPos )  }   //-- Popupmenu öffnen
Wow gute Idee =D>

ich habe es mit

Code: Alles auswählen

FUNCTION GetCursorPos()
LOCAL sPoint := REPLICATE(CHR(0),8)
LOCAL nX     := 0
LOCAL nY     := 0

STATIC GetCursorPos

   IF GetCursorPos = NIL
      GetCursorPos := DllPrepareCall("user32.dll",DLL_STDCALL,;
                                                 "GetCursorPos")
   ENDIF
   DllExecuteCall(GetCursorPos,@sPoint)

   nX := BIN2L(SUBSTR(sPoint,1,4))                          
   nY := BIN2L(SUBSTR(sPoint,5,4))                          

   nY := (- 1 * nY)+APPDESKTOP():CURRENTSIZE()[2] - 1      // from Top to Down

RETURN ({nX,nY})
gelöst welches mit die "aktuelle" Position am Bildschirm gibt.
Will ich das nun auf ein "Fenster" beziehen so muss ich das noch "umrechnen" mit

Code: Alles auswählen

FUNCTION PopAbsPos(oDlg)
LOCAL aPos := {0,0}
LOCAL aDlg := oDlg:currentpos()
LOCAL aAbs := GetCursorPos()

   aPos[ 1 ] := aAbs[1] - aDlg[1]
   aPos[ 2 ] := aAbs[2] - aDlg[2]

RETURN aPos
und hatte damit die "relative" Position bezogen auf das "Fenster".

Ein Pop-up Menu könnte also so aussehen

Code: Alles auswählen

PROCEDURE PopTransparents(oDlg,aDLGOWNER)
LOCAL oSubMenu
LOCAL aPos     := PopAbsPos(oDlg)

   oSubMenu       := XbpMenu():new(oDlg)
   oSubMenu:title := "~Transparenz"
   oSubMenu:create()

   oSubMenu:addItem({"  ~0 %",{|| SP_TPZ(0),AllTPZ(aDLGOWNER)},,})
   ...
   oSubMenu:addItem({" ~90 %",{|| SP_TPZ(90),AllTPZ(aDLGOWNER)},,})

   oSubMenu:PopUp(oDlg,aPos,2,;
                       XBPMENU_PU_DEFAULT+XBPMENU_PU_MOUSE_RBDOWN)
RETURN
Es wird also das Pop-up Menu genau an der Stelle angezeigt wo sich gerade die Maus befindet
gruss by OHR
Jimmy
Dieter
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 237
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen
Hat sich bedankt: 2 Mal
Danksagung erhalten: 3 Mal

Re: Dynamisches Kontextmenu in xbpBrowse [Erledigt]

Beitrag von Dieter »

Hallo Jimmy,

deine Positionierung des Kontextmenüs beim Drücken der rechten
Maustaste bezieht sich allgemein auf ein Fenster. Bei einem xbpBrowse sind
aber auch die relativen Zeilen- und Spaltennummern und darüber hinaus die
absolute Zeilennummer des Datenarrays oder der Datenbank wichtig. Die
Positionierung des Menüs an der richtigen Browserzelle ist hier im Forum schon
mehrfach erörtert worden. Ich selbst nutze hierzu einen Vorschlag von Wolfgang
Ciriack in einer abgewandelten Form wie folgt:

Code: Alles auswählen

FUNCTION ActRbMenu(aMPos,aLC,oBr,oRightMenu)
** Erzeugt ein Kontextmenu an der Stelle, an der mit
** der rechten Maustaste geklickt wurde
** aLC   Array(2) mit Zeilen-(Line) und Spaltenposition
** siehe Slot :itemRbDown := {| aMousePos, aRowCol, self | ... }

local nRight:=0, nLeft:=0, nUp:=0, nDown:=0, i:=0
nRight:=aLC[2] - oBr:ColPos
nDown :=aLC[1] - oBr:RowPos
if nRight < 0
   nLeft:=nRight * -1
endif
if nDown < 0
   nUp:=nDown * -1
endif
for i:=1 to nUp
   oBr:up()
next
for i:=1 to nDown
   oBr:down()
next
for i:=1 to nRight
   oBr:right()
next
for i:=1 to nLeft
   oBr:left()
next
oBr:RefreshAll()
oRightMenu:Popup(oBr,aMPos)
return NIL

*** in Kombination mit ***

oBrowse:itemRbDown := {| aMousePos, aRowCol, oBrowse | ActRbMenu(aMousePos,aRowCol,oBrowse,oRightMenu) }
Mit "dynamisch" meinte ich eigentlich nicht die Positionierung an der
richtigen Stelle, sondern dass jedes Browserfeld in Abhängigkeit von der
Spalten- und Zeilennummer und meinetwegen auch von dem Inhalt ein eigenes
Kontextmenü mit unterschiedlich vielen Menüeinträgen hat.

Vielen Dank jedoch für den interessanten Code, den man sicherlich in Fenstern
ohne xbpBrowse gut einsetzen kann.
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
Rolf
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 258
Registriert: Do, 27. Apr 2006 12:28
Wohnort: Görlitz

Re: Dynamisches Kontextmenu in xbpBrowse

Beitrag von Rolf »

@Jimmy
AUGE_OHR hat geschrieben:Wow gute Idee =D>
Ja, aber nicht von mir, wie schon von Dieter erwähnt, wurde das Thema schon mehrfach erläutert.
Der Code von oben ist hier aus dem Forum oder aus dem Alaska-Forum. Von wem hab ich mir leider nicht notiert.

@Dieter
Dieter hat geschrieben:Mit einem oRightMenu:beginMenu-Codeblock ist die Lösung wirklich einfach
Könntest du bitte zu dieser Bemerkung noch ein paar Sätze verlieren. Wie sieht deine Umsetzung nun aus.

Liebe Grüße
Rolf
Dieter
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 237
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen
Hat sich bedankt: 2 Mal
Danksagung erhalten: 3 Mal

Re: Dynamisches Kontextmenu in xbpBrowse [Erledigt]

Beitrag von Dieter »

Hallo Rolf,

es werden zwei Codeblock-Slots benötigt:

Code: Alles auswählen

oBrowse:itemRbDown := {| aMousePos, aRowCol, oBrowse | ActRbMenu(aMousePos,aRowCol,oBrowse,oRightMenu) }
Hiermit wird das normale Kontextmenü an der richtigen Browserzelle aufgerufen.

Code: Alles auswählen

oRightMenu:BeginMenu:={|| zeigeUser(oBrowse,oRightmenu)}
Wenn das Kontextmenu aufgerufen wird, dann greift dieser Codeblock. Wie du
schon in deiner ersten Mail gesagt hast, benötigt man das Browser-Objekt und
das Menu-Objekt, um ein erweitertes Kontextmenü zu bauen. Das geschieht in der
Funktion zeigeUser. In meinem Fall wollte ich unterhalb der Kontextfunktionen
angeben, welcher User die letzte Dateneingabe in ein Browserfeld gemacht hat.
Über das Browser-Objekt wird nun cUser berechnet und anschließend wird mit

Code: Alles auswählen

  oRMenu:setItem(oRMenu:numItems(),{cUser,NIL} )
  oRMenu:configure()
das Kontextmenü neu konfiguriert.
Als kleinen Trick habe ich im normalen Kontextmenü mit

Code: Alles auswählen

oRightMenu:AddItem({"",NIL } )
einen DUMMY-Menüeintrag vorgewählt.
Das kann man sicherlich auch anders machen.

Ich hoffe, dass die grundsätzliche Vorgehensweise jetzt klar ist.
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
Antworten