How to remove item from string gadget context menu?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

How to remove item from string gadget context menu?

Post by Lord »

Hi!

How can I remove one or more items from a string gadget context menu?

Code: Select all

OpenWindow(1, 10, 10, 640, 400, "Window with String Gadget")
StringGadget(9, 10, 10, 620, 24," something...")
Debug GadgetID(9)
hMenu= GetMenu_(GadgetID(9))
Debug hMenu
Debug RemoveMenu_(hmenu, 3, #MF_BYPOSITION); example: remove third entry

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
GetMenu_() returns number of StringGadget?

Finally I want to remove the last five entries and the last two menu bars of
the context menu. Is there a way?
Image
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: How to remove item from string gadget context menu?

Post by RASHAD »

You can not do it
But you can create your own context menu

Code: Select all

Global Oldproc

Procedure StringCallback(hWnd, uMsg, wParam, lParam)
 Select uMsg
    Case #WM_CONTEXTMENU
            DisplayPopupMenu(0, WindowID(0))
      ProcedureReturn 0
            
  EndSelect
 ProcedureReturn CallWindowProc_(Oldproc, hWnd, uMsg, wParam, lParam)
EndProcedure

LoadFont(0,"georgia",12)
 If OpenWindow(0, 0, 0, 300, 50, "StrinGadget Context Menu",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget| #PB_Window_ScreenCentered )
			If CreatePopupMenu(0)
			  MenuItem(1, "Copy")
			  MenuItem(2, "Cut")
			  MenuItem(3, "Paste")
			  MenuBar()
			  MenuItem(4, "Undo")
			  MenuBar()
			  MenuItem(5, "Delete")
			  MenuBar()
			  MenuItem(6, "Quit")
			EndIf


        StringGadget(0, 10, 10, 280, 30, "")
        SetGadgetFont(0,FontID(0))
        Oldproc = SetWindowLongPtr_(GadgetID(0), #GWL_WNDPROC, @StringCallback())

Repeat
  Select WaitWindowEvent(1) 
     Case #PB_Event_CloseWindow
             Quit = 1
             
     Case #PB_Event_Menu
            Select EventMenu()
                    Case 1
                            SendMessage_(GadgetID(0),#WM_COPY,0,0)
                    Case 2
                            SendMessage_(GadgetID(0),#WM_CUT,0,0)
                    Case 3
                            SendMessage_(GadgetID(0),#WM_PASTE,0,0)
                    Case 4
                            SendMessage_(GadgetID(0),#WM_UNDO,0,0)
                    Case 5
                            SendMessage_(GadgetID(0),#WM_CLEAR,0,0)
                    Case 6
                            Quit = 1
            EndSelect

     Case #PB_Event_Gadget
            Select EventGadget()
                   Case 0
            EndSelect
  EndSelect

Until Quit = 1
EndIf
End
Egypt my love
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

Re: How to remove item from string gadget context menu?

Post by Lord »

Hi Rashad!

Thank you for your answer.
RASHAD wrote:You can not do it
But you can create your own context menu
...
That's bad. :cry:
I already have my own popup menu, but I thought
that if there is already a windows context menu,
it would be smarter just to use this menu and only
remove or disable the unwanted menu items.
In system menu you can remove a menu item by
using GetSystemMenu_() and RemoveMenu_().
Image
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: How to remove item from string gadget context menu?

Post by netmaestro »

GetMenu_() returns number of StringGadget?
Actually MSDN says that for child windows the return value is undefined. Child windows cannot host a menu. But this is a context menu, something different. You can make your own, but if you prefer to modify the system context menu for a control, I'll show you a trick. The code works in two steps: One, a message hook catches the menu being created and records the hwnd for its window. But at this point it's too early in the process to retrieve a hMenu. So then Two, a message containing this hwnd is sent asynchronously (PostMessage not SendMessage) to the winproc of the main window. By the time this message is received and processed, a hMenu is available for retrieval via MN_GETHMENU. From here Bob's your uncle and you can use RemoveMenu, ModifyMenu, SetMenuItemInfo, etc. Basically any command that requires a hMenu.

Code: Select all

; Yet another useless program from netmaestro

#WM_HOLYCONTEXTMENUBATMAN = #WM_APP + 1

Procedure HookProc(nCode, wParam, lParam) 
  
  If (nCode = #HC_ACTION)
    *cwps.CWPSTRUCT = lParam
    Select *cwps\message
        
      Case #WM_CREATE
        szClass.s=Space(128)
        GetClassName_(*cwps\hwnd, @szClass, 127)
        If szClass="#32768"
          PostMessage_(WindowID(0), #WM_HOLYCONTEXTMENUBATMAN, *cwps\hwnd, 0) ; Must institute a delay before executing MN_GETMENU
        EndIf
        
    EndSelect 
  EndIf
  
  ProcedureReturn CallNextHookEx_(0, nCode, wParam, lParam)
  
EndProcedure

Procedure WinProc(hwnd, msg, wparam, lparam)
  Static g_hHook
  
  Select msg 
      
    Case #WM_PARENTNOTIFY
      If wparam & $FFFF = #WM_RBUTTONDOWN ; Detect right-click on child windows
        With wp.POINT
          \x = lparam & $FFFF
          \y = lparam >> 16
        EndWith
        MapWindowPoints_( WindowID(0), #HWND_DESKTOP, @wp, 1)
        If WindowFromPoint_(PeekQ(@wp)) = GadgetID(0) ; Modify menu for only selected controls
          g_hHook = SetWindowsHookEx_(#WH_CALLWNDPROC, @HookProc(), #Null, GetCurrentThreadId_())
        EndIf
      EndIf
      ProcedureReturn 0
      
    Case  #WM_HOLYCONTEXTMENUBATMAN
      hwnd = wparam
      hmenu = SendMessage_(hwnd, #MN_GETHMENU,0,0) ; Get the hMenu and modify it
      RemoveMenu_(hmenu, 6, #MF_BYPOSITION)        ; Remove menubar
      RemoveMenu_(hmenu, 5, #MF_BYPOSITION)        ; Remove 'Delete'
      RemoveMenu_(hmenu, 4, #MF_BYPOSITION)        ; Remove 'Paste'
      RemoveMenu_(hmenu, 3, #MF_BYPOSITION)        ; Remove 'Copy'
      RemoveMenu_(hmenu, 2, #MF_BYPOSITION)        ; Remove 'Cut'
      UnhookWindowsHookEx_(g_hHook)                ; So as not to affect submenus
      
  EndSelect
  
  ProcedureReturn #PB_ProcessPureBasicEvents
  
EndProcedure

OpenWindow(0,0,0,320,240,"", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

SetWindowCallback(@WinProc())
StringGadget(0,20,40,200,20,"stuff")

Repeat
  EventID = WaitWindowEvent()
Until EventID=#PB_Event_CloseWindow
BERESHEIT
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

Re: How to remove item from string gadget context menu?

Post by Lord »

Hi netmaestro!
netmaestro wrote:...

Code: Select all

; Yet another useless program from netmaestro
...
I think this is PureUnderstatement.
Your code worked like a charm.
Thank you for this masterpiece.
Image
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: How to remove item from string gadget context menu?

Post by Kwai chang caine »

Waouuhh !!! Great code, very useful for me :shock:
Thanks Netmaestro 8)
ImageThe happiness is a road...
Not a destination
schic
User
User
Posts: 34
Joined: Fri Sep 12, 2003 10:17 am

Re: How to remove item from string gadget context menu?

Post by schic »

Thanks Netmaestro the Program my be usless but not the code

but to use it I had to set g_hHook to static otherwise mainmenus are affected

Code: Select all

Procedure WinCallback(hwnd, msg, wparam, lparam)
  Static g_hHook
...
Post Reply