GetObject method interrupts keyboard hook execution?

B

bourgui

Hi all,

I set up a local keyboard hook in powerpoint (so that I can define my
own shortcuts), using SetWindowsHookEx etc....

The hook works fine, but I get this strange problem: if my
'KeyHandler' (the callback procedure for my hook) function calls
another routine that itself makes a 'GetObject' call, the 'KeyHandler'
seems to reset the keyevent, as I receive the event again through the
callback procedure.

For example, lets imagine that on a KeyDown event, I call the
'CreateShape' routine, defined as follows:

Code:
Sub CreateShape()
Dim mObj As Object

ActiveWindow.Selection.SlideRange.Shapes.AddShape(msoShapeRectangle,
Rnd * 250, Rnd * 100, Rnd * 300, Rnd * 175).Select

On Error GoTo NotRunning
Set mObj = GetObject(, "Word.Application")

Exit Sub

NotRunning:
MsgBox "Word not running"
End Sub
[CODE]

(I realize the 'GetObject' call is completely useless here, but this
is just to illustrate what happens. Also, I used Word in the exemple,
but the same thing happens with all other applications I have tried)

If Word happens to be running, anywhere from 5 to 20 shapes will be
created, as the KeyHandler is called several times, suggesting that
the keyEvent is being fed back somehow. Sometimes VBA crashes, I
supposed caught in an infinite loop.
If Word is not running, the message box will popup as expected, but
twice in a row.

The time seems to be a factor in this case as, if step through
manually, the problem doesn't usually happen.
I don't have any problems with any of my functions when they get
called by any other mean than the callback procedure, and this code
has been in use for a while now, so the problem must come the hook.

Does anybody have any idea how I can ensure that the callback
procedure will wait for the proper execution of GetObject?
Or is it something else?


Thanks!
 
B

bourgui

OK, after countless hours on this I found some sort of 'hack' that
fixes it.

If the routine you want to launch is set as the action for a control
(e.g. a toolbar button), call 'Button.Execute' rather than the macro
itself. I tried it after wondering why the macro call would react
differently when called directly and when called from the interface.

It makes no sense, but it works for me.

I'll be using that until I can find something better...
 
C

Clif McIrvin

bourgui said:
OK, after countless hours on this I found some sort of 'hack' that
fixes it.

If the routine you want to launch is set as the action for a control
(e.g. a toolbar button), call 'Button.Execute' rather than the macro
itself. I tried it after wondering why the macro call would react
differently when called directly and when called from the interface.

It makes no sense, but it works for me.

I'll be using that until I can find something better...



In what limited coding I've done in Access VBA, I learned that one needs
to be quite careful when writing code that might trigger other events.
It was not a trivial task, but this occasional programmer eventually
discovered that some of my routines were getting interrupted (by events
I didn't even realize I was triggering) and when the event processes
completed and control returned to my routine the environment had changed
and my routine would fail.

The only solutions I have found are 1) write recursive / re-entrant code
(that is not capable of triggering and endless loop, or is smart enough
to recognize one and gracefully kill it) or 2) figure out a way to
accomplish the task without triggering events -- not always easy.

Sounds like you have encountered a similar situation -- and your
solution may not be a hack at all -- it *may* be the recommended
practice.

Thanks for sharing your solution.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top