Seite 1 von 1

Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Fr, 21. Nov 2014 10:26
von satmax
Warum funktioniert folgende Zeile nicht:

SetAppEvent( xbeK_CTRL_F1 , { |mp1,mp2,oXbp| tdLaunchPad('MultiLanguage', mp1,mp2,oXbp) } )

Muss da noch etwas berücksichtigt werden, muss das in jedem EventLoop extra abgefragt werden?

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Fr, 21. Nov 2014 10:47
von brandelh
Was erwartest du denn und was passiert wenn du was tust ?

So wie ich die Zeile verstehe, ordnest du den Codeblock der Tastatur Strg+F1 zu.
Da wird man zunächst nichts sehen. Wenn man Strg+F1 drückt, sollte deine Message aufgehen.

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Fr, 21. Nov 2014 10:57
von Tom
Das erklärt die Doku m.E. relativ eindeutig. Es gibt einige Funktionalitäten, die das automatisch berücksichtigen, aber:

In allen anderen Fällen kann der Codeblock mit SetAppEvent() abgefragt werden und muss anschließend durch Aufruf von Eval() ausgeführt werden.

Und zwar in der Eventloop. Siehe Beispiel in der Doku.

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Fr, 21. Nov 2014 16:05
von satmax
Ich habe zum Testen in Mainprogramm folgenden Zeilen hinzugefügt:
(Wobei ich der Meinung war, die erste Zeile sollte reichen um die Function tdLaunchPad() aufzurufen:)

Code: Alles auswählen

SetAppEvent( xbeK_CTRL_F1 , { |mp1,mp2,oXbp| tdLaunchPad('MultiLanguage', mp1,mp2,oXbp) } )
...
   ******* primary event loop
   DO WHILE nEvent <> xbeP_Quit
      nEvent := AppEvent(@mp1,@mp2,@oXbp)
      IF (bBlock := SetAppEvent(nEvent)) <> NIL     // for testing only
             Eval( bBlock, mp1, mp2, oXbp )
             DebugPrint("EVAL")
      ENDIF                                                 // for testing only
      if nEvent ==  (xbeP_User + 1)    
         DebugPrint("xbeP_User+1")
         // Put the CRT and the exe in the foreground
         // see the explanation below on function ReceiverWndProc()
         DllExecuteCall( _tfpSetForegroundWindow_ , SetAppWindow():GetHwnd() )
      else
         oXbp:HandleEvent( nEvent, mp1, mp2 )
      end

   ENDDO


Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Fr, 21. Nov 2014 17:34
von AUGE_OHR
satmax hat geschrieben:Ich habe zum Testen in Mainprogramm folgenden Zeilen hinzugefügt:
(Wobei ich der Meinung war, die erste Zeile sollte reichen um die Function tdLaunchPad() aufzurufen:)
wenn du SetKey() verwendest geht das durch das GET System.
Wenn du SetAppEvent() verwendet wird der Event in die Queue geschoben welche du mit AppEvent() wieder "ausliest"
satmax hat geschrieben:

Code: Alles auswählen

      if nEvent ==  (xbeP_User + 1)    
         DebugPrint("xbeP_User+1")
         // Put the CRT and the exe in the foreground
         // see the explanation below on function ReceiverWndProc()
         DllExecuteCall( _tfpSetForegroundWindow_ , SetAppWindow():GetHwnd() )
Frage : was hast du als (xbeP_User + 1) definiert ?
woher hast du "_tfpSetForegroundWindow_" ?

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Fr, 21. Nov 2014 19:39
von satmax
Hallo Jimmy,

kommt aus Deinen Beispielen. :)

TestWmCopyData.zip:

Code: Alles auswählen

_tfpSetForegroundWindow_ := DllPrepareCall(GetHUser32(),DLL_STDCALL,"SetForegroundWindow")
An andere Stelle gibts dann ein:

Code: Alles auswählen

// SetForegroundWindow()  not always work from external threads of 
// the destination window so we post a custom Xbase++ event and call
// SetForegroundWindow() from the CRT main loop
PostAppEvent(xbeP_User + 1 ,0,0,SetAppWindow())

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Fr, 21. Nov 2014 19:41
von satmax
brandelh hat geschrieben:Was erwartest du denn und was passiert wenn du was tust ?

So wie ich die Zeile verstehe, ordnest du den Codeblock der Tastatur Strg+F1 zu.
Da wird man zunächst nichts sehen. Wenn man Strg+F1 drückt, sollte deine Message aufgehen.
Ich hätte erartet das beim drücken auf die Strg+F1 Taste mein Funktion aufgerufen wird, aber das ist eben nicht der Fall.

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Sa, 22. Nov 2014 0:00
von brandelh
Ich wollte nur klarstellen, dass man genauer schreiben muss was man meint !

Und Tom hatte völlig Recht, dass im unteren Absatz der Hilfe genau erklärt ist, dass SetAppKey() und SetAppEvent() je nach Programmzustand anders reagiert.
In der Hilfe steht das mit Beispiel drinn. Ich hatte nur den ersten Absatz gelesen ;-)

So wie ich das sehe wird aus READ oder MENU etc. direkt der Codeblock ausgeführt, im anderen Fall musst du mit eval() den Codeblock selbst aufrufen.
Im Prinzip ist das ja so wie im alten clipper auch, SET KEY TO ... funktionierte auch nur in READ, Menu etc. nie in einfachen Schleifen.
Dort musste man mit INKEY das Ereignis erkennen und auslösen.

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Mo, 24. Nov 2014 8:07
von satmax
Ich möchte gerne eine F Taste Programmglobal einer bestimmten Funktion zuordnen.

Folgendes habe ich versucht:

Code: Alles auswählen

// keine der folgenden 4 Zeilen bewirkt etwas:
SetAppEvent( xbeK_CTRL_F1 , { |mp1,mp2,oXbp| MsgBox('Test Strg+F1') } )
SetAppEvent( xbeK_CTRL_F2 , { |mp1,mp2,oXbp| MsgBox('Test Strg+F2')  } )
SetAppEvent( xbeK_F3 ,      { |mp1,mp2,oXbp| MsgBox('Test F3')  } )
bBlock := SetKey( xbeK_CTRL_F2, { |mp1,mp2,oXbp| MsgBox('SetKey')  } )

// diese Zeile funktioniert:
SetAppEvent( xbeM_LbClick , { |mp1,mp2,oXbp| MsgBox('Test Maus')  } )
 	
DO WHILE nEvent <> xbeP_Close
	nEvent := AppEvent( @mp1, @mp2, @oXbp, 0 )
	
	IF (bBlock := SetAppEvent(nEvent)) <> NIL
	   Eval( bBlock, mp1, mp2, oXbp )
	
	ELSEIF nEvent < xbeB_Event
      DebugPrint( nEvent )
	
	ELSEIF nEvent == xbeM_RbClick
	  QUIT
	
	ENDIF
ENDDO
Offensichtlich habe ich da einen Denkfehler, warum funktioniert hier keine der Keyboard Tasten, der Mausklick aber schon?

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Mo, 24. Nov 2014 15:34
von AUGE_OHR
hi,
satmax hat geschrieben:Offensichtlich habe ich da einen Denkfehler, warum funktioniert hier keine der Keyboard Tasten, der Mausklick aber schon?
hm ... bei mir funktioniert dein Code ?!

Ich persönlich halte nicht viel von SetAppEvent() denn es "könnte" in jeder Event-Loop reagieren.

auch ist xbeK_* nicht die Konstante für einen Event sondern der "Wert" einer Taste.

Code: Alles auswählen

   CASE nEvent == xbeP_Keyboard .AND. mp1 = xbeK_ESC
