|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Hover effects, IMessageFilter not working as expectedI'm developping a form that renders differently when hovered and trigger some processing when not hovered (leaved). The thing is, when I leave my form and another form from my application is underneath, it works fine, but if I leave my form and anything that is not from my application is underneath, the Leave event does not fire until I hover something from my application. Here's my filtered code for the IMessageFilter (I did not pasted the declarations, I just pasted my message proc) (at the end of the post) Can someone tell me what's wrong with this code? thanks ThunderMusic [CODE] public bool PreFilterMessage(ref Message m) { // Everything is done with WM_MOUSEMOVE if (m.Msg == WM_MOUSEMOVE) { // look if the target is our control or contained by our control Control ctrl = Control.FromHandle(m.HWnd); if (ctrl != null && (ctrl == this._container || this._container.Contains(ctrl))) { // if this message WM_MOUSEMOVE is the first we get, // we must trigger the MouseEnter event if (!this._isEntered) { // trigger MouseEnter this.OnMouseEnter(); this._isEntered = true; } // Get point (using target control coordinates) Point pt = new Point(m.LParam.ToInt32()); // convert to controls coordinates if necessary Point containerPoint; if (ctrl != this._container) containerPoint = this._container.PointToClient(ctrl.PointToScreen(pt)); else containerPoint = pt; // Trigger MouseMove this.OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, containerPoint.X, containerPoint.Y, 0)); } else { // If the target is not a child and MouseLeaves has not been triggered // we must trigger MouseLeave if (this._isEntered) { // Trigger MouseLeave this.OnMouseLeave(); this._isEntered = false; } } } return false; } [/CODE] Have you tried using the Activated and Deactivated events instead? See
this from MSDN help: The Enter and Leave events are suppressed by the Form class. The equivalent events in the Form class are the Activated and Deactivate events. The Enter and Leave events are hierarchical and will cascade up and down the parent chain until the appropriate control is reached. For example, assume you have a Form with two GroupBox controls, and each GroupBox control has one TextBox control. When the caret is moved from one TextBox to the other, the Leave event is raised for the TextBox and GroupBox, and the Enter event is raised for the other GroupBox and TextBox. Bryan Phillips MCSD, MCDBA, MCSE Blog: http://bphillips76.spaces.live.com Show quote "ThunderMusic" <NoSpAmdanlatathotmaildotcom@NoSpAm.com> wrote in message news:eh#7bOT#GHA.3456@TK2MSFTNGP02.phx.gbl: > Hi, > I'm developping a form that renders differently when hovered and trigger > some processing when not hovered (leaved). The thing is, when I leave my > form and another form from my application is underneath, it works fine, but > if I leave my form and anything that is not from my application is > underneath, the Leave event does not fire until I hover something from my > application. > > Here's my filtered code for the IMessageFilter (I did not pasted the > declarations, I just pasted my message proc) (at the end of the post) > > Can someone tell me what's wrong with this code? > > thanks > > ThunderMusic > > [CODE] > public bool PreFilterMessage(ref Message m) > { > // Everything is done with WM_MOUSEMOVE > if (m.Msg == WM_MOUSEMOVE) > { > // look if the target is our control or contained by our control > Control ctrl = Control.FromHandle(m.HWnd); > if (ctrl != null && (ctrl == this._container || > this._container.Contains(ctrl))) > { > // if this message WM_MOUSEMOVE is the first we get, > // we must trigger the MouseEnter event > if (!this._isEntered) > { > // trigger MouseEnter > this.OnMouseEnter(); > this._isEntered = true; > } > // Get point (using target control coordinates) > Point pt = new Point(m.LParam.ToInt32()); > // convert to controls coordinates if necessary > Point containerPoint; > if (ctrl != this._container) > containerPoint = > this._container.PointToClient(ctrl.PointToScreen(pt)); > else > containerPoint = pt; > // Trigger MouseMove > this.OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, > containerPoint.X, containerPoint.Y, 0)); > } > else > { > // If the target is not a child and MouseLeaves has not been > triggered > // we must trigger MouseLeave > if (this._isEntered) > { > // Trigger MouseLeave > this.OnMouseLeave(); > this._isEntered = false; > } > } > } > return false; > } > [/CODE] hi, thanks for your answer... unfortunately, it's not exactly what I
need... Activate and Deactivate are triggered when a user clicks on a form (activated) or click on another form or minimize (Deactivate)... The behavior I need is when the user move his mouse over the form or out of the form... I agree that the MouseEnter and MouseLeave of the form are hierarchical, that's why I did implement IMessageFilter.... Now the thing is, I must discover how to receive the message (or event) so the program can tell when the mouse cursor went out of the form's boundaries. Thanks ThunderMusic Show quote "Bryan Phillips" <bphillips@nospam.crowechizek.com.spammenot> wrote in message news:O7NrmmW%23GHA.4468@TK2MSFTNGP05.phx.gbl... > Have you tried using the Activated and Deactivated events instead? See > this from MSDN help: > > The Enter and Leave events are suppressed by the Form class. The > equivalent events in the Form class are the Activated and Deactivate > events. The Enter and Leave events are hierarchical and will cascade up > and down the parent chain until the appropriate control is reached. For > example, assume you have a Form with two GroupBox controls, and each > GroupBox control has one TextBox control. When the caret is moved from one > TextBox to the other, the Leave event is raised for the TextBox and > GroupBox, and the Enter event is raised for the other GroupBox and > TextBox. > > Bryan Phillips > MCSD, MCDBA, MCSE > Blog: http://bphillips76.spaces.live.com > > > > > "ThunderMusic" <NoSpAmdanlatathotmaildotcom@NoSpAm.com> wrote in message > news:eh#7bOT#GHA.3456@TK2MSFTNGP02.phx.gbl: > >> Hi, >> I'm developping a form that renders differently when hovered and trigger >> some processing when not hovered (leaved). The thing is, when I leave my >> form and another form from my application is underneath, it works fine, >> but >> if I leave my form and anything that is not from my application is >> underneath, the Leave event does not fire until I hover something from my >> application. >> >> Here's my filtered code for the IMessageFilter (I did not pasted the >> declarations, I just pasted my message proc) (at the end of the post) >> >> Can someone tell me what's wrong with this code? >> >> thanks >> >> ThunderMusic >> >> [CODE] >> public bool PreFilterMessage(ref Message m) >> { >> // Everything is done with WM_MOUSEMOVE >> if (m.Msg == WM_MOUSEMOVE) >> { >> // look if the target is our control or contained by our control >> Control ctrl = Control.FromHandle(m.HWnd); >> if (ctrl != null && (ctrl == this._container || >> this._container.Contains(ctrl))) >> { >> // if this message WM_MOUSEMOVE is the first we get, >> // we must trigger the MouseEnter event >> if (!this._isEntered) >> { >> // trigger MouseEnter >> this.OnMouseEnter(); >> this._isEntered = true; >> } >> // Get point (using target control coordinates) >> Point pt = new Point(m.LParam.ToInt32()); >> // convert to controls coordinates if necessary >> Point containerPoint; >> if (ctrl != this._container) >> containerPoint = >> this._container.PointToClient(ctrl.PointToScreen(pt)); >> else >> containerPoint = pt; >> // Trigger MouseMove >> this.OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, >> containerPoint.X, containerPoint.Y, 0)); >> } >> else >> { >> // If the target is not a child and MouseLeaves has not been >> triggered >> // we must trigger MouseLeave >> if (this._isEntered) >> { >> // Trigger MouseLeave >> this.OnMouseLeave(); >> this._isEntered = false; >> } >> } >> } >> return false; >> } >> [/CODE] > Hi,
Here is your problem. You are using MouseMove event which is based on WM_MOUSEMOVE. This message as any other mouse messages are posted to the window under the mouse cursor. Because you use message filter you receive this message if the mouse is over any form (control) that belongs to your application. However when the mouse moves over window that is not part of your application we just stop receiving mouse messages and there is no notification when this happens they just stop. Windows have three solutions to the problem (at least these are the ones that I can come up with at the moment): installing window hook WH_MOUSE_LL, using TrackMouseEvent API and setting mouse capture. - WH_MOUSE_LL are possible to be implemented in .NET, but it requires using PInvoke and I think it is the hardest one to implement - Setint the mouse capture means that the mouse message will be dispatched to your window even when the mouse cursor is outside of the window. The problem is that it works only if mouse button has been pressed when the mouse is inside the window is held down while moving the mouse. WindowsForms sets the mouse capture when the mouse button is pressed, so it should work by itself, but if it doesn't work for you that means you want to register mouse leave not only when the mouse button is down. - TrackMouseEvent is used internaly by Windows forms and the functionality is exposed as MouseLeave and MouseHover events. Why don't use these events instead of implementing your own solution? The only problem that I see is that you are going to receive mouse leave even if the mouse is inside the form, but enters some form's child control. This cases can be filtered our by checking the form hosting tghe control. The WM_MOUSELEAVE used internally is posted to the message queue, thus can be handeled with message filter -- Show quoteHTH Stoitcho Goutsev (100) "ThunderMusic" <NoSpAmdanlatathotmaildotcom@NoSpAm.com> wrote in message news:OtNY$Wc%23GHA.1196@TK2MSFTNGP02.phx.gbl... > hi, thanks for your answer... unfortunately, it's not exactly what I > need... Activate and Deactivate are triggered when a user clicks on a > form (activated) or click on another form or minimize (Deactivate)... The > behavior I need is when the user move his mouse over the form or out of > the form... > > I agree that the MouseEnter and MouseLeave of the form are hierarchical, > that's why I did implement IMessageFilter.... Now the thing is, I must > discover how to receive the message (or event) so the program can tell > when the mouse cursor went out of the form's boundaries. > > Thanks > > ThunderMusic > > "Bryan Phillips" <bphillips@nospam.crowechizek.com.spammenot> wrote in > message news:O7NrmmW%23GHA.4468@TK2MSFTNGP05.phx.gbl... >> Have you tried using the Activated and Deactivated events instead? See >> this from MSDN help: >> >> The Enter and Leave events are suppressed by the Form class. The >> equivalent events in the Form class are the Activated and Deactivate >> events. The Enter and Leave events are hierarchical and will cascade up >> and down the parent chain until the appropriate control is reached. For >> example, assume you have a Form with two GroupBox controls, and each >> GroupBox control has one TextBox control. When the caret is moved from >> one TextBox to the other, the Leave event is raised for the TextBox and >> GroupBox, and the Enter event is raised for the other GroupBox and >> TextBox. >> >> Bryan Phillips >> MCSD, MCDBA, MCSE >> Blog: http://bphillips76.spaces.live.com >> >> >> >> >> "ThunderMusic" <NoSpAmdanlatathotmaildotcom@NoSpAm.com> wrote in message >> news:eh#7bOT#GHA.3456@TK2MSFTNGP02.phx.gbl: >> >>> Hi, >>> I'm developping a form that renders differently when hovered and trigger >>> some processing when not hovered (leaved). The thing is, when I leave my >>> form and another form from my application is underneath, it works fine, >>> but >>> if I leave my form and anything that is not from my application is >>> underneath, the Leave event does not fire until I hover something from >>> my >>> application. >>> >>> Here's my filtered code for the IMessageFilter (I did not pasted the >>> declarations, I just pasted my message proc) (at the end of the post) >>> >>> Can someone tell me what's wrong with this code? >>> >>> thanks >>> >>> ThunderMusic >>> >>> [CODE] >>> public bool PreFilterMessage(ref Message m) >>> { >>> // Everything is done with WM_MOUSEMOVE >>> if (m.Msg == WM_MOUSEMOVE) >>> { >>> // look if the target is our control or contained by our control >>> Control ctrl = Control.FromHandle(m.HWnd); >>> if (ctrl != null && (ctrl == this._container || >>> this._container.Contains(ctrl))) >>> { >>> // if this message WM_MOUSEMOVE is the first we get, >>> // we must trigger the MouseEnter event >>> if (!this._isEntered) >>> { >>> // trigger MouseEnter >>> this.OnMouseEnter(); >>> this._isEntered = true; >>> } >>> // Get point (using target control coordinates) >>> Point pt = new Point(m.LParam.ToInt32()); >>> // convert to controls coordinates if necessary >>> Point containerPoint; >>> if (ctrl != this._container) >>> containerPoint = >>> this._container.PointToClient(ctrl.PointToScreen(pt)); >>> else >>> containerPoint = pt; >>> // Trigger MouseMove >>> this.OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, >>> containerPoint.X, containerPoint.Y, 0)); >>> } >>> else >>> { >>> // If the target is not a child and MouseLeaves has not been >>> triggered >>> // we must trigger MouseLeave >>> if (this._isEntered) >>> { >>> // Trigger MouseLeave >>> this.OnMouseLeave(); >>> this._isEntered = false; >>> } >>> } >>> } >>> return false; >>> } >>> [/CODE] >> > > Great, it seems to work fine now by filtering on the WM_MOUSELEAVE message
in my MessageFilter. Thanks a lot ThunderMusic "Stoitcho Goutsev (100)" <1**@100.com> a écrit dans le message de news: %23jIU3Ef%23GHA.1***@TK2MSFTNGP02.phx.gbl...Show quote > Hi, > > Here is your problem. You are using MouseMove event which is based on > WM_MOUSEMOVE. This message as any other mouse messages are posted to the > window under the mouse cursor. Because you use message filter you receive > this message if the mouse is over any form (control) that belongs to your > application. However when the mouse moves over window that is not part of > your application we just stop receiving mouse messages and there is no > notification when this happens they just stop. Windows have three > solutions to the problem (at least these are the ones that I can come up > with at the moment): installing window hook WH_MOUSE_LL, using > TrackMouseEvent API and setting mouse capture. > > - WH_MOUSE_LL are possible to be implemented in .NET, but it requires > using PInvoke and I think it is the hardest one to implement > - Setint the mouse capture means that the mouse message will be dispatched > to your window even when the mouse cursor is outside of the window. The > problem is that it works only if mouse button has been pressed when the > mouse is inside the window is held down while moving the mouse. > WindowsForms sets the mouse capture when the mouse button is pressed, so > it should work by itself, but if it doesn't work for you that means you > want to register mouse leave not only when the mouse button is down. > - TrackMouseEvent is used internaly by Windows forms and the > functionality is exposed as MouseLeave and MouseHover events. Why don't > use these events instead of implementing your own solution? > The only problem that I see is that you are going to receive mouse leave > even if the mouse is inside the form, but enters some form's child > control. This cases can be filtered our by checking the form hosting tghe > control. The WM_MOUSELEAVE used internally is posted to the message queue, > thus can be handeled with message filter > > > -- > HTH > Stoitcho Goutsev (100) > > "ThunderMusic" <NoSpAmdanlatathotmaildotcom@NoSpAm.com> wrote in message > news:OtNY$Wc%23GHA.1196@TK2MSFTNGP02.phx.gbl... >> hi, thanks for your answer... unfortunately, it's not exactly what I >> need... Activate and Deactivate are triggered when a user clicks on a >> form (activated) or click on another form or minimize (Deactivate)... >> The behavior I need is when the user move his mouse over the form or out >> of the form... >> >> I agree that the MouseEnter and MouseLeave of the form are hierarchical, >> that's why I did implement IMessageFilter.... Now the thing is, I must >> discover how to receive the message (or event) so the program can tell >> when the mouse cursor went out of the form's boundaries. >> >> Thanks >> >> ThunderMusic >> >> "Bryan Phillips" <bphillips@nospam.crowechizek.com.spammenot> wrote in >> message news:O7NrmmW%23GHA.4468@TK2MSFTNGP05.phx.gbl... >>> Have you tried using the Activated and Deactivated events instead? See >>> this from MSDN help: >>> >>> The Enter and Leave events are suppressed by the Form class. The >>> equivalent events in the Form class are the Activated and Deactivate >>> events. The Enter and Leave events are hierarchical and will cascade up >>> and down the parent chain until the appropriate control is reached. For >>> example, assume you have a Form with two GroupBox controls, and each >>> GroupBox control has one TextBox control. When the caret is moved from >>> one TextBox to the other, the Leave event is raised for the TextBox and >>> GroupBox, and the Enter event is raised for the other GroupBox and >>> TextBox. >>> >>> Bryan Phillips >>> MCSD, MCDBA, MCSE >>> Blog: http://bphillips76.spaces.live.com >>> >>> >>> >>> >>> "ThunderMusic" <NoSpAmdanlatathotmaildotcom@NoSpAm.com> wrote in message >>> news:eh#7bOT#GHA.3456@TK2MSFTNGP02.phx.gbl: >>> >>>> Hi, >>>> I'm developping a form that renders differently when hovered and >>>> trigger >>>> some processing when not hovered (leaved). The thing is, when I leave >>>> my >>>> form and another form from my application is underneath, it works fine, >>>> but >>>> if I leave my form and anything that is not from my application is >>>> underneath, the Leave event does not fire until I hover something from >>>> my >>>> application. >>>> >>>> Here's my filtered code for the IMessageFilter (I did not pasted the >>>> declarations, I just pasted my message proc) (at the end of the post) >>>> >>>> Can someone tell me what's wrong with this code? >>>> >>>> thanks >>>> >>>> ThunderMusic >>>> >>>> [CODE] >>>> public bool PreFilterMessage(ref Message m) >>>> { >>>> // Everything is done with WM_MOUSEMOVE >>>> if (m.Msg == WM_MOUSEMOVE) >>>> { >>>> // look if the target is our control or contained by our >>>> control >>>> Control ctrl = Control.FromHandle(m.HWnd); >>>> if (ctrl != null && (ctrl == this._container || >>>> this._container.Contains(ctrl))) >>>> { >>>> // if this message WM_MOUSEMOVE is the first we get, >>>> // we must trigger the MouseEnter event >>>> if (!this._isEntered) >>>> { >>>> // trigger MouseEnter >>>> this.OnMouseEnter(); >>>> this._isEntered = true; >>>> } >>>> // Get point (using target control coordinates) >>>> Point pt = new Point(m.LParam.ToInt32()); >>>> // convert to controls coordinates if necessary >>>> Point containerPoint; >>>> if (ctrl != this._container) >>>> containerPoint = >>>> this._container.PointToClient(ctrl.PointToScreen(pt)); >>>> else >>>> containerPoint = pt; >>>> // Trigger MouseMove >>>> this.OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, >>>> containerPoint.X, containerPoint.Y, 0)); >>>> } >>>> else >>>> { >>>> // If the target is not a child and MouseLeaves has not >>>> been >>>> triggered >>>> // we must trigger MouseLeave >>>> if (this._isEntered) >>>> { >>>> // Trigger MouseLeave >>>> this.OnMouseLeave(); >>>> this._isEntered = false; >>>> } >>>> } >>>> } >>>> return false; >>>> } >>>> [/CODE] >>> >> >> > > |
|||||||||||||||||||||||