Storing global data (was Callbacks and events on Windows) (Real Studio Plugins Mailinglist archive)

Back to the thread list
Next thread: newbie question - how to store a file from the disk in the database


Re: Callbacks and events on Windows   -   Dave Addey
  Storing global data (was Callbacks and events on Windows)   -   Dave Addey
   Re: Storing global data (was Callbacks and events on Windows)   -   James Milne
   Re: Storing global data (was Callbacks and events on Windows)   -   James Milne
    Re: Storing global data (was Callbacks and events on Windows)   -   Dave Addey
     Re: Storing global data (was Callbacks and events on Windows)   -   Dave Addey
      Re: Storing global data (was Callbacks and events on Windows)   -   James Milne
       Re: Storing global data (was Callbacks and events on Windows)   -   Dave Addey
        Re: Storing global data (was Callbacks and events on Windows)   -   Dave Addey

Storing global data (was Callbacks and events on Windows)
Date: 26.04.06 14:45 (Wed, 26 Apr 2006 14:45:27 +0100)
From: Dave Addey
Okay, so I set about a variant of approach 2, and I've hit another snag.
Perhaps that comes from trying to do everything in the plugin. This one
should be a quick question :-)

I have a HIDManager class, which manages all connections to DirectInput and
provides devices and device elements when requested. My approach is to add
two functions to this class:

RegisterWindowForHIDEvents(inWindowHandle as integer)
UnregisterWindowForHIDEvents(inWindowHandle as integer)

The register function stores the current WindowProc pointer for the window,
and installs its own WindowProc instead. What I need to do now is to make
the old WindowProc pointer available to the new WindowProc, so that it can
pass on any unwanted events to the usual RB window procedure. Here's my
dilemma: how do I store these old pointers in a global way such that they
may be retrieved by the custom WindowProc? (It could then identify the right
one to used based on the window handle passed in.)

If I store them in the HIDManager instance, I have no way to retrieve the
instance from within the WindowProc. Is there anywhere else (within my
plugin code) that they could be stored and be globally available?

Dave.

> From: Dave Addey <<email address removed>>
> Reply-To: REALbasic Plugins <<email address removed>>
> Date: Wed, 26 Apr 2006 13:10:14 +0100
> To: REALbasic Plugins <<email address removed>>
> Conversation: Callbacks and events on Windows
> Subject: Re: Callbacks and events on Windows
>
>> Approach #1 is not gonna fly- you can't call into REALbasic code from that
>> other thread. Bad Things Will Happen.
>>
>> Approach #2 is probably heading in the right direction.
>>
>> I must admit I've never attempted to do any HID work on Windows, so I don't
>> know how it passes events to the application. What API are you using?
>>
>> You could create your own hidden offscreen window using the Win32 APIs and
>> catch the HID events using your own WndProc.
>
> Hi James,
>
> Thanks for the advice!
>
> I wondered if that might be the case for Approach 1. Bah. Thanks for the
> confirmation. I've used background threads in plugins before, but only
> where there's no interaction with RB, so I wondered if this might be the
> case.
>
> I'm using DirectInput for the HID support on Windows. It seems to *nearly*
> do everything I need, with the possible exception of support for device
> elements with big data values (i.e. "more than a DWORD"), which is
> unfortunately the case for a lot of interesting devices. I think this
> should be possible to implement, however, as soon as my Windows Driver
> Development Kit CD turns up. I've got device and device element discovery,
> information gathering, and event polling all working nicely on Win32 and
> MachO. But the killer feature is to be able to be notified when events
> arrive on Win32 too.
>
> So approach 2 it is, then. I'm very intrigued by your suggestion of
> creating a hidden offscreen window. Would this window need to be frontmost
> window to receive events? I've not really got my head round Windows'
> reliance on windows (if you see what I mean) in order to receive events in a
> GUI application. Are the concepts of 'my application is active' and 'one of
> my windows is frontmost' one and the same thing in Win32?
>
> I know I can set the cooperative level for a device:
>
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/
> IDirectInputDevice8__SetCooperativeLevel.asp
>
> ...and the most useful scenario is when the application is frontmost. But
> what if the app has many windows? How does this affect my use of a window
> as the event handler?
>
> The hidden offscreen window approach is definitely worth exploring. Any
> pointers as to how one would go about doing this? Sorry to ask - but this
> particular part of it is all new to me...
>
> Thanks again for the help,
>
> Dave.
>
> _______________________________________________
> Unsubscribe or switch delivery mode:
> <http://www.realsoftware.com/support/listmanager/>
> Search the archives of this list here:
> <http://support.realsoftware.com/listarchives/lists.html>

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Storing global data (was Callbacks and events on Windows)
Date: 26.04.06 15:14 (Wed, 26 Apr 2006 15:14:32 +0100)
From: James Milne
Dave Addey wrote:
> Okay, so I set about a variant of approach 2, and I've hit another snag.
> Perhaps that comes from trying to do everything in the plugin. This one
> should be a quick question :-)
>
> I have a HIDManager class, which manages all connections to DirectInput and
> provides devices and device elements when requested. My approach is to add
> two functions to this class:
>
> RegisterWindowForHIDEvents(inWindowHandle as integer)
> UnregisterWindowForHIDEvents(inWindowHandle as integer)
>
> The register function stores the current WindowProc pointer for the window,
> and installs its own WindowProc instead. What I need to do now is to make
> the old WindowProc pointer available to the new WindowProc, so that it can
> pass on any unwanted events to the usual RB window procedure. Here's my
> dilemma: how do I store these old pointers in a global way such that they
> may be retrieved by the custom WindowProc? (It could then identify the right
> one to used based on the window handle passed in.)
>
> If I store them in the HIDManager instance, I have no way to retrieve the
> instance from within the WindowProc. Is there anywhere else (within my
> plugin code) that they could be stored and be globally available?

