CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 17
  1. #1
    Join Date
    Apr 2002
    Location
    Australia
    Posts
    54

    Question Popup menu on mousemove message

    Hi,

    I am trying to implement a popup menu that opens on a mousemove message rather than a right mouse click. When the cursor is in a particular region of the client window, the popup menu should be displayed. If the mouse moves to a different region, the original popup menu should 'disappear' and a modified menu should appear that is specific to that region.

    I am finding this quite difficult to get working - does anyone have any ideas for me? This has been my approach so far:

    In the OnMouseMove handler - I check the cursor coordinates and create/load the popup menu specific to the region. Because I am using TrackPopupMenu to display the popup menu, no other mouse move messages were getting through until I closed that menu or select an item from it.

    My attempt at a solution (after searching on CodeGuru) was to use a thread specific hook to catch the mousemove message - to do this I used:

    Code:
    SetWindowsHookEx(WH_MOUSE, MouseHook, NULL,GetCurrentThreadId());
    The MouseHook function is declared as:

    Code:
    LRESULT CALLBACK MouseHook(int nCode, WPARAM wParam,  LPARAM lParam)
    In this function I check if it is a mousemove message and then call the same code to check the region and create a new popup menu.

    My problem is that the popup menu will display the first time and then will remain on the screen until I close it or select an item from it .... if I step into the code, the MouseHook function is being called and sometimes fires the code to create a new menu, but it doesn't seem to work. I am not sure if my problem lies in how I am implementing the creation of the menu or how I am trying to create and use the windows hook.

    Sorry for the lengthy explanation, but can anyone shed some light on this problem? Or perhaps suggest a better way to achieve the same result??

    thanks,
    Em
    Last edited by Emster; April 14th, 2004 at 05:46 PM.

  2. #2
    Join Date
    May 1999
    Location
    West Sussex, England
    Posts
    1,939
    At a guess, the problem is probably due to the open menu. You need to dismiss the one that is open before trying to pop up the next one. My only suggestion on doing this, is to use SetFocus() onto a different control so that the menu gets killed. Then create the new one.
    Please use meaningful question titles - "Help me" does not let me know whether I can help with your question, and I am unlikely to bother reading it.
    Please remember to rate useful answers. It lets us know when a question has been answered.

  3. #3
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917

    Re: Popup menu on mousemove event

    Originally posted by Emster
    Because I am using TrackPopupMenu to display the popup menu, no other mouse move events were getting through until I close that menu or select an item from it.
    To clarify you should refer to handling mouse messages not events. Events are handled in VB.
    Anytime menu pops up menu enters its modal loop and captures mouse. Roger’s guess is correct. You have to dismiss menu somehow before you invoke another one.
    GetLastError returns 0x000005A6 - Popup menu already active.
    Originally posted by Emster
    My attempt at a solution (after searching on CodeGuru) was to use a thread specific hook to catch the mousemove event - to do this I used:
    .
    .
    . In this function I check if it is a mousemove event and then fire the same code to check the region and create a new popup menu.
    this approach is correct. It allows you to catch WM_MOUSEMOVE message and act on it. Again nothing is fired here this is C++ MFC programming - mouse message is being sent to a window and you catch it inside of the hook.
    Originally posted by Emster
    My problem is that the popup menu will display the first time and then will remain on the screen until I close it or select an item from it
    You can use several approaches to dismiss menu.

    Some coding: call SendInput. You with INPUT dwFlags set to MOUSEEVENTF_LEFTDOWN. You would have to make sure that cursor is not in menu area.

    The simplest. Use PostMessage(WM_LBUTTONDOWN, 0, 0); it always works.

    You can also use FindWindow to find menu and DestroyWindow to dismiss menu.
    There are only 10 types of people in the world:
    Those who understand binary and those who do not.

  4. #4
    Join Date
    Feb 2000
    Location
    San Diego, CA
    Posts
    10,354
    or post a WM_CANCELMODE event to the owner of the menu. I guess this is a graceful way according to MSDN.

  5. #5
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917
    Right. Forgot to mention that.
    There are only 10 types of people in the world:
    Those who understand binary and those who do not.

  6. #6
    Join Date
    Apr 2002
    Location
    Australia
    Posts
    54
    Thankyou Roger Allen and Kirants for your suggestions on closing the menu and a special thanks to JohnCz for your detailed help and explanation of my problem (+ corrections of my programming terminology ).

    I have now solved my problem by closing the first popup menu, then creating and displaying the new one. I had previously tried to send an LBUTTONDOWN message to close it, but was doing it incorrectly - so now I have corrected my code it works! I am now going to try the other alternatives suggested to see if they work equally as well.

    thanks again!!
    Emelia

  7. #7
    Join Date
    Apr 2002
    Location
    Australia
    Posts
    54
    Hi again,

    After solving my initial problem with this popup menu, I have run into another one. I thought I would continue in this thread as all my background info is here.

    Anyway - the problem is that the FIRST time my popup menu is displayed, moving the mouse into another region will not dismiss the menu. After some debugging it seems that although I have set the windows hook to capture the mouse move message, NO mouse move messages are actually getting through (ie: the hook is not catching them, so my code to close the menu and reopen is not being reached).
    If I close that initial menu and move the mouse into a new region, it works fine from then on. It is only failing on the first time.

    Does anyone have any ideas about this? Could something else be stopping the mouse messages from getting through?


    thanks
    Em

  8. #8
    Join Date
    Apr 2002
    Location
    Australia
    Posts
    54
    I found this in MSDN (note the bold section):
    WH_MOUSE
    Windows calls this hook when a GetMessage or a PeekMessage function is called and Windows has a mouse message to process. Like the WH_KEYBOARD hook, this filter function receives a hook code, which indicates whether the message is being removed (HC_NOREMOVE), an identifier specifying the mouse message, and the x and y coordinates of the mouse. Filters can tell Windows to discard the message. Filters for this hook must reside in a DLL.
    I have not used a DLL for my WH_MOUSE filter function - perhaps this is my problem. I was under the impression that I only had to use a DLL for implementing system-wide hooks.... but perhaps the WH_MOUSE hook is the exception.

    Has anyone else come across this? I would appreciate your feedback if you have...

    thanks
    Em

  9. #9
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917
    Originally posted by Emster
    I was under the impression that I only had to use a DLL for implementing system-wide hooks.... but perhaps the WH_MOUSE hook is the exception.
    I am not sure what do you mean by another region in your previous post.

    You are correct. System wide hooks would have to be in a dll since that dll is loaded into a address space of all processes.

    There is big confusion as how to install global hook and discussion about that falls beyond a scope of this forum.

    We have two different kinds of hooks system-wide (global) or thread specific.

    WH_MOUSE hook can be both.
    If you install hook in exe module and pass thread ID it will filter messages for that thread only. It stops monitoring if you are outside of thread window, and continues when mouse is back over this window.

    If you pass module handle not a thread ID, it will filter messages for local thread, but as soon as you leave window of that thread, a hook you install will be disconnected from a chain.

    But you have another choice: window NT introduced so called low level hooks: WH_MOUSE_LL and WH_KEYBOARD_LL. They are both global only; therefore after installing WH_MOUSE_LL hook you will be able to catch all mouse messages for all threads from the desktop.
    Last edited by JohnCz; April 19th, 2004 at 03:35 PM.
    There are only 10 types of people in the world:
    Those who understand binary and those who do not.

  10. #10
    Join Date
    Apr 2002
    Location
    Australia
    Posts
    54
    Hi,

    What I mean by 'another region' is: the window the mouse is moving over is divided up into application-specific regions (really just rectangles at different co-ordinates). When the mouse moves from one of these regions to another, a new menu should popup. It works AFTER the first time, but not ON the first time. Does that make it more clear?

    So, because of this, I am assuming I only need to use thread-specific hooks ie: I don't care about what the mouse is doing in any other application window apart from my own. The documentation I was reading, however, seemed to suggest that I needed to use a DLL for ANY WH_MOUSE filter function.... but it doesn't sound like it from your post.....

    thanks again for your reply,
    Em

  11. #11
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917
    Originally posted by Emster
    I needed to use a DLL for ANY WH_MOUSE filter function.... but it doesn't sound like it from your post.....
    As I have already mentioned, you do not have to have your hook procedure in a dll if this is WH_MOUSE and hook is thread specific.

    You can consider using WH_MOUSE_LL that is always global and does not to be in a DLL.
    There are only 10 types of people in the world:
    Those who understand binary and those who do not.

  12. #12
    Join Date
    Apr 2002
    Location
    Australia
    Posts
    54
    ok - thanks JohnCz.... that clears up that issue.

    Now I just have to go back and see why it is not working.

    thanks for all your help,
    Emelia

  13. #13
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917
    You are welcome.
    Let me know how it works.
    There are only 10 types of people in the world:
    Those who understand binary and those who do not.

  14. #14
    Join Date
    Apr 2002
    Location
    Australia
    Posts
    54

    Unhappy still not working...

    Hi,

    I am still not receiving any WM_MOUSEMOVE messages the first time I set the mouse hook (WH_MOUSE).

    I tried using a WH_MOUSE_LL hook instead (as JohnCz suggested), but I cannot compile - WH_MOUSE_LL is an unknown identifier. I am using Win2000 SP4. I have tried include "winuser.h" and "windows.h" but still no luck.

    Any suggestions?
    thanks,
    EM
    Last edited by Emster; April 29th, 2004 at 02:22 AM.

  15. #15
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917
    Sample:
    Attached Files Attached Files
    There are only 10 types of people in the world:
    Those who understand binary and those who do not.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured