trapshift() / Trapanykey()

Auf dem Weg von Clipper, FoxPro u.ä. nach Xbase++

Moderator: Moderatoren

Antworten
Eckhard Sallermann
UDF-Programmierer
UDF-Programmierer
Beiträge: 88
Registriert: Fr, 29. Jun 2007 13:32
Wohnort: 33330 Gütersloh
Kontaktdaten:

trapshift() / Trapanykey()

Beitrag von Eckhard Sallermann »

Tach zusammen,

Gibt es eine Möglichkeit, etwas, wie in Clipper mit Trapshift() zu implenentieren, so dass
man überall im Programm eine Funktion aufrufen kann, wenn die ALT-taste gedrückt wird ?

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

Re: trapshift() / Trapanykey()

Beitrag von brandelh »

Hi,

wenn die ALT Taste allein einen Event erzeugt - vermutlich eher einen Keyboardevent mit speziellem KEY, kann man den z.B. in der Eventloop abfangen, dann gilt er im ganzen Programm.
Ob dies aber so ist, weiß ich nicht.
Gruß
Hubert
manni1729
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 30
Registriert: Mi, 04. Jun 2008 14:18
Wohnort: Nordhessen

Re: trapshift() / Trapanykey()

Beitrag von manni1729 »

brandelh hat geschrieben:Hi,

wenn die ALT Taste allein einen Event erzeugt - vermutlich eher einen Keyboardevent mit speziellem KEY, kann man den z.B. in der Eventloop abfangen, dann gilt er im ganzen Programm.
Ob dies aber so ist, weiß ich nicht.
Hi,
die ALT Taste allein erzeugt kein Event. Man kann sie aber mit KeyStat() abfragen ob sie gedrückt wurde. Das geht auch mit Shift+Ctrl

Gruß Manni
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: trapshift() / Trapanykey()

Beitrag von AUGE_OHR »

manni1729 hat geschrieben:Man kann sie aber mit KeyStat() abfragen ob sie gedrückt wurde. Das geht auch mit Shift+Ctrl
du meinst sicherlich AppKeyState() denn KbdStat() aus den Tools will man ja wie die Trap* Functionen loswerden.
gruss by OHR
Jimmy
Eckhard Sallermann
UDF-Programmierer
UDF-Programmierer
Beiträge: 88
Registriert: Fr, 29. Jun 2007 13:32
Wohnort: 33330 Gütersloh
Kontaktdaten:

Re: trapshift() / Trapanykey()

Beitrag von Eckhard Sallermann »

Na ja, wenn das Programm mit Inkey(0) auf einen Tastendruck wartet und der Benutzer dann die ALT-Taste drückt, dann soll ein Hilfemenue angezeigt werden
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: trapshift() / Trapanykey()

Beitrag von Herbert »

Warum sich das Leben schwer machen?
F1 ist die Hilfe-Taste. War auch schon zu DOS-Zeiten so.
Grüsse Herbert
Immer in Bewegung...
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: trapshift() / Trapanykey()

Beitrag von AUGE_OHR »

Eckhard Sallermann hat geschrieben:Na ja, wenn das Programm mit Inkey(0) auf einen Tastendruck wartet und der Benutzer dann die ALT-Taste drückt, dann soll ein Hilfemenue angezeigt werden
ob das "so" geht hab ich noch nicht probiert ... aber da das "procedural" gedacht ist denke ich eher nicht.
siehe dir mal das Demo zu AppKeyState() an wie das in eine Event loop läuft.
gruss by OHR
Jimmy
Eckhard Sallermann
UDF-Programmierer
UDF-Programmierer
Beiträge: 88
Registriert: Fr, 29. Jun 2007 13:32
Wohnort: 33330 Gütersloh
Kontaktdaten:

Re: trapshift() / Trapanykey()

Beitrag von Eckhard Sallermann »

Gibt es denn keine Möglichkeit überall im Programm eine Routine zu starten, sobald die ALT-GR-Taste betätigt wird ?

Nachtrag: also es geht nicht um eine GUI-Anwendung
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: trapshift() / Trapanykey()

Beitrag von AUGE_OHR »

Eckhard Sallermann hat geschrieben:Gibt es denn keine Möglichkeit überall im Programm eine Routine zu starten, sobald die ALT-GR-Taste betätigt wird ?
siehe dir mal http://www.xbaseforum.de/viewtopic.php?f=16&t=5693 an. ALT-GR -> Ctrl-ALT
Eckhard Sallermann hat geschrieben:Nachtrag: also es geht nicht um eine GUI-Anwendung
dann musst du statt den 4th parameter von AppEvenet() eben SetTimerEvent() verwenden
gruss by OHR
Jimmy
Eckhard Sallermann
UDF-Programmierer
UDF-Programmierer
Beiträge: 88
Registriert: Fr, 29. Jun 2007 13:32
Wohnort: 33330 Gütersloh
Kontaktdaten:

Re: trapshift() / Trapanykey()

Beitrag von Eckhard Sallermann »

So etwas habe ich schon versucht, allerdings kann ich dann keine Tasten abfragen, während ich in der Schleife bin

Code: Alles auswählen

SetTimerEvent(10, {|| CheckKeyboard() } ) 

function CheckKeyboard()
local nrow 
local ncol 
local o_Scr 
local nColor 
local nCursor
local p_getlist 

if AppKeyState( xbeK_CTRL  ) = APPKEY_DOWN
	nrow := row()
	ncol := col()
	p_getlist := save_gets()
	nCursor := setcursor()
	o_Scr := savescreen( 4,0,maxrow(),maxcol())
	nColor := setcolor()
	setcursor(0)
	setcolor("n/bg,n/bg,,,n/bg")
	@  6,10 clear to 9,69
	@  6,10 to 9,69

	@  7,12 say "ALTGR-B"                                                  color "w+/bg,w+/bg,,,w+/bg"
	@  7,21 say "= Aktuellen Bildschirminhalt drucken"                     color "n/bg,n/bg,,,n/bg"

	@  8,12 say "ALTGR-M"                                                  color "w+/bg,w+/bg,,,w+/bg"
	@  8,21 say "= Mandant andern"                                         color "n/bg,n/bg,,,n/bg"
	clear typeahead
	set typeahead to 0
	set typeahead to 32
	While TRUE
	   n_key := inkey(0.1)
	   // n_Key := AppEvent( @mp1, @mp2, @oXbp , 1 )
	   @ 0,0 say time() 
	   @ 1,0 say n_key
	   @ 2,0 say nextkey()
	   do case
		   case upper(chr(n_key)) == "B"
			   Restscreen(4, 0, maxrow(), maxcol(), p_scr )  // alten Bildschirm
			   prn_scr()
		   case n_key = 230     // K_ALT_M
			   Restscreen(4, 0, maxrow(), maxcol(), p_scr )  // alten Bildschirm
			   GetMandant()
		   otherwise
			   if !n_key = 0
				   chis := right( keyread() , 2 )
				   keysend( chis , TRUE )
			   endif
	   endcase
		if !AppKeyState( xbeK_CTRL  ) = APPKEY_DOWN
			exit
		endif
	Enddo
	rest_gets( p_getlist )
	setcursor( nCursor )
	setcolor( nColor )
	restscreen( 4,0,maxrow(),maxcol() , o_Scr )	
	setpos( nrow, ncol )

endif
return NIL
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: trapshift() / Trapanykey()

Beitrag von AUGE_OHR »

Eckhard Sallermann hat geschrieben:So etwas habe ich schon versucht, allerdings kann ich dann keine Tasten abfragen, während ich in der Schleife bin
mit SetTimerEvent() wird ein Thread aufgerufen der dir den "Zustand" der Tasten ermitteln worauf er eine "Aktion" auf den "Rückgabe" Wert erfolgt soll.

