Announcement

Collapse
No announcement yet.

Menu Handle <> Window Handle?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Menu Handle <> Window Handle?

    Im trying to intercept menu notifications (which i do successfully) using SetWinEventHook(), however, the window that the procedure reports is not a valid Menu handle...

    Heres some code:

    Code:
    FUNCTION WinEventFunc(BYVAL HookHandle AS LONG, BYVAL LEvent AS LONG, BYVAL hWnd AS LONG, BYVAL idObject AS LONG, BYVAL idChild AS LONG, BYVAL idEventThread AS LONG, BYVAL dwmsEventTime AS LONG) AS LONG
    
    If IsMenu(hWnd) then Beep ' Never beeps
    
    call ShowWindow(hwnd, %false)  ' Hides the popup
    
        FUNCTION = %TRUE
    END FUNCTION
    Any ideas?

  • #2
    Example of the issue:

    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "WIN32API.INC"
    
    FUNCTION WinEventFunc(BYVAL HookHandle AS LONG, BYVAL LEvent AS LONG, BYVAL hWnd AS LONG, BYVAL idObject AS LONG, BYVAL idChild AS LONG, BYVAL idEventThread AS LONG, BYVAL dwmsEventTime AS LONG) AS LONG
       
        IF isMenu(hWNd) THEN BEEP              ' Never beeps
        
        CALL ShowWindow(hWNd, %SW_HIDE)        ' Hides the popup menu
        
        FUNCTION = 1
    END FUNCTION
    
    CALLBACK FUNCTION ShowDIALOG1Proc()
    
        STATIC LHook AS DWORD
        LOCAL Result AS LONG
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
                  LHook = SetWinEventHook(%EVENT_SYSTEM_MENUPOPUPSTART, %EVENT_SYSTEM_MENUPOPUPSTART, 0, _
                                          CODEPTR(WinEventFunc), 0, 0, %WINEVENT_OUTOFCONTEXT OR %WINEVENT_SKIPOWNTHREAD)
    
            CASE %WM_DESTROY
                  Result = UnhookWinEvent(LHook)
        END SELECT
    
    END FUNCTION
    
    FUNCTION PBMAIN()
        LOCAL hDlg AS DWORD
    
        DIALOG  NEW %HWND_DESKTOP, "SetWinEventHook", 200, 100, 200,100, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_CAPTION OR _
                                   %WS_SYSMENU OR %WS_MINIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME, _
                                   %WS_EX_WINDOWEDGE OR %WS_EX_CONTROLPARENT OR %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
                                   %WS_EX_RIGHTSCROLLBAR, TO hDlg
        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc
        
    END FUNCTION

    Comment


    • #3
      Hi Elias,

      How's this?

      Code:
      #COMPILE EXE
      #DIM ALL
      #INCLUDE "WIN32API.INC"
      
      %MN_GETHMENU = &H01E1
      
      FUNCTION WinEventFunc(BYVAL HookHandle AS LONG, BYVAL LEvent AS LONG, BYVAL hWnd AS LONG, BYVAL idObject AS LONG, BYVAL idChild AS LONG, BYVAL idEventThread AS LONG, BYVAL dwmsEventTime AS LONG) AS LONG
         LOCAL hMenu AS DWORD
      
         hMenu = SendMessage(hWnd, %MN_GETHMENU, 0,0)
         IF IsMenu(hMenu) THEN
            BEEP
         END IF
         CALL ShowWindow(hWNd, %SW_HIDE)        ' Hides the popup menu
         EndMenu
      
         FUNCTION = 1
      END FUNCTION
      
      CALLBACK FUNCTION ShowDIALOG1Proc()
      
          STATIC LHook AS DWORD
          LOCAL Result AS LONG
      
          SELECT CASE AS LONG CBMSG
              CASE %WM_INITDIALOG
                    LHook = SetWinEventHook(%EVENT_SYSTEM_MENUPOPUPSTART, %EVENT_SYSTEM_MENUPOPUPSTART, 0, _
                                            CODEPTR(WinEventFunc), 0, 0, %WINEVENT_OUTOFCONTEXT) 'OR %WINEVENT_SKIPOWNTHREAD)
      
              CASE %WM_DESTROY
                    Result = UnhookWinEvent(LHook)
          END SELECT
      
      END FUNCTION
      
      FUNCTION PBMAIN()
          LOCAL hDlg AS DWORD
      
          DIALOG  NEW %HWND_DESKTOP, "SetWinEventHook", 200, 100, 200,100, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_CAPTION OR _
                                     %WS_SYSMENU OR %WS_MINIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME, _
                                     %WS_EX_WINDOWEDGE OR %WS_EX_CONTROLPARENT OR %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
                                     %WS_EX_RIGHTSCROLLBAR, TO hDlg
          DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc
      
      END FUNCTION
      Note that I've removed the %WINEVENT_SKIPOWNTHREAD from the initial call, or the callback doesn't fire at all (here at least). Also, using ShowWindow in the callback hides the menu window, but doesn't prevent me clicking on items from it where they were displayed - i.e. it just gives me an invisible, but still fully active, menu. So I've added EndMenu instead, to remove it. Lastly, getting hMenu isn't really necessary for the code shown here, as EndMenu doesn't take a parameter, but I've shown it in case you want to do other things with the menu.

      I hope that helps.

      Regards,

      Pete.

      Comment


      • #4
        Code not shown (for SetWinEventHook) so I can't tell if you are trying to hide a the window from another process or from your own, but if it's your own process using a hook is kinda overkill....
        WM_INITMENU
        The WM_INITMENU message is sent when a menu is about to become active. It occurs when the user clicks an item on the menu bar or presses a menu key. This allows the application to modify the menu before it is displayed
        WM_INITMENUPOPUP
        The WM_INITMENUPOPUP message is sent when a drop-down menu or submenu is about to become active. This allows an application to modify the menu before it is displayed, without changing the entire menu
        .. Oops, I see now in the SECOND post it does appear you want to 'do something' based on other processes' activity.

        In that case...
        The client thread that calls SetWinEventHook must have a message loop, sometimes known as a "GUI thread," in order to receive events.
        Maybe the Modal dialogbox message loop is insufficient and you need a 'real' message loop associated with the calling thread.

        Try changing your DIALOG SHOW to MODELESS and add a message loop and see what happens.

        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Hello Peter,

          That seems to work with Dialog menus, but it fails with menus created with TrackPopupMenu. I dont seem to find any way to get the handle of menues created with TrackPopupMenu in other processes.

          Michael, i will try to use the dialog handle to temporarily suibclass the target dialog and get the handle of the menu.

          Thanx

          Comment


          • #6
            What are you trying to do?

            Seems like... you put up a popup window, and you want it to disappear as soon as the user does....... "something?" Tries to use any menu in any program? Presses a key or moves or clicks the mouse?

            Than again, maybe instead of an event hook you should be doing a message hook on WM_INITMENU and WM_INITMENUPOPUP.


            MCM
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              Hello Michael. What im trying to do? Im trying to disable globally any menu options named "properties". Its for the Internet cafe program i made. I dont want users to mess with properties of anything on the PC.

              So far i can only get the window handle of the popup menu, but i can't get the menu handle. And seems like im not alone, according to this forum, a guy named Roger allen tried to do exactly what im trying to do.

              So, basically what im trying to do is to translate hWnd to hMenu, because SetWinEventHook() reports only the hWnd but leaves out the hMenu.

              Comment


              • #8
                Disregard, Seems like Peter hit the nail, But i thought it wasnt working because i mistyped the Declaration of MN_GETHMENU (as it wasnt in my Win32api.inc i looked for it in the web (0x01E1)).

                Thanx.

                Comment


                • #9
                  What declaration did you end up using?
                  Rgds, Dave

                  Comment


                  • #10
                    I used &h01E1

                    I will post the final code in the source code forum.

                    Comment


                    • #11
                      Originally posted by Elias Montoya View Post
                      I used &h01E1
                      See post #3, 4th line of source code....

                      Comment


                      • #12
                        Originally posted by Peter Jinks View Post
                        See post #3, 4th line of source code....
                        OHHH!!

                        Gotta pay more attention!

                        Heres the final work:
                        http://www.powerbasic.com/support/pb...553#post306553

                        Comment

                        Working...
                        X