[Macros][Writer] How to cancel an event?

In Writer, I assign to the event “Non-alphanumeric input” in a frame item, the sub “input_frame”

My sub runs some code. it takes two parameters. The code parameters tells which key has been pressed, example 1282 for tab key

sub input_frame(name, code)
if (code == 1282) {
msgbox("tab key has been pressed!")
end if
end sub

→ But once I run this sub, how do I prevent the tab event from inserting a tabulation? Like event.preventDefault() would do in Javascript…

Where can I find documentation related to this case?

please help :frowning:

that feel when the only relevant result on google are my unanswered questions on forums…

Please, calm, everybody in this forum we are voluntaries.

A deliberate dupe of OP’s own How to cancel an event?.

In that question, @Lupp had answered the next day you posted the question, suggesting to read Andrew Pitonyak’s “Useful Macro Information” ch.14.3.6, which starts with these words:

Handlers are a special type of listener. As listeners they can intercept an event, but in addition an handler acts as event consumer, in other words, an handler can “eat” the event.

So no, your questions are answered timely. It’s just you who doesn’t return with description how specifically did the answer not fit you.

I did try to use the information on ch. 14.3.6 of Andrew Pitonyak’𝑠 book,

However this is either far above my understanding of LO macros, either it is indeed unhelpful in the case of macros assignated via macro tab of my frame properties. Here, Andrew has an event object, wheras I just have the keycode of the key that have been pressed.

There is no way to stop further processing of an event currently from standard event handlers that you assign on Macro tab of objects’ properties. The code that handles it, SwDoc::ExecMacro, currently handles the EXTENDED_STYPE case (which is used for these handlers, despite being “BASIC”) without taking return value into account (see the TODO comment); so SwEditWin::KeyInput cannot use it in lines 1513-1514. You are welcome to file a bug, and even to come with a fix if you like. Don’t forget to mention the filed bug number here in a comment to allow tracking its status for anyone interested in this issue.

(The intended way is to use a function as handler, and return a non-0 numeric value to stop further processing.)

In the meanwhile, see @Lupp’s answer you were given in your original question.

If you decide to take this and try to fix, I can mentor you if you like. Pointers: you might need to use unoToSbxValue function for an intermediate value when converting uno::Any return value to OUString. Modifying the latter signature might also be required.

Since my attention was drawn to this thread by link-mentioning me, I want to state that I never wrote code for intercepting/handling events in Writer.
Assuming the OriginalQuestioner actually needs a way to trigger something to happen with his frame, and being informed that there is missing the “eat-event-capability” of routines assigned to objects via the >Properties>>Macro facility, I would suggest to consider to use Shift+Tab to trigger the interception. Afaik there is no default assignment to the modified key if used outside TextTable that would be spoilt If a TextTable inside the frame occurs, Ctrl+Shift+Tab might be an alternative. .
Workaround:

Sub onNANpressedInsideFrame(pFrameName, pKeyCode)
Const shTabKeyCode = 5378 REM =1282 + 2^12 (Second addend for the modifier.)
If (pKeyCode=shTabKeyCode) Then
  MsgBox("Shift+Tab key has been pressed!")
End If
End Sub

By adding a loop that never ends at the end of my sub, the sub never ends so tab is never send.

Do
Loop Until 0=1

Is it a good idea? Will it consume alot of ressource once triggering multiple time this sub? I don’t know, let see.

Edit 2:

Then I can catch all the “tab” event pending this way :

sub killMacrosAndCatchEvents
dim document   as object
dim dispatcher as object
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dispatcher.executeDispatch(document, ".uno:InsertAnnotation", "", 0, Array())
Wait 1
dispatcher.executeDispatch(document, ".uno:DeleteComment", "", 0, Array())
dispatcher.executeDispatch(document, ".uno:BasicStop", "", 0, Array())
end sub

Once the macros are killed with uno:BasicStop, the tabulations are sent inside the annotation and it is closed almost instantly.

→ Could still be more elegant.

And then, when I press F5 I have an autohotkey macro that automatically : sends ctrl+alt+c to open a comment, send ctrl+shift+q to kill every macro, so all my tabulation are written in the comment, then I exit the comment. So I can clear all these loops in case it start consuming lots of ressources. Not the most elegant way, but it works

Would you still follow the advise to at least file a bug if you need to fix the shortcoming?

Sure I will

Thank you!