It is currently Thu May 23, 2013 3:25 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: SendKey ?
PostPosted: Thu Feb 16, 2012 10:40 am 
Offline
New User
New User

Joined: Thu Feb 16, 2012 10:28 am
Posts: 3
Hi All,

This my first post :) --
Can you please tell, whether a SendKey analog exist in MAC OS?
Any OSX Api function to simulate keybd_event like in Windows?
Is it possible to do it in PureBasic for Mac?

Many thanks!


Top
 Profile  
 
 Post subject: Re: SendKey ?
PostPosted: Thu Feb 16, 2012 6:59 pm 
Offline
Addict
Addict
User avatar

Joined: Mon Aug 04, 2008 10:56 pm
Posts: 849
Location: Seattle, USA
What does it do?

viewtopic.php?f=19&t=46205

_________________
MacBook Pro/Retina, OSX 10.8.3 Mountain Lion, PB-5.11x64


Last edited by WilliamL on Thu Feb 16, 2012 8:50 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: SendKey ?
PostPosted: Thu Feb 16, 2012 7:07 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Apr 21, 2005 2:38 pm
Posts: 814
Location: Germany
At first: welcome to the PureBasic Forum, Eidos... :wink:

What do you want to achieve?

If you want to simulate a key press into a StringGadget this can be
done very easily and cross-platform:
Code:
EnableExplicit