der Event ist "xbeP_*" und mp1 ist der "Wert" der Taste

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Mo, 24. Nov 2014 15:55
von satmax
Wenn Du also zB. F3 drückst kommt die Meldung!?

Normal würde ich das auch so nicht verwenden. Die Idee war eher so etwas wie einen Service HOT-Key zu machen. Damit ich im Supportfall eine bestimmte Tastenkombi drücke und etwas nachsehen kann, da sollte dann jeder Event Loop reagieren.

Was ist der richtige Weg für einen Hotkey like F1?

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Mo, 24. Nov 2014 16:01
von AUGE_OHR
satmax hat geschrieben:Wenn Du also zB. F3 drückst kommt die Meldung!?
JA
satmax hat geschrieben:Was ist der richtige Weg für einen Hotkey like F1?
F1 ist ja ein "Sonderfall" weil da gewöhnlich die "Hilfe" dran hängt (siehe XbpHelp() und xbeP_HelpRequest Event )

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Mo, 24. Nov 2014 16:06
von satmax
Wie kann das wieder sein, warum geht das bei mir nicht? Compileroption oder Xbase++ V2?

Code: Alles auswählen

[PROJECT]
    COMPILE       = xpp
    COMPILE_FLAGS = -q -w
    DEBUG         = yes
    GUI           = yes
    LINKER        = alink
    LINK_FLAGS    = 
    RC_COMPILE    = arc
    RC_FLAGS      = -v
    PROJECT.XPJ

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Mo, 24. Nov 2014 17:59
von AUGE_OHR
satmax hat geschrieben:Wie kann das wieder sein, warum geht das bei mir nicht? Compileroption oder Xbase++ V2?
ich habe deinen Code so verwendet

Code: Alles auswählen

#include "Appevent.ch"

PROCEDURE MAIN
LOCAL mp1, mp2, oXbp, nEvent
LOCAL bBlock

   CLS
   // use Mouse Events xbeM_*
   SetMouse(.T.)

   // keine der folgenden 4 Zeilen bewirkt etwas:
   SetAppEvent( xbeK_CTRL_F1 , { |mp1,mp2,oXbp| MsgBox('Test Strg+F1') } )
   SetAppEvent( xbeK_CTRL_F2 , { |mp1,mp2,oXbp| MsgBox('Test Strg+F2')  } )
   SetAppEvent( xbeK_F3 ,      { |mp1,mp2,oXbp| MsgBox('Test F3')  } )

   // geändert auf F4 damit man einen Unterschied hat ... funktionier eh nicht "so"
   bBlock := SetKey( xbeK_F4, { |mp1,mp2,oXbp| MsgBox('SetKey')  } )

   // diese Zeile funktioniert:
   SetAppEvent( xbeM_LbClick , { |mp1,mp2,oXbp| MsgBox('Test Maus')  } )

   DO WHILE nEvent <> xbeP_Close
      nEvent := AppEvent( @mp1, @mp2, @oXbp, 0 )

      IF (bBlock := SetAppEvent(nEvent)) <> NIL
         Eval( bBlock, mp1, mp2, oXbp )

      ELSEIF nEvent < xbeB_Event
*        DebugPrint( nEvent )
?        chr( nEvent )

      ELSEIF nEvent == xbeM_RbClick
        QUIT

      ENDIF
   ENDDO

RETURN
compiliert mit XPP Test1 -w
Alink Test1 /PM:PM

und das kommt dabei raus
SetAppEvent.zip
EXE v1.9.355
(3.45 KiB) 216-mal heruntergeladen

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Mo, 24. Nov 2014 19:53
von satmax
OK Jimmy, mit Deinem Source geht es bei mir auch. Ab dem Zeitpunkt wo ein XpbDialog ins Spiel kommt geht es nicht mehr:

Code: Alles auswählen

FUNCTION Main()
LOCAL oDlg, mp1, mp2, nEvent, oXbp, bBlock

