Seite 1 von 1

Hotkey einstellen

Verfasst: Mi, 28. Apr 2021 10:50
von Jan
Moin,

gerade bin ich etwas am verzweifeln. Vielleicht hat da jemand eine Idee.

Das Programm ist zwar kompiliert mit /ga, aber die Oberfläche ist zeichenbasiert. Es gibt auch keine Haupt-Eventschleife, da es bis auf wenige Ausnahmen keine GUI-Elemente da drin gibt - die haben dann natürlich jeweils ihre eigene Event-Schleife.

Was ich jetzt machen muß: Ein Wert muß in die Zwischenablage geschrieben werden. Und dann muß ich einen Hotkey aufrufen, damit ein anderes Programm sich den Inhalt der Zwischenablage abholt und passend verarbeiten kann. Das alles soll der Benutzer nicht selber machen, sondern automatisch passieren, wenn der Benutzer die entsprechende Funktion aufruft.

Ansich klappt alles im Debugger: Der Wert ist korrekt in der Zwischenablage. PostAppEvent(nHotkey) gibt mir ein .T. zurück. Das folgende AppEvent() gibt mir den nHotkey ganz korrekt zurück. Also eigentlich alles ganz super. Nur das andere Programm bekommt nichts. Nur wenn ich dann wirklich in die Hardware greife und den Hotkey drücke, dann kommt da was an.

Wo ist da mein Denkfehler?

Jan

Re: Hotkey einstellen

Verfasst: Mi, 28. Apr 2021 11:45
von georg
Hallo, Jan -


liegt wohl daran, dass Du das Event innerhalb Deines Programms erzeugst, darum bekommt das andere Programm das nicht mit.

Re: Hotkey einstellen

Verfasst: Mi, 28. Apr 2021 11:55
von Jan
Georg,

und wie bekomme ich den dann nach außen transportiert?

Jan

Re: Hotkey einstellen

Verfasst: Mi, 28. Apr 2021 12:08
von ramses
Zum Beispiel mit der SendInput funktion aus der User32.dll von Windows.

Re: Hotkey einstellen

Verfasst: Mi, 28. Apr 2021 12:44
von Jan
Hallo Carlo,

gute Idee. Da steh ich dann jetzt aber auf dem Schlauch wie ich das Array da übergeben kann. Alaska hat da zwar sein EXTERN mit dem letzten Update wieder erweitert, aber Arrays wie wir sie kennen gehen da halt (noch) nicht.

Jan

Re: Hotkey einstellen

Verfasst: Mi, 28. Apr 2021 13:09
von ramses
Hallo Jan

so wie ich mich errinnere benötigts du eine Struktur oder einfach einen entsprechend aufgebauten String und pro Taste 2 Aufrufe:
1. Taste drücken
2. Taste loslassen

Ich gehe es mal im Projekt suchen.

Re: Hotkey einstellen

Verfasst: Mi, 28. Apr 2021 13:26
von Jan
Carlo,

das wäre super!

Mir fällt gerade ein: Hatte Alaska nicht auch ein STRUCTURE eingebaut, mit dem Arrays passend umgebaut werden können?

Jan

Re: Hotkey einstellen

Verfasst: Mi, 28. Apr 2021 21:07
von ramses
Hallo Jan

musste unvorhergesehen Arbeit für die nächsten Tage vorbereiten gehen und konnte den Code noch nicht suchen.
Hole das nach wenn ich zurück bin.

Re: Hotkey einstellen

Verfasst: Fr, 30. Apr 2021 5:20
von AUGE_OHR
hi,
ramses hat geschrieben: Mi, 28. Apr 2021 12:08 Zum Beispiel mit der SendInput funktion aus der User32.dll von Windows.
und woher "weiss" die "andere" App von dem "Input" :?:
solange du kein Handle vom "Ziel" hast wird nichts dort an kommen.

Re: Hotkey einstellen

Verfasst: Fr, 30. Apr 2021 5:30
von AUGE_OHR
hier ein Beispiel für SendInput. Es ist mit Ot4xb

Code: Alles auswählen

#include "ot4xb.ch"
//-----------------------------------------------------------------------------------------------------------------------
#define INPUT_MOUSE     0
#define INPUT_KEYBOARD  1
#define INPUT_HARDWARE  2

