Seite 1 von 1

Markierung automatisch in Zwischenablage kopieren

Verfasst: 15.06.2018 06:53
von techniker
Hallo,

über eine externe Hardware bekomme ich einen Triggerimpuls,
wobei ich den zuvor markierten Text (egal in welcher Anwendung)
in die Zwischenablage kopiere und dadurch weiterverarbeiten kann.

Prinzipiell klappt das schon. Aber aus irgendwelchen Gründen kann
ich keine Texte aus der eigenen Anwendung kopieren.

Das Prinzip ist ganz einfach: "CTRL+C" emulieren, kurz warten und dann Clipboard lesen.
Manchmal braucht Windows 2-3x Emulationen, bis diese ausgeführt wird. Darum in einer
Endlosschleife mit Timeout.

Code: Alles auswählen

EnableExplicit
Declare.s CatchMarkedText()

Procedure.s CatchMarkedText()
  Protected ems.q = ElapsedMilliseconds(), ems2.q
  
  ClearClipboard()
  
  While(Not Len(GetClipboardText()) And ElapsedMilliseconds() < ems + 200) ; Text in Zwischenablage enthalten? (oder Timeout)
    keybd_event_(#VK_CONTROL, 0, 0, 0) ; CTRL gedrückt
    keybd_event_(67, 0, 0, 0) ; C gedrückt
    keybd_event_(67, 0, #KEYEVENTF_KEYUP, 0) ; C losgelassen
    keybd_event_(#VK_CONTROL, 0, #KEYEVENTF_KEYUP, 0) ; CTRL losgelassen
    
    ems2 = ElapsedMilliseconds()
    While(ElapsedMilliseconds() < ems2 + 10) : Wend ; Zwischen CTRL+C und Abfrage der Zwischenablage warten
  Wend
  
  ProcedureReturn GetClipboardText()
EndProcedure
  
  
CompilerIf #PB_Compiler_IsMainFile
  OpenWindow(0, 0, 0, 400, 300, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Define Event.l
  StringGadget(0, 15, 15, 250, 20, "Testtext0815")
  AddWindowTimer(0, 1, 250)
  
  Repeat
  Event = WaitWindowEvent(15)
    If Event = #PB_Event_Timer And EventTimer() = 1
      Debug Str(ElapsedMilliseconds())+"  ->"+CatchMarkedText()
    EndIf    
  Until Event = #PB_Event_CloseWindow
CompilerEndIf
Kennt jemand den Grund, warum in der eigenen PB-Anwendung mit dieser Emulation
keine Texte kopiert werden können? Oder gibt es eine elegantere Möglichkeit?

Danke im Voraus! :-)

Re: Markierung automatisch in Zwischenablage kopieren

Verfasst: 15.06.2018 08:04
von man-in-black
Hi,

du behandelst sowohl den Timer als auch die das Abarbeiten der Fensterevents in
einer Schleife/ einem Thread. Triggerst du das Signal, ist dein Mainthread in der 'Klick'-Schleife gefangen. In der Zeit können keine anderen Events abgearbeitet werden.
Ergo wird nie was in den Zwischenspeicher kopiert. Maximal danach, wenn alles zu spät ist.

MFG
MIB

Re: Markierung automatisch in Zwischenablage kopieren

Verfasst: 15.06.2018 08:09
von techniker
Aber warum wird dann das CTRL+C als einzelnes "C" interpretiert und der Testtext manchmal überschrieben?
-> Starte den Code, markiere den Testtext und drücke CTRL+C! :?

Das Übernehmen aus anderen Anwendungen funktioniert (anscheinend) fehlerfrei.

=> Wie kann man das Problem elegant lösen?

Re: Markierung automatisch in Zwischenablage kopieren

Verfasst: 15.06.2018 08:21
von man-in-black
Hi,

mag sein, dass dir deine Events da etwas durcheinandergewürfelt werden. Wieso auch immer.
Vielleicht hat beim Abarbeiten auch dein Stringgadget kurzzeitig mal nicht den Fokus.
Spekulier ... spekulier ... ;)

Lösen kannst du das durch einen separaten Thread.
Wieso das bei anderen Anwendungen geht? Weil es zwei Prozesse sind und damit wie Threads unabhängig laufen.

MFG
MIB

Re: Markierung automatisch in Zwischenablage kopieren

Verfasst: 15.06.2018 09:00
von Nino
Hi!

a) Das Überwachen der Windows-Zwischenablage geht eleganter so: https://www.purebasic.fr/english/viewto ... 63#p491463
Dein Programm empfängt dann ein Ereignis, wenn sich deren Inhalt ändert.

b) Zum Simulieren von Tastendrücken sollte für Windows 2000 oder neuer laut Microsoft nicht mehr keybd_event_() verwendet werden, sondern SendInput_().

Grüße!