Markierung automatisch in Zwischenablage kopieren

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
techniker
Beiträge: 160
Registriert: 27.01.2016 11:08
Wohnort: BY

Markierung automatisch in Zwischenablage kopieren

Beitrag 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! :-)
Never change a running system - Never run a changed system!
(PB 6.03 LTS [x86])
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: Markierung automatisch in Zwischenablage kopieren

Beitrag 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
(hab alles, kann alles, weiß alles!!^^)

Bild
Benutzeravatar
techniker
Beiträge: 160
Registriert: 27.01.2016 11:08
Wohnort: BY

Re: Markierung automatisch in Zwischenablage kopieren

Beitrag 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?
Never change a running system - Never run a changed system!
(PB 6.03 LTS [x86])
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: Markierung automatisch in Zwischenablage kopieren

Beitrag 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
(hab alles, kann alles, weiß alles!!^^)

Bild
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Markierung automatisch in Zwischenablage kopieren

Beitrag 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!
Antworten