SetWindowData() is your friend. It allows you to store data against the Window Handle. When you create the window, call SetWindowHandle and stash your REALobject instance reference in there.

You can use GetWindowData to retrieve your REALobject instance from the HWND passed to the WndProc.

Re: Storing global data (was Callbacks and events on Windows)
Date: 26.04.06 15:28 (Wed, 26 Apr 2006 15:28:00 +0100)
From: James Milne
On Wednesday, April 26, 2006, at 03:14PM, James Milne <<email address removed>> wrote:
>> Here's my
>> dilemma: how do I store these old pointers in a global way such that they
>> may be retrieved by the custom WindowProc? (It could then identify the right
>> one to used based on the window handle passed in.)
>>
>> If I store them in the HIDManager instance, I have no way to retrieve the
>> instance from within the WindowProc. Is there anywhere else (within my
>> plugin code) that they could be stored and be globally available?
>
>SetWindowData() is your friend. It allows you to store data against the Window Handle. When you create the window, call SetWindowHandle and stash your REALobject instance reference in there.
>
>You can use GetWindowData to retrieve your REALobject instance from the HWND passed to the WndProc.

Sorry- the functions I meant where GetWindowLong and SetWindowLong.

<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windowclasses/windowclassreference/windowclassfunctions/setwindowlong.asp>

Re: Storing global data (was Callbacks and events on Windows)
Date: 26.04.06 16:11 (Wed, 26 Apr 2006 16:11:47 +0100)
From: Dave Addey
Hi James,

That is exactly what I needed - and it seems to work :-) Thanks!

Dave.

> From: James Milne <<email address removed>>
> Reply-To: REALbasic Plugins <<email address removed>>
> Date: Wed, 26 Apr 2006 15:28:00 +0100
> To: REALbasic Plugins <<email address removed>>
> Cc: REALbasic Plugins <<email address removed>>, REALbasic
> Plugins <<email address removed>>
> Subject: Re: Storing global data (was Callbacks and events on Windows)
>
> On Wednesday, April 26, 2006, at 03:14PM, James Milne <<email address removed>>
> wrote:
>>> Here's my
>>> dilemma: how do I store these old pointers in a global way such that they
>>> may be retrieved by the custom WindowProc? (It could then identify the right
>>> one to used based on the window handle passed in.)
>>>
>>> If I store them in the HIDManager instance, I have no way to retrieve the
>>> instance from within the WindowProc. Is there anywhere else (within my
>>> plugin code) that they could be stored and be globally available?
>>
>> SetWindowData() is your friend. It allows you to store data against the
>> Window Handle. When you create the window, call SetWindowHandle and stash
>> your REALobject instance reference in there.
>>
>> You can use GetWindowData to retrieve your REALobject instance from the HWND
>> passed to the WndProc.
>
> Sorry- the functions I meant where GetWindowLong and SetWindowLong.
>
> <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/
> windowsuserinterface/windowing/windowclasses/windowclassreference/windowclassf
> unctions/setwindowlong.asp>
> --
> James Milne
> _______________________________________________
> Unsubscribe or switch delivery mode:
> <http://www.realsoftware.com/support/listmanager/>
> Search the archives of this list here:
> <http://support.realsoftware.com/listarchives/lists.html>

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Storing global data (was Callbacks and events on Windows)
Date: 26.04.06 16:58 (Wed, 26 Apr 2006 16:58:30 +0100)
From: Dave Addey
Here's another, final piece of the puzzle:

