I have a plugin where I want to have a custom undo/redo that is completely independent of Rhino’s undo/redo. Furthermore, I don’t want the Rhino model to do anything when the user presses ctrl-z or ctrl-y. This is because the plugin model itself needs to take care of all the undo/redo actions to avoid corrupting its data.
The current solution is we have a custom rhino command “myplugin_undo” and “myplugin_redo” that can be added as a macro in the Rhino options dialog to override the ctrl-z and ctrl-y behavior.
This is not a very scalable solution and is more of a workaround than anything. Is there anything I can do about this so that we don’t need to provide special installation instructions?
That being said, I think I’d be curious to know what and why you’re trying to do what you’re trying to do, preventing undo/redo might not be the best approach.
I agree that it is not what “should” be done, and I’d never design things this way, but I’m working with an inherited codebase developed by another company and things are the way they are, at least within the bounds of what is reasonable to change without causing too many other issues.
I actually am not entirely clear myself about “corruption” (I’m using the word loosely) and need to investigate further and there may be other ways around the problem that are less invasive. In the most basic terms: we have a 3dm file that is a geometry cache and display for data in a parametric model the user is creating, via the intermediary of a plugin. Separately there is the parametric configuration data. Finally there is a state engine keeping track of user progress. Undoing operations in the Rhino model could theoretically cause any number of synchronization issues between the cached model and the plugin’s parametric configuration and state of flow.
If I think of something more specific I’ll post here.
In addition, for Windows programmming, even if I don’t have any Windows programming experience, I think you can do the same playing with changing WNDPROC callback of rhino window to process the message queue. So you can « capture » key events and eventually send message to original rhino window wndproc if your plugin doesn’t process the message.
It’s Just an idea, I can’t try it as I didn’t own a windows computer.
Hope it helps !
You should be able to do this with a low-level keyboard hook, using functions in kernel32.dll and user32.dll. There’s a lot of examples on the web, this is just one of them.
I have used this a long time ago, and I don’t have access to that code anymore. One thing I do remember is that this is a global keyboard hook, that’s also active in other programs. So you want to check if the Rhino main window has focus when you’re processing keyboard events, as you probably don’t want to modify the behavior in other programs.
This is why (global keyboard hook) I prefer « re-route » rhino windows messaging queue to plugin window/control
The other drawback (or challenge) with global keyboard hook (at least on mac) is that the callback is not in the « gui » thread, so you can’t directly check/access gui controls like windows objects.
[edit]
Oupss… read the provided link, and on Windows os, no problem to access gui in hook callback
Hey @gruedisueli, I’d recommend updating the state and handing the sync issues by subscribing to Command.UndoReo rather than preventing Undo Redo if you can help it. (And if you can’t looks like theres lots of handy folks here with help )
You can also add your own CustomUndoEvents in case you need special things to be undoable.
Regarding code samples the EventWatcher is always handy to understand what Rhinos doing with its Event Chains.