Developer forums (C::B DEVELOPMENT STRICTLY!) > Plugins development

Key Macros plugin

(1/8) > >>

Pecan:
I've written a plugin to create and playback key macros.

A key macrosText looks like "{END}{ENTER}{TAB 2}//{SPACE}" for example.

The keyMacro is played back by creating a menu item with a command key chosen by the user, eg., "MyMac \tCtrl-Enter" such that when the user types Ctrl-Enter the interpreted macroText is stuffed into the keyboard queue.

Now, lets say a user creates a keyMacro with the text "{}" with a menu command key of "MyMacro \t{". This acturally works. The user types { on the keyboard and {} appears in the editor. Over and over and over and over.....

The macro processor (plugin) is in a loop because the OS sees the '{' in the keyboard queue, sees that its a menu command and invokes the macro plugin again.

I can prevent this by disallowing any keyMacro whos macroText contains the menu command key. eg. if a menu item with command key '{' invokes a  keyMacro whos macroText contains '{', refuse to play it back.

I'd rather not do that. I'd like to find a way to play the macro but stop the loop.

Some ideas that didnt work...

* A timer. Very iffy. On different systems, keyMacro could get through multiple times.
* Play back only once. Ok, how do you play it next time? What would clear the "I just played that" status?
I'd appreciate some ideas.
Thanks
pecan

 

dmoore:
this sounds like a handy macro.

some thoughts/questions:

* would you have the same problem if someone pasted text containing "{"?

* it seems that you need some way to distinguish typed input from inserted input. failing that you could require all key assignments use a CTRL or ALT modifier.

* are you trapping the "changed" status of the cbEditor rather than the "keystroke" status?

* does the plugin operate only when focus is in the editor window or on all C::B windows?

* it would be nice if this plugin was integrated with "Keyboard shortcuts"

hope to see it working soon :)

byo:

--- Quote from: Pecan on December 11, 2006, 03:37:46 pm ---Some ideas that didnt work...

* A timer. Very iffy. On different systems, keyMacro could get through multiple times.
* Play back only once. Ok, how do you play it next time? What would clear the "I just played that" status?
--- End quote ---

Ok few ideas:

* Mixing Playback-once with a timer (blocking flag set before executing macro and timer clears blocking flag) - this may still be risky becuase of different speed on different computers

* Accessing cb editor directly (I'm not sure but they shouldn't throw keys into system's message queue avoiding recall of menu entry)
* Setting some blocking flag just before senting key events and resetting it after all keys are sent. But thils will work only if keys will be sent using immediate functions - so no AddPEndingEvent could be used just ProcessEvent or it will require calling Manager::Yield() before clearing flag
Regards
   BYO

Pecan:
Thanks for your response.


--- Quote from: dmoore on December 11, 2006, 03:55:29 pm ---this sounds like a handy macro.
some thoughts/questions:
* would you have the same problem if someone pasted text containing "{"?

--- End quote ---
No, the loop does not occur on paste. Only when invoked via the keyboard.
However, pasting does not provide anywhere near the flexibility of the keyboard.

--- Quote ---* it seems that you need some way to distinguish typed input from inserted input. failing that you could require all key assignments use a CTRL or ALT modifier.

--- End quote ---
Indeed. But the macroText is not inserted. It's actually pushed onto the keyboard queue. Thus there is no distinction between chars originating from the macro and those typed at the keyboard by the user.

An Alt-N macro that contained "{Alt}n" puts me in the same hard place.

With wxWidgets, chars cannot be "inserted" into native controls, they can only come from the keyboard. If the plugin attempted to use the widgets facilities, SetValue(), ScrollWindow() etc, it'd have to determine the control type, the function to use, etc etc. It'd have to recreate the wxWidgets wheel.

--- Quote ---* are you trapping the "changed" status of the cbEditor rather than the "keystroke" status?

--- End quote ---
KeyMacs is not trapping any status at all right now. It's invoked by the menu system, looks up the menu name, matches that to a keyMacro of the same name, translates its menuText to keystrokes and pushes 'em into the keyboard queue.

Edit: 2006/12/11 2:27 PM
Ah, I see what you mean. But the cbEditor changed flag may not be raised if the macro changed say the find dialog. {Ctrl}f"{"{ENTER} would not raise the "changed" flag, but it would cause the loop.

It does know the last macro name, the time, and the macroText.

--- Quote ---* does the plugin operate only when focus is in the editor window or on all C::B windows?

--- End quote ---
I have restricted the macro to execute only when invoke from a CBeditor window. However, the macroText can open/close/switch/start pgms/invoke other menus etc. eg. "{Ctrl}fFIXME{ENTER}" opens the find dialog, types FIXME into the find control and executes the find.

--- Quote ---* it would be nice if this plugin was integrated with "Keyboard shortcuts"
hope to see it working soon :)

--- End quote ---
I suspect that in future, the KeyBinder plugin will be deprecated. So integration might not be forthcoming.

Got any ideas about that loop problem?

dmoore:
you could try something like the following, a slight twist on byos proposal (far from perfect, but not sure how you could do anything else if you are using the key buffer)

1. receive keystroke to invoke macro
2. switch off key macro lookups
3. insert macro text into key buffer + append a final key command to switch on key macro lookups when done

Navigation

[0] Message Index

[#] Next page

Go to full version