Welcome to the SRP Forum! Please refer to the SRP Forum FAQ post if you have any questions regarding how the forum works.
Qualified Events with multiple instances of the same form.
Happy New Year all.
I am finding myself needing to play with qualified events for the first time so be gentle :)
This system in question does not utilise promoted events ( I know!) so the code exists in form.
There exists code that fires a popup window on mouseover of a control (a Edit Box to be precise) by setting "QUALIFY_EVENT" and using WINMSG, etc. It closes when the mouse leaves said control. Without complicating it just yet, the code does actually work on a single instance of the form.
However, this particular form is capable of running multiple instances of itself. In this case OI referes to the window as WINDOW*2, WINDOW*3 etc.
I think due to the way the Qualify Event is saved to SYSREPOSEVENTEXES (seperated by an *) , it all falls apart for 2nd+ instances (as in doesnt run) because it treats the instance identifier as seperate field (it obviously should not be!)
I guess I am looking for broad answers at this stage.
Is this expected behavior for multi instance?
If so, then is this there a better solution (available for this old system)
Happy to try an piece together the code to present if you dont have a clue what I am talking about!
Cheers in advance.
I am finding myself needing to play with qualified events for the first time so be gentle :)
This system in question does not utilise promoted events ( I know!) so the code exists in form.
There exists code that fires a popup window on mouseover of a control (a Edit Box to be precise) by setting "QUALIFY_EVENT" and using WINMSG, etc. It closes when the mouse leaves said control. Without complicating it just yet, the code does actually work on a single instance of the form.
However, this particular form is capable of running multiple instances of itself. In this case OI referes to the window as WINDOW*2, WINDOW*3 etc.
I think due to the way the Qualify Event is saved to SYSREPOSEVENTEXES (seperated by an *) , it all falls apart for 2nd+ instances (as in doesnt run) because it treats the instance identifier as seperate field (it obviously should not be!)
I guess I am looking for broad answers at this stage.
Is this expected behavior for multi instance?
If so, then is this there a better solution (available for this old system)
Happy to try an piece together the code to present if you dont have a clue what I am talking about!
Cheers in advance.
Comments
Equ WM_MOUSEFIRST$ to 512 ; //'0x0200' - mouse on the control for the first time Equ WM_MOUSELAST$ to 522 ; //'0x0209' - mouse on the control for the last time (leaving) /* * Qualify Mouse On and Mouse Off events for the buttons in the menu * - the events are processed in the WINMSG event of the IMAGE_CODE button */ Qualifier = 1 :@FM: 2 :"*": @APPID<1> :"*WINMSG*": @WINDOW :".IMAGE_DISPLAY" /** Window Itself **/ r = Send_Message(@WINDOW, "QUALIFY_EVENT", WM_MOUSEFIRST$, 1) r = Send_Message(@WINDOW:".ON_HAND_FORE", "QUALIFY_EVENT", WM_MOUSEFIRST$, Qualifier) r = Send_Message(@WINDOW:".ON_HAND_FORE", "QUALIFY_EVENT", WM_MOUSELAST$, Qualifier) r = Send_Message(@WINDOW, "QUALIFY_EVENT", WM_MOUSEFIRST$, Qualifier) r = Send_Message(@WINDOW , "QUALIFY_EVENT", WM_MOUSELAST$, Qualifier)
Like I said, new to it so am trying to work out the need for all those lines. Please tell me if you consider some superfluos.
Sorry, distracted with a meeting. Limited to this one form.
I am about to try your recommendation Kevin.
Qualifier = 1
This alone tells OpenInsight to listen for your Windows Message and it will send an event to the control's WINMSG event. You can then create a handler using a QuickEvent to route the call to a commuter module.
Sorry gents, this went on the backburner for a few days.
I used Don's suggestion of the single Qualifier and managed to get the hover appearing as I want in all window instances with the WINMSG on the control.
I now just have to work out why it isnt triggering the close when i hover off but it seems we are on the right track...
Code 0x0200 is actually called WM_MOUSEMOVE. It is fired constantly whenever the mouse hovers over the control. That means you can get hundreds of these messages a second. Make sure to keep the code in this handler to an absolute minimum or you will notice the mouse stutter.
Code 0x0209 is for WM_MBUTTONDBLCLK. I'm not sure why you would need that.
Windows does not actually send messages for entering or leaving a control area. You have to manually handle it using a combination of WM_MOUSEMOVE and TrackMouseEvent. However, I think that would not work the way you need it to. You don't want to know when the mouse leaves the EDITLINE, you want to know when it leaves the popup.
The problem is that WM_MOUSEMOVE is sent to the control directly beneath the cursor. When the user leaves the popup, will their cursor be on the EDITLINE again? Or the Form? Or another control? This can become problematic.
Our solution in Frameworks is to use WM_SETCURSOR (code 0x0020). If you qualify this event for the form, then it will fire for the form no matter which child control the mouse is over. Like WM_MOUSEMOVE, it fires every single time the mouse moves. You'll have to do some work to extract the mouse position and compare it's screen coordinates to local control coordinates.
In that event handler, you check to see if the mouse if above the EDITLINE control. If so, show the popup. Once the popup is visible, the form will not get WM_MOUSEMOVE messages while the mouse if over the popup, therefore, the next time you do get a WM_MOUSEMOVE, you can assume the mouse left the popup form and you can close it.
Like I said, this is going to be work. This kind of stuff is not easy in OI.
Will - I know you aren't using FrameWorks for this specific application, but you do have access to a copy of FrameWorks. Therefore, I suggest you look at the Promoted_WinMsg_Event function. Under the case statement for WM_SETCURSOR there is an indented case statement for Otherwise$. There is where you can find our logic for tracking the mouse movement and whether a control is is getting the mouse moved over it or whether the control is losing the mouse movement. You can also see that we call a custom event handler called MOUSEOVER and MOUSEOFF to make it easier to implement logic that needs to be tied to those "events".