The WindowProc receives Messages. DirectInput sets Events:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/
IDirectInputDevice8__SetEventNotification.asp

How do the two intermix? How do I differentiate messages and events in my
WindowProc? Or have I got the complete wrong end of the stick?

Dave.

> From: Dave Addey <<email address removed>>
> Reply-To: REALbasic Plugins <<email address removed>>
> Date: Wed, 26 Apr 2006 16:11:47 +0100
> To: REALbasic Plugins <<email address removed>>
> Conversation: Storing global data (was Callbacks and events on Windows)
> Subject: Re: Storing global data (was Callbacks and events on Windows)
>
> Hi James,
>
> That is exactly what I needed - and it seems to work :-) Thanks!
>
> Dave.
>
>> From: James Milne <<email address removed>>
>> Reply-To: REALbasic Plugins <<email address removed>>
>> Date: Wed, 26 Apr 2006 15:28:00 +0100
>> To: REALbasic Plugins <<email address removed>>
>> Cc: REALbasic Plugins <<email address removed>>, REALbasic
>> Plugins <<email address removed>>
>> Subject: Re: Storing global data (was Callbacks and events on Windows)
>>
>> On Wednesday, April 26, 2006, at 03:14PM, James Milne <<email address removed>>
>> wrote:
>>>> Here's my
>>>> dilemma: how do I store these old pointers in a global way such that they
>>>> may be retrieved by the custom WindowProc? (It could then identify the
>>>> right
>>>> one to used based on the window handle passed in.)
>>>>
>>>> If I store them in the HIDManager instance, I have no way to retrieve the
>>>> instance from within the WindowProc. Is there anywhere else (within my
>>>> plugin code) that they could be stored and be globally available?
>>>
>>> SetWindowData() is your friend. It allows you to store data against the
>>> Window Handle. When you create the window, call SetWindowHandle and stash
>>> your REALobject instance reference in there.
>>>
>>> You can use GetWindowData to retrieve your REALobject instance from the HWND
>>> passed to the WndProc.
>>
>> Sorry- the functions I meant where GetWindowLong and SetWindowLong.
>>
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui>>
/
>>
windowsuserinterface/windowing/windowclasses/windowclassreference/windowclass>>
f
>> unctions/setwindowlong.asp>
>>
>> --
>> James Milne
>> _______________________________________________
>> Unsubscribe or switch delivery mode:
>> <http://www.realsoftware.com/support/listmanager/>
>>
>> Search the archives of this list here:
>> <http://support.realsoftware.com/listarchives/lists.html>
> _______________________________________________
> Unsubscribe or switch delivery mode:
> <http://www.realsoftware.com/support/listmanager/>
> Search the archives of this list here:
> <http://support.realsoftware.com/listarchives/lists.html>

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Storing global data (was Callbacks and events on Windows)
Date: 26.04.06 17:22 (Wed, 26 Apr 2006 17:22:55 +0100)
From: James Milne

On Wednesday, April 26, 2006, at 04:58PM, Dave Addey <<email address removed>> wrote:

>Here's another, final piece of the puzzle:
>
>The WindowProc receives Messages. DirectInput sets Events:
>
>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/
>IDirectInputDevice8__SetEventNotification.asp
>
>How do the two intermix? How do I differentiate messages and events in my
>WindowProc? Or have I got the complete wrong end of the stick?

Ah, sorry. I haven't read the DirectInput documentation yet; it's been years since I've done any work with DirectInput.

Dredging up Win32 that I've done my best in the last couple of years to suppress:

Events are objects that you create and use to send messages between threads. You create an Event using CreateEvent and attach it to the DirectInput device using SetEventNotification. You later query that Event using MsgWaitForMultipleObjects to see if anything has happened for that device. If anything has happened, you can then query the device. Typically you call MsgWaitForMultipleObjects from another thread, as MsgWaitForMultipleObjects can be told to block the thread until something happens.