es müsste also etwa so aussehen ( nicht getestet )

Code: Alles auswählen

PROCEDURE MAIN
PRIVATE myState := 0 
STATIC nLast  := 0

SetTimerEvent(10, {|| myState := CheckKeyboard() } ) 
...

   While TRUE
      n_key := inkey(0.1)
      do case
         case nLast <> myState
              nLast := myState
             // hier "Aktion"
             DO CASE
                CASE myState = 2
                CASE myState = 4
                CASE myState = 8


function CheckKeyboard()
LOCAL nState := 0
 
   // Anzeige ob Thread läuft
   @0,0 TIME()

   IF APPKEY_DOWN = AppKeyState( xbeK_SHIFT )
      nState += 2
   ENDIF
   IF APPKEY_DOWN = AppKeyState( xbeK_CTRL  )
      nState += 4
   ENDIF
   IF APPKEY_DOWN = AppKeyState( xbeK_ALT    )
      nState += 8
   ENDIF
return nState
probiere es mal aus ob der Thread so läuft und du links/oben die Uhrzeit am laufen hast.
gruss by OHR
Jimmy
Eckhard Sallermann
UDF-Programmierer
UDF-Programmierer
Beiträge: 88
Registriert: Fr, 29. Jun 2007 13:32
Wohnort: 33330 Gütersloh
Kontaktdaten:

Re: trapshift() / Trapanykey()

Beitrag von Eckhard Sallermann »

Hi Jimmy,

das nützt mir aber doch nicht wirklich etwas, ich möchte doch überall im der App etwas machen, wenn die ALT-GR-Taste betätigt wird.
In deinem Beispiel müsste ich das dann ja überall abfragen.