// ---------------------------------------------------------------------------
function Main()
local oInput   := Input():New()
local nEvents  :=  4
local nSize    := oInput:_sizeof_()
local pBuffer  := _xgrab( nSize * nEvents  )
local n , nn


// MOVING THE MOUSE
for nn := 1 to 1

    oInput:_link_( pBuffer , .F.)
    oInput:type       := INPUT_MOUSE
    oInput:mi:dwFlags := nOr( 0x8000 , 0x0001 ) // ( MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE )
    @user32:SendInput(1 , pBuffer , nSize)

    for n := 1 to 50
       oInput:_zeromemory_()
       oInput:type       := INPUT_MOUSE
       oInput:mi:dx      := 5
       oInput:mi:dy      := 5
       oInput:mi:dwFlags := 0x0001 // MOUSEEVENTF_MOVE
       @user32:SendInput( 1, pBuffer , nSize)
       Sleep( 10 )
    next
next

// SENDING KEYSTROKES
oInput:_zeromemory_()
oInput:type       := INPUT_KEYBOARD
oInput:ki:wVk     := 0x5B // VK_LWIN

GwstArrayNext(oInput)
oInput:type       := INPUT_KEYBOARD
oInput:ki:wVk     := 0x5B // VK_LWIN
oInput:ki:dwFlags := 0x0002 // KEYEVENTF_KEYUP

GwstArrayNext(oInput)
oInput:type       := INPUT_KEYBOARD
oInput:ki:wVk     := 27 // Esc.
                                  
GwstArrayNext(oInput)
oInput:type       := INPUT_KEYBOARD
oInput:ki:wVk     := 27 // Esc.
oInput:ki:dwFlags := 0x0002 // KEYEVENTF_KEYUP


for n := 1 to 20
   @user32:SendInput( nEvents, pBuffer , nSize)
   Sleep( 30 )
next

oInput:_unlink_()
_xfree( pBuffer)

return NIL
//-------------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------
BEGIN STRUCTURE INPUT
   MEMBER DWORD type
   BEGIN UNION
   MEMBER @MOUSEINPUT mi
   MEMBER @KEYBDINPUT ki
   MEMBER @HARDWAREINPUT hi
   END UNION
END STRUCTURE // 28 // BYTES
// ---------------------------------------------------------------------------
BEGIN STRUCTURE MOUSEINPUT
    MEMBER LONG dx
    MEMBER LONG dy
    MEMBER DWORD mouseData
    MEMBER DWORD dwFlags
    MEMBER DWORD time
    MEMBER DWORD dwExtraInfo
END STRUCTURE // 24 BYTES
//-----------------------------------------------------------------------------------------------------------------------
BEGIN STRUCTURE KEYBDINPUT
    MEMBER WORD wVk
    MEMBER WORD wScan
    MEMBER DWORD dwFlags
    MEMBER DWORD time
    MEMBER DWORD dwExtraInfo
END STRUCTURE // 16
//-----------------------------------------------------------------------------------------------------------------------
BEGIN STRUCTURE HARDWAREINPUT
    MEMBER DWORD uMsg
    MEMBER WORD wParamL
    MEMBER WORD wParamH
END STRUCTURE // 8
//-----------------------------------------------------------------------------------------------------------------------


Re: Hotkey einstellen

Verfasst: Fr, 30. Apr 2021 20:44
von ramses
AUGE_OHR hat geschrieben: Fr, 30. Apr 2021 5:20 und woher "weiss" die "andere" App von dem "Input" :?:
Genau. Es war mir dass da noch was fehlt.
Die Ziel-App muss zuerst irgendwie den Focus erhalten!
Ist mir heute Nacht bein nachdenken in Regensburg eingefallen.
Leider habe ich den Code nicht mehr.
Es was damals eine Auftragsarbeit die ich anschliessend vollständig abgegeben habe.

Nur andere Funktion zum suchen des Prozess-Handels anhand des EXE Namens habe ich noch. (mit ot4xb)

Re: Hotkey einstellen

Verfasst: Sa, 01. Mai 2021 18:20
von ramses
Hallo

ich habe doch noch was in den Unterlagen gefunden wie die Lösung damals war.

