Seite 1 von 1

trapshift() / Trapanykey()

Verfasst: Fr, 11. Nov 2011 17:23
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

Re: trapshift() / Trapanykey()

Verfasst: Fr, 11. Nov 2011 21:19
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.

Re: trapshift() / Trapanykey()

Verfasst: Fr, 11. Nov 2011 21:45
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

Re: trapshift() / Trapanykey()

Verfasst: Fr, 11. Nov 2011 22:58
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.

Re: trapshift() / Trapanykey()

Verfasst: Mo, 14. Nov 2011 8:45
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

Re: trapshift() / Trapanykey()

Verfasst: Mo, 14. Nov 2011 11:29
von Herbert
Warum sich das Leben schwer machen?
F1 ist die Hilfe-Taste. War auch schon zu DOS-Zeiten so.

Re: trapshift() / Trapanykey()

Verfasst: Mo, 14. Nov 2011 17:14
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.

Re: trapshift() / Trapanykey()

Verfasst: Fr, 18. Nov 2011 9:50
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

Re: trapshift() / Trapanykey()

Verfasst: Fr, 18. Nov 2011 10:47
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

Re: trapshift() / Trapanykey()

Verfasst: Fr, 18. Nov 2011 11:43
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

Re: trapshift() / Trapanykey()

Verfasst: Fr, 18. Nov 2011 12:06
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.

Re: trapshift() / Trapanykey()

Verfasst: Fr, 18. Nov 2011 13:01
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 :(

Re: trapshift() / Trapanykey()

Verfasst: Fr, 18. Nov 2011 20:36
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.

Re: trapshift() / Trapanykey()

Verfasst: Sa, 19. Nov 2011 8:42
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


Re: trapshift() / Trapanykey()

Verfasst: Sa, 19. Nov 2011 9:53
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.