I'll have a better read when I get home this evening. I'll be able to advise you better then.

Re: Storing global data (was Callbacks and events on Windows)
Date: 26.04.06 17:30 (Wed, 26 Apr 2006 17:30:23 +0100)
From: Dave Addey
Hi James,

Thanks! Any help you can give is very much appreciated.

One thought I had: do I need to run a background thread to keep an eye out
for these events? The thread would then post custom user messages (WM_USER
or above) to registered windows when an event occurs? I think the process
of posting an event to a window gets around the thread-calling-RB problems
(a bit like Carbon Events on the Mac), but tbh I'm really not sure if I'm
understanding it well enough to know if that's right or not :-)

Thanks in advance for the help!

Dave.

> Ah, sorry. I haven't read the DirectInput documentation yet; it's been years
> since I've done any work with DirectInput.
>
> Dredging up Win32 that I've done my best in the last couple of years to
> suppress:
>
> Events are objects that you create and use to send messages between threads.
> You create an Event using CreateEvent and attach it to the DirectInput device
> using SetEventNotification. You later query that Event using
> MsgWaitForMultipleObjects to see if anything has happened for that device. If
> anything has happened, you can then query the device. Typically you call
> MsgWaitForMultipleObjects from another thread, as MsgWaitForMultipleObjects
> can be told to block the thread until something happens.
>
> I'll have a better read when I get home this evening. I'll be able to advise
> you better then.
>
> --
> Kind regards,
> James Milne
> _______________________________________________
> Unsubscribe or switch delivery mode:
> <http://www.realsoftware.com/support/listmanager/>
> Search the archives of this list here:
> <http://support.realsoftware.com/listarchives/lists.html>

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: Storing global data (was Callbacks and events on Windows)
Date: 27.04.06 08:54 (Thu, 27 Apr 2006 08:54:35 +0100)
From: Dave Addey
Just to answer my own question...

I tried this approach, and it seems to work. My background thread waits for
DirectInput events to arrive, and posts a custom message (via PostMessage)
to a registered window whenever one arrives. This moves all calls back into
the RB code to the main thread's message loop, making everything safe.

Thanks once again to James for the help with this - I'm on the home straight
now, I think :-)

Dave.

> From: Dave Addey <<email address removed>>
> Reply-To: REALbasic Plugins <<email address removed>>
> Date: Wed, 26 Apr 2006 17:30:23 +0100
> To: REALbasic Plugins <<email address removed>>
> Conversation: Storing global data (was Callbacks and events on Windows)
> Subject: Re: Storing global data (was Callbacks and events on Windows)
>
> Hi James,
>
> Thanks! Any help you can give is very much appreciated.
>
> One thought I had: do I need to run a background thread to keep an eye out
> for these events? The thread would then post custom user messages (WM_USER
> or above) to registered windows when an event occurs? I think the process
> of posting an event to a window gets around the thread-calling-RB problems
> (a bit like Carbon Events on the Mac), but tbh I'm really not sure if I'm
> understanding it well enough to know if that's right or not :-)
>
> Thanks in advance for the help!
>
> Dave.
>
>> Ah, sorry. I haven't read the DirectInput documentation yet; it's been years
>> since I've done any work with DirectInput.
>>
>> Dredging up Win32 that I've done my best in the last couple of years to
>> suppress:
>>
>> Events are objects that you create and use to send messages between threads.
>> You create an Event using CreateEvent and attach it to the DirectInput device
>> using SetEventNotification. You later query that Event using
>> MsgWaitForMultipleObjects to see if anything has happened for that device. If
>> anything has happened, you can then query the device. Typically you call
>> MsgWaitForMultipleObjects from another thread, as MsgWaitForMultipleObjects
>> can be told to block the thread until something happens.
>>
>> I'll have a better read when I get home this evening. I'll be able to advise
>> you better then.
>>
>> --
>> Kind regards,
>> James Milne
>> _______________________________________________
>> Unsubscribe or switch delivery mode:
>> <http://www.realsoftware.com/support/listmanager/>
>>
>> Search the archives of this list here:
>> <http://support.realsoftware.com/listarchives/lists.html>
> _______________________________________________
> Unsubscribe or switch delivery mode:
> <http://www.realsoftware.com/support/listmanager/>
> Search the archives of this list here:
> <http://support.realsoftware.com/listarchives/lists.html>

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>