Ich dachte eher, dass man in der CheckKeyboard() Funktion schon abfragen kann, welche Taste zusätzlich gedrückt wird :(
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: trapshift() / Trapanykey()

Beitrag von AUGE_OHR »

Eckhard Sallermann hat geschrieben:das nützt mir aber doch nicht wirklich etwas, ich möchte doch überall im der App etwas machen, wenn die ALT-GR-Taste betätigt wird.
In deinem Beispiel müsste ich das dann ja überall abfragen.
ich hatte zwischendurch hier mal eine Idee mit Code angerissen.
nach einigen Test musste ich feststellen das ich nicht weiss wie ich bei eine VIO Application einen weitern Thread laufen lassen soll der bei einem "aktiven" GET "eingreifen" könnte.

Code: Alles auswählen

PROCEDURE MachMal()
    CLEAR
    TRAPSHIFT("Trap_ALT", 8)
    Var1 := SPACE(50)
    Var2 := SPACE(50)
    @ 10,20 GET Var1
    @ 11,20 GET Var2
    READ
    TRAPSHIFT()
RETURN

PROCEDURE  TRAPSHIFT(cProc, nStatus)
LOCAL cString 

   IF PCOUNT()  > 0
      Schalt_OnOff(.T.)
      cString := "{||"+cProc+"("+LTRIM(STR(nStatus))+") }"
      EVAL( &cString )
   ELSE
      Schalt_OnOff(.F.)
   ENDIF
RETURN

PROCEDURE Trap_ALT(nStatus)

   InVar   := INKEY(0.1) -> 0
   nEvent := nEvent := AppEvent( @mp1, @mp2, @oXbp, 0 ) -> 0
soweit sogut aber in Trap_ALT() bekomme ich nichts in der Schleife wenn das GET "aktive" ist.
man müsste also mal sehen ob man das mit einem eigenen "modifizierten" GET Reader machen "könnte" ...

nun habe ich mir SetKey(), für VIO & Hybrid, noch mal angesehen und die INKEY.CH durchforstet.
ALT-GR == CTRL_ALT gibt es nicht also keine Chance mit SetKey().

Frage : warum brauchst du CTRL_ALT ? ich pflege damit die ShortCut Links auf dem Desktop zu belegen.
gruss by OHR
Jimmy
Eckhard Sallermann
UDF-Programmierer
UDF-Programmierer
Beiträge: 88
Registriert: Fr, 29. Jun 2007 13:32
Wohnort: 33330 Gütersloh
Kontaktdaten:

Re: trapshift() / Trapanykey()

Beitrag von Eckhard Sallermann »

Inzwischen habe ich Code von Alaska bekommen . . . Die XBTools habe ich auch

Code: Alles auswählen

#ifdef __XPP__
#pragma library( "xbtbase1.lib" )
#pragma library( "xbtbase2.lib" )
#endif

PROCEDURE Main()
  CLEAR
    TRAPSHIFT("Trap_ALT", 8)
    Var1 := SPACE(50)
    Var2 := SPACE(50)
    @ 10,20 GET Var1
    @ 11,20 GET Var2
    READ
    TRAPSHIFT()
  RETURN


  PROCEDURE Trap_ALT( Status )
    @ MAXROW(), 0 SAY " ........ ALT ist gedrckt ........ "
    InVar := 0
    DO WHILE NUMAND(KBDSTAT(), 8) = 8 .AND. InVar = 0
      InVar := INKEY()
    ENDDO
    DO CASE
      CASE InVar = 306      // ALT-M
      KEYSEND(CHARMIX("Mit freundlichen Gráen", CHR(0)), .T.)
    ENDCASE
    @ MAXROW(), 0
  RETURN


#ifdef __XPP__
#include "appevent.ch"
#define xbeTS_CallProc xbeP_User 

function TrapShift( cProc, nMask, nMilliSecs )
 LOCAL cRet := ""
 STATIC oThread

   IF oThread != NIL
      cRet := oThread:Cargo
   ENDIF

   IF Empty(cProc) == .T.
      IF oThread != NIL
         oThread:SetInterval( 0 )
         oThread := NIL

         SetAppEvent( xbeTS_CallProc, NIL )
      ENDIF

      RETURN cRet      
   ENDIF

   IF IsFunction(cProc) == .F.
      XbpException():RaiseParameterValue( {cProc,nMask,nMilliSecs} )
   ENDIF

   IF Empty(nMilliSecs) == .T.
      nMilliSecs := 10
   ENDIF

   IF oThread == NIL
      oThread := Thread():New()
      oThread:Cargo := cProc
      oThread:SetInterval( nMilliSecs )
      oThread:Start( {|| TrapCheck(oThread:Cargo, nMask)} )

      SetAppEvent( xbeTS_CallProc, {|cProc,nStat| &(cProc)(nStat)} )
   ENDIF

RETURN cRet


function TrapCheck( cProc, nMask )
 LOCAL nStat := KbdStat()

   IF NumAnd(nStat,nMask)==nMask
      PostAppEvent( xbeTS_CallProc, cProc, nStat )
   ENDIF
RETURN

#endif

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: trapshift() / Trapanykey()

Beitrag von AUGE_OHR »

Eckhard Sallermann hat geschrieben:

Code: Alles auswählen

      KEYSEND(CHARMIX("Mit freundlichen Gráen", CHR(0)), .T.)
aha !!! also per KeySend() in die Event Queue.
... dabei wird doch gesagt
This function exists for compatibility reasons only. A key code is build from its ASCII code and the keyboard scan code. This can lead to problems especially when programming in GUI mode and/or using different keyboards. It is strongly recommended not to use KeySend() but PostAppEvent().
der Trick es in die "Main Queue" zu bekommen ist wohl

Code: Alles auswählen

SetAppEvent( xbeTS_CallProc, {|cProc,nStat| &(cProc)(nStat)} )
was ich "so" auch noch noch gesehen habe.
gruss by OHR
Jimmy
Antworten