oDlg := XbpDialog():new(,,,,, .F. )
oDlg:taskList                 := .T.
oDlg:clientSize               := { 1024, 600 }
oDlg:drawingArea:clipChildren := .T.
oDlg:title                    := 'Test'
oDlg:create()
oDlg:drawingArea:setFontCompoundName( '9.Arial' )
CenterControl( oDlg )
SetAppWindow( oDlg )

oDlg:show()
SetAppFocus(oDlg)

// keine der folgenden 4 Zeilen bewirkt etwas:
SetAppEvent( xbeK_CTRL_F1 , { |mp1,mp2,oXbp| MsgBox('Test Strg+F1') } )
SetAppEvent( xbeK_CTRL_F2 , { |mp1,mp2,oXbp| MsgBox('Test Strg+F2')  } )
SetAppEvent( xbeK_F3 ,      { |mp1,mp2,oXbp| MsgBox('Test F3')  } )
bBlock := SetKey( xbeK_CTRL_F2, { |mp1,mp2,oXbp| MsgBox('SetKey')  } )

SetAppEvent( xbeK_F2 , { |mp1,mp2,oXbp| MsgBox('Test F2')  } )

// das funktioniert:
SetAppEvent( xbeM_LbClick , { |mp1,mp2,oXbp| MsgBox('Test Maus')  } )
 	


DO WHILE nEvent <> xbeP_Close
	nEvent := AppEvent( @mp1, @mp2, @oXbp, 0 )
	
	IF (bBlock := SetAppEvent(nEvent)) <> NIL
	   Eval( bBlock, mp1, mp2, oXbp )
	
	ELSEIF nEvent < xbeB_Event
	   DebugPrint( nEvent )
	
	ELSEIF nEvent == xbeM_RbClick
	  QUIT
	
	ENDIF
ENDDO
QUIT

RETURN NIL
Ist das so, gibt es eventuell eine Alternative?

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Mo, 24. Nov 2014 21:37
von Wolfgang Ciriack
Ohne jetzt weg. Zeitmangels den ganzen Beitrag gelesen zu haben, aber sollte der Event für SetAppEvent nicht nur xbeP_Keyboard sein und an diesen Codeblock werden dann die Parameter mp1 und mp2 übergeben ?

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Di, 25. Nov 2014 3:54
von AUGE_OHR
satmax hat geschrieben:Ab dem Zeitpunkt wo ein XpbDialog ins Spiel kommt geht es nicht mehr:
Kurz : SetAppEvent() ist nicht für FULL-GUI gedacht wie man denken könnte.
unter Full-GUI ist bei einem Tastendruck der Event immer xbeP_Keyboard (1048580) und mp1 der "Wert" (z.b. xbeK_F3 = 65650)
du benötigst also beides um Tastendruck unter FULL-GUI auszuwerten

Code: Alles auswählen

   CASE nEvent == xbeP_Keyboard .AND. mp1 = xbeK_F3
lang : das hat mit Windows zu tun wo bei jeder User Aktion ein WM_* Event erzeugt wird.
wenn die Controls einen Tastendruck nicht selbst auswerten ( wie ein o:Keyboard Slot ) dann wird es an den "Parent" weitergeleitet.
der "Parent" bei meinen native Controls ist ein XbpStatic der es durch die Xbase++ Queue weiterleitet an das "Fenster" was nun sein "Parent" ist.
Durch das Prinzip sind überhaupt erst "Fenster" möglich was typisch für Windows ist.

btw.
Wenn man ein PostAppEvent(xbeP_Keyboard,xbeK_*,,oXbp) verschickt ist der 4th. Parameter (oXbp) gewöhnlich das "Fenster".

Re: Frage zu SetAppEvent( xbeK_CTRL_F1 , ...

Verfasst: Di, 25. Nov 2014 10:08
von satmax
Kurz : SetAppEvent() ist nicht für FULL-GUI gedacht wie man denken könnte.
Danke Jimmy, das hätte Alaska auch gleich in die Hilfe schreiben können. :?