Capturing Windows messages registered using RegisterWindowsMessage

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Capturing Windows messages registered using RegisterWindowsMessage

Mikael Svane
Another ActiveX related question...

After successfully wrapping the SpriteX control I decided to test another
one. This one, however, uses a different event system. It has a few normal
events, but it also has a couple of events that are sent as messages to a
window. This works like this:

First I send a handle to the ActiveX control telling it to which window it
should send it's callback messages. I simply use the #handle of my
AXControlSite subclass.

After I have enabled callbacks, the control internally uses
RegisterWindowsMessage to register it's (four) messages. For each "event
message", the control has a method that answer the message number that
RegisterWindowsMessage returned when each message was registered. The
ActiveX control documentation for one of these methods looks like this:

>property NotifyMessageNum: word;

>The message number assigned by RegisterWindowMessage for the message:

>‘FlicPlayer32 Notify'; notification message

>This message number allows the WndProc() of a form (or player etc.) to
access
>the notification messages generated by the player as defined using the
Notify()
>settings.

After having read
http://www.object-arts.com/wiki/html/Dolphin/AddingNewWindowsMessages.htm I
thought that I knew how to capture the messages, but unfortunately I was
wrong. It turns out that the RegisterWindowsMessage message numbers returned
by the control are outside the range of the view messageMap. Typical values
are about -6500.

Before checking the size of the map, I thought that the problem was that the
values, which were returned as SmallIntegers should actually have been
unsigned. I therefore converted them using:

(SDWORD fromUnsignedInteger: "message number here") asUnsignedInteger

but this didn't work either, since the values accepted by the messageMap are
1 to 1024. Now I'm starting to think that perhaps I should use a completely
different mechanism for receiving these messages.

Any suggestions?

Mikael Svane
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Capturing Windows messages registered using RegisterWindowsMessage

Blair McGlashan
Mikael

You wrote in message news:92q0uf$7qcut$[hidden email]...
>...
> After having read
> http://www.object-arts.com/wiki/html/Dolphin/AddingNewWindowsMessages.htm
I
> thought that I knew how to capture the messages, but unfortunately I was
> wrong. It turns out that the RegisterWindowsMessage message numbers
returned
> by the control are outside the range of the view messageMap. Typical
values
> are about -6500.
>
> Before checking the size of the map, I thought that the problem was that
the
> values, which were returned as SmallIntegers should actually have been
> unsigned. I therefore converted them using:
>
> (SDWORD fromUnsignedInteger: "message number here") asUnsignedInteger
>
> but this didn't work either, since the values accepted by the messageMap
are
> 1 to 1024. Now I'm starting to think that perhaps I should use a
completely
> different mechanism for receiving these messages.

The View class has a message dispatching framework which divides Windows
messages into three groups:

1) system defined (< WM_USER)
2) user    (WM_USER thru WM_USER_LAST inclusive)
3) registered (anything else)

This is handled in View>>dispatchMessage:wParam:lParam:.
1) System defined messages which are common to all windows, such as
WM_CREATE, are dispatched directly out of the View class MessageMap, which
happens to be a rather sparse 1024 slot array.
2) User messages (often employed by standard windows controls) have fixed
ids, but on a per Window class basis, and may therefore have different
meanings depending on the recipient. As such they are not generically
dispatched, but are instead routed through a View's implementation of
#dispatchUser:wParam:lParam:. If you look at existing definitions of this,
you will see that these are implemented by passing a Dictionary/LookupTable
(mappings ids to selectors), to the helper method
View>>dispatchUser:wParam:lParam:map:
3) Registered messages have variable ids, with the both ends of the
communication being aware of a well known name for the event, and
dynamically determining the actual numeric id to use at run time. These are
routed through a View's implementation of #dispatchRegistered:wParam:lParam:

In short, you need to override #dispatchRegistered:wParam:lParam:, and this
will mean that an AXControlSite subclass will be required (if the site is
where the messages get sent that is). If the number of registered messages
is small then one might choose to implement a "switch" style conditional, or
if there are many then using a selector map and #perform:etc is neater.

Oh, and the message numbers should be unsigned (they will arrive as the
first parameter of #dispatchRegistered:wParam:lParam: as unsigned 32-bit
integers). RegisterWindowMessage() is documented as returning a UINT. The
reason you are probably seeing them as signed is that VB doesn't support
unsigned integers, and consequently most OCX designers make the
unsatisfactory choice of mapping these to 32-bit signed integers (Longs).
The easiest way to convert a 32-bit signed integer to a 32-bit unsigned
integer in Dolphin is by sending it #asDword (e.g. -6500 asDword).

As an aside it seems a bit odd that properties are provided for accessing
the windows message ids (actually, it's a bit odd that windows messages are
used at all) since the whole point of RegisterWindowMessage is to provide
the same unique id no matter how many times it is called as long as one
passes the same message name. There's not a lot of point using
RegisterWindowsMessage if it is not called from both "client" and "server",
it would be simpler to just allocate some ids in the WM_USER range.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Capturing Windows messages registered using RegisterWindowsMessage

Mikael Svane
Blair,

>> Typical values are about -6500.
>>

>As an aside it seems a bit odd that properties are provided for accessing
>the windows message ids (actually, it's a bit odd that windows messages are
>used at all) since the whole point of RegisterWindowMessage is to provide
>the same unique id no matter how many times it is called as long as one
>passes the same message name. There's not a lot of point using
>RegisterWindowsMessage if it is not called from both "client" and "server",
>it would be simpler to just allocate some ids in the WM_USER range.
>


It was actually very odd. The negative numbers answered by the methods were
not the actual message id that should be converted to unsigned values, but
instead the proper value had to be calculated like this:

properValue := 65536 + "negative message id here"

Very strange and only by luck and by using the Transcript and debugger was I
able to determine this formula. It would have been easier if the control's
documentation could have mentioned this...

Thanks a lot.

Regards

Mikael Svane
[hidden email]