Der Beispiel Code sucht ein Fenster mit dem Titel "*new 1 - Notepad++" und sendet an dieses "F5 testT"


Code: Alles auswählen

 
          // F5    t     e      s     t
   arr := { 0x74, 0x54, 0x45, 0x53, 0x54  }   // zu sendende Keystrokes


   nHwHnd  := FindWindow(nil, "*new 1 - Notepad++")
   if nHwHnd = 0
       msgbox("Benötigtes Programm ist nicht geladen")
   else
       SetForegroundWindow( nHwHnd )
       SetActiveWindow( nHwHnd )
       //
       for i = 1 to len(arr)
         u995sendArr2Keyboard( {arr[i]}, 0 )
         sleep(5) // Kurz Warten, dem Ziel zeit zur abarbeitung geben
       next


       u995sendArr2Keyboard( {0x10} , 1 )   // Shift drücken
       u995sendArr2Keyboard( {0x54} , 0 )   // T  senden
       u995sendArr2Keyboard( {0x10} , 2 )   // Shift loslassen


   endif


// --- Keycodes siehe unter
//  https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
//
//
function u995sendArr2Keyboard( aMSKeyCodes, nWie )   // array mit Virt-Keycodes // nwie --> 0 = drücken und loslassen, 1 = nur drücken, 2 = nur Loslassen
local oInput   := Input():New()
local i, nEvents, pBuffer
local nSize  := oInput:_sizeof_()

nEvents := len( aMSKeyCodes )
if nWie = 0
    nEvents *= 2
endif
pBuffer  := _xgrab( nSize * nEvents  )
oInput:_link_( pBuffer , .F.)
oInput:_zeromemory_()
oInput:type       := 1          // INPUT_KEYBOARD
for i = 1 to len(aMSKeyCodes)
   if nwie = 0 .or. nWie = 1
      oInput:ki:wVk     := aMSKeyCodes[i]
      oInput:ki:dwFlags := 0x0000 // KEYEVENTF_KEYDOWN
   endif
   if nWie = 0
      GwstArrayNext(oInput)
   endif
   if nwie = 0 .or. nWie = 2
      oInput:ki:wVk     := aMSKeyCodes[i]
      oInput:ki:dwFlags := 0x0002 // KEYEVENTF_KEYUP
   endif
next
sendInput( nEvents, pBuffer , nSize)
oInput:_unlink_()
_xfree( pBuffer)
return(nil)



BEGIN STRUCTURE INPUT
   MEMBER DWORD type
   BEGIN UNION
   MEMBER @MOUSEINPUT    mi
   MEMBER @KEYBDINPUT    ki
   MEMBER @HARDWAREINPUT hi
   END UNION
END STRUCTURE

BEGIN STRUCTURE MOUSEINPUT
    MEMBER LONG  dx
    MEMBER LONG  dy
    MEMBER DWORD mouseData
    MEMBER DWORD dwFlags
    MEMBER DWORD time
    MEMBER DWORD dwExtraInfo
END STRUCTURE

BEGIN STRUCTURE KEYBDINPUT
    MEMBER WORD  wVk
    MEMBER WORD  wScan
    MEMBER DWORD dwFlags
    MEMBER DWORD time
    MEMBER DWORD dwExtraInfo
END STRUCTURE

BEGIN STRUCTURE HARDWAREINPUT
    MEMBER DWORD uMsg
    MEMBER WORD  wParamL
    MEMBER WORD  wParamH
END STRUCTURE


static DLLFUNCTION SetForegroundWindow( hWnd )               USING STDCALL FROM USER32.DLL
static DLLFunction SetActiveWindow(hwnd)                     USING STDCALL FROM USER32.DLL
static DLLFUNCTION FindWindow( cClass, cName)                USING STDCALL FROM USER32.DLL
static DLLFUNCTION SendInput(nEvents, pBuffer , nSize  )     USING STDCALL FROM USER32.DLL




Re: Hotkey einstellen

Verfasst: Mo, 03. Mai 2021 11:19
von Jan
Hallo Carlo,

Danke für Deine intensiven Bemühungen. Heute komme ich da leider nicht zu, aber ich werde das in den kommenden Tagen mal durchtesten.

Jan