OpenWindow(0, 270, 100, 270, 70, "Simulate key press", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
StringGadget(0, 10, 10, WindowWidth(0) - 20, 20, "")
ButtonGadget(1, 30, 40, WindowWidth(0) - 60, 20, "Simulate pressing of <K> key")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1
        If EventType() = #PB_EventType_LeftClick
          SetGadgetText(0, GetGadgetText(0) + "K")
        EndIf
      EndIf
  EndSelect
ForEver

If you want to simulate a key press by generating an internal event,
things are becoming more complicated:
Code:
EnableExplicit

ImportC ""
  CreateEvent(MemoryAllocatorRef.L, EventClass.L, EventKind.L, EventTime.D, EventAttributes.L, *EventRef)
  SendEventToEventTargetWithOptions(EventRef.L, EventTargetRef.L, OptionBits.L)
EndImport

#kEventAttributeNone = 0
#kEventClassControl = 'cntl'
#kEventParamTextInputSendKeyboardEvent = 'tske'

Structure EventTypeSpec
  EventClass.L
  EventKind.L
EndStructure

ProcedureC ControlHandler(*NextEventHandler, EventRef.L, UserData.L)
  Protected Result.L

  If GetEventKind_(EventRef) = #kEventParamTextInputSendKeyboardEvent
    SetGadgetText(0, GetGadgetText(0) + "K")
  EndIf
EndProcedure

Dim EventTypes.EventTypeSpec(0)

Define EventRef.L
Define Result.L

OpenWindow(0, 270, 100, 270, 70, "Simulate key press", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
StringGadget(0, 10, 10, WindowWidth(0) - 20, 20, "")
ButtonGadget(1, 30, 40, WindowWidth(0) - 60, 20, "Simulate pressing of <K> key")

EventTypes(0)\EventClass = #kEventClassControl
EventTypes(0)\EventKind = #kEventParamTextInputSendKeyboardEvent
InstallEventHandler_(GetControlEventTarget_(GadgetID(0)), @ControlHandler(), 1, @EventTypes(), 0, 0)

If CreateEvent(0, #kEventClassControl, #kEventParamTextInputSendKeyboardEvent, 0, #kEventAttributeNone, @EventRef)
  Debug "CreateEvent() failed!"
  End
EndIf

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1
        If EventType() = #PB_EventType_LeftClick
          SendEventToEventTarget_(EventRef, GetControlEventTarget_(GadgetID(0)))
        EndIf
      EndIf
  EndSelect
ForEver

If you want to know how to detect the pressing of keys (and clicks onto
different mouse buttons) in a window (not as input into a StringGadget)
and display these actions in a TextGadget, then you might take a look
into this thread.


Top
 Profile  
 
 Post subject: Re: SendKey ?
PostPosted: Fri Feb 17, 2012 10:41 am 
Offline
New User
New User

Joined: Thu Feb 16, 2012 10:28 am
Posts: 3
Thank you for reply!

Actually, I'm writing a simple plugin for QuarkXpress and want to send key/word to edit window of QXP.
I've tried apple script, but that works too slowly and sometimes hanging the whole Qxp.
The solution was to make a simple application that stays on top and sending keystrokes to Quark on demand (pressing button)

The text is compiling inside the plugin and copied into the clipboard. Then switching to Qxp and simulating the APPLE + V (paste) operation. All wanted to do, is to simulate the Apple+V command.

here is the code where I'm trying to achieve this:
Code:
  Repeat
    evt = WaitWindowEvent()
  Select evt
    Case #PB_Event_CloseWindow
      quit = 1
    Case #PB_Event_Gadget
      eg = EventGadget()
      If eg >=0 And eg <=11
        SetClipboardText (GetGadgetText(eg)) ; put text into clipboard ...
        DisableWindow (0, 1) ; remove sticky option for dialog
        ; <<---- Here, simulate Apple+V keystroke
        DisableWindow (0, 0) ; back sticky option
      EndIf
   EndSelect   
  Until quit = 1 


I hope that your second solution will fit my requirements.
Many thanks!


Top
 Profile  
 
 Post subject: Re: SendKey ?
PostPosted: Fri Feb 17, 2012 5:56 pm 
Offline
Addict
Addict
User avatar

Joined: Mon Aug 04, 2008 10:56 pm
Posts: 849
Location: Seattle, USA
Well, how about that!?

Anyway, we got two routines from shardik for sending and getting keystrokes.

Thanks again shardik!

_________________
MacBook Pro/Retina, OSX 10.8.3 Mountain Lion, PB-5.11x64


Top
 Profile  
 
 Post subject: Re: SendKey ?
PostPosted: Sat Feb 18, 2012 1:46 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Apr 21, 2005 2:38 pm
Posts: 814
Location: Germany
Eidos,

thank you for the description of your intended project. Unfortunately I
have no QuarkXpress to code a customized solution, but I have tried to
find a similar solution which starts TextEdit and sends keystrokes to be
displayed in TextEdit (or each other application which currently has the
keyboard focus). You have to send the virtual key codes and the modifier
key mask (for example if you have the need to press the Shift key
simultaneously). Perhaps you should modify the SendKey() procedure to
accept a normal ANSI character which will then of course have to be
translated to the corresponding virtual key code. Since you can call
SendKey() multiple times, there is no need to use the clipboard anymore... :wink:
Code:
EnableExplicit

#kCGHIDEventTap= 0

; ----- Virtual keycodes (defined in Events.h)

#kVK_ANSI_E = $0E
#kVK_ANSI_H = $04
#kVK_ANSI_L = $25
#kVK_ANSI_O = $1F
#kVK_Return = $24

; ----- Modifier key masks (defined in IOLLEvent.h)

#kCGEventFlagMaskShift     = $020000 ; = NX_SHIFTMASK
#kCGEventFlagMaskControl   = $040000 ; = NX_CONTROLMASK
#kCGEventFlagMaskAlternate = $080000 ; = NX_ALTERNATEMASK
#kCGEventFlagMaskCommand   = $100000 ; = NX_COMMANDMASK

ImportC ""
  CFRelease(CFTypeRef.L)
  CGEventCreateKeyboardEvent(CGEventSourceRef.L, CGVirtualKeyCode.U, KeyDown.L)
  CGEventPost(CGEventTapLocation.L, CGEventRef.L)
  CGEventSetFlags(CGEventRef.L, CGEventFlags.L)
EndImport

Procedure.L SendKey(VirtualKey.U, ModifierKey.L = 0)
  Protected KeyEvent.L

  KeyEvent = CGEventCreateKeyboardEvent(0, VirtualKey, #True)

  If KeyEvent
    ; ----- Press key
    CGEventSetFlags(KeyEvent, ModifierKey)
    CGEventPost(#kCGHIDEventTap, KeyEvent)
    CFRelease(KeyEvent)

    KeyEvent = CGEventCreateKeyboardEvent(0, VirtualKey, #False)
    CGEventSetFlags(KeyEvent, ModifierKey)

    If KeyEvent
      ; ----- Release key
      CGEventPost(#kCGHIDEventTap, KeyEvent)
      CFRelease(KeyEvent)
    EndIf
  EndIf

  ProcedureReturn KeyEvent
EndProcedure

Define Msg.S = "Hello!"
Define ProgramID.L

ProgramID = RunProgram("Open", "/Applications/TextEdit.app", "", #PB_Program_Open)

If ProgramID
  ; ----- Wait until TextEdit is running (increase delay if necessary)
  Delay(100)
  ; ----- Send Keys to TextEdit
  SendKey(#kVK_ANSI_H, #kCGEventFlagMaskShift)
  SendKey(#kVK_ANSI_E)
  SendKey(#kVK_ANSI_L)
  SendKey(#kVK_ANSI_L)
  SendKey(#kVK_ANSI_O)
  SendKey(#kVK_Return)
  CloseProgram(ProgramID)
EndIf


Top
 Profile  
 
 Post subject: Re: SendKey ?
PostPosted: Sun Feb 19, 2012 1:04 pm 
Offline
New User
New User

Joined: Thu Feb 16, 2012 10:28 am
Posts: 3
Hi Shardik,

Many thanks for code! That's really useful piece of code.
I came from Windows world and just started with Mac using PB.

I have faced with strange clipboard behavior in PB before implementing your senkey solution in mac.
It seems that SetClipboardText doesn't work properly on my Mac OSX.
The application can put into clipboard text and then read it back. SetClipboardText and GetClipboatdText works fine within the application, BUT SHOW Clipboard operation inside the FINDER doesn't show anything...

Simple text editor, safari and mac Word are showing my entries via APPLE+V (paste from clipboard).

Also, I've tried to copy the text from PB IDE and paste somewhere else: that worked! even showed up in SHOW Clipboard and QuarkXPress, but no luck when using Set/Get clipboard operations.

Can some try to run simple CLIPBOARD example on Mac OS (use only SetClipboardText) and check whether text visible or not in Show Clipboard window.

That's really strange and makes my development efforts useless....

Here is my mac configuration:
Powermac G4, MacOS X 10.4.9. (8p 135), Darwin 8.9.0
QuarkXpress v6.1 PPC


Top
 Profile  
 
 Post subject: Re: SendKey ?
PostPosted: Sun Feb 19, 2012 6:45 pm 
Offline
Addict
Addict
User avatar

Joined: Mon Aug 04, 2008 10:56 pm
Posts: 849
Location: Seattle, USA
Works ok for me. I've been using the clipboard copy/paste in a couple of apps and it has been working for me. When I look in 'Show clipboard', from the finder, it's there... ran example and cmd+V when in TextEdit and it pasted correctly. (only tried the text - canceled the pict load)

Code:
; ------------------------------------------------------------
;
;   PureBasic - Clipboard example file
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;

; Paste text to the clipboard..
SetClipboardText("PureBasic pasted text example.")

; Display the contents of the clipboard...
MessageRequester("Info", "Text in the clipboard"+#LF$+"'"+GetClipboardText()+"'", 0)

; Now paste an image...

If LoadImage(0, OpenFileRequester("Load a picture","","Bitmap (*.bmp)|*.bmp",0))
  If SetClipboardImage(0)

    MessageRequester("Info", "Image correctly pasted to the clipboard."+Chr(10)+"Open 'Paint' to test it !", 0)
  EndIf
EndIf

_________________
MacBook Pro/Retina, OSX 10.8.3 Mountain Lion, PB-5.11x64


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye