Block RightMouse Click on Stringagdget.

Just starting out? Need help? Post your questions and find answers here.
GenRabbit
Enthusiast
Enthusiast
Posts: 151
Joined: Wed Dec 31, 2014 5:41 pm

Block RightMouse Click on Stringagdget.

Post by GenRabbit »

I trying to intercept right click's on stringadgets and kill them of so the popupmenu do not appear if there is bad data in the Clipboard so they can't paste.

I'm checking it in an Callback if the mousepointer is over the gadgets and the code know when I'm over the gadget. tried to set uMsg to 0, wParam to 0 and both to zero, but the window popupmenu still comes up.
Is #WM_RBUTTONDown the place to kill it of at all?

As of now, Its not doing anything with the clipboard except check it.

Code: Select all

	Procedure.i WindowCallback(hWnd.i, uMsg.i, WParam.i, LParam.i)
		Protected.i GadgetClicked
		Protected.POINT pt
		Protected.s sTemp
		Protected.i x, i
		Protected.w IsNumber
		Protected.w Character
		Select WParam
			Case #WM_RBUTTONDOWN
				sTemp = GetClipboardText()
				i = Len(sTemp)
				IsNumber = 1
				While x < i
					Character = PeekW(@sTemp+ (x * #SizeWord))
					If character > #VK_9 Or character < #VK_0
						isnumber = 0
						Break
					EndIf
					x + 1
				Wend
				GetCursorPos_(@pt)
				GadgetClicked = WindowFromPoint_(PeekQ(@pt))
				Select GadgetClicked
					Case HwndMinutesFromTheBeginning ;#TxtMinutesFromTheBeginning
						Debug "MFTB"
						;uMsg = 0
					Case HwndHourInDay ;#TxtHourInDay
						Debug "HID"
						;uMsg = 0
					Case HwndMinutesInHour ;#TxtMinutesInHour
						Debug "MIAH"
						;uMsg = 0
				EndSelect
				
			EndSelect
		ProcedureReturn #PB_ProcessPureBasicEvents	
	EndProcedure
BarryG
Addict
Addict
Posts: 4123
Joined: Thu Apr 18, 2019 8:17 am

Re: Block RightMouse Click on Stringagdget.

Post by BarryG »

GenRabbit wrote: Sat Dec 07, 2024 12:28 amI trying to intercept right click's on stringadgets and kill them of so the popupmenu do not appear if there is bad data in the Clipboard so they can't paste.
But the user can still Ctrl+V or Win+V to paste it. :)

Maybe it's better to monitor the StringGadget for banned text and clear it if found. Or maybe monitor the clipboard with GetClipboardText() and then use FindString() to see if the banned text is in it; and if so, do SetClipboardText("") to clear the clipboard text. Mind you, this should only be done for a private app, or only if the user knows that the clipboard is being monitored for banned text.
GenRabbit
Enthusiast
Enthusiast
Posts: 151
Joined: Wed Dec 31, 2014 5:41 pm

Re: Block RightMouse Click on Stringagdget.

Post by GenRabbit »

The ctrl+v/Win+v should be easier. As for banned text its everything which is not a number.
Banned is probably the wrong word here. Not allowed should be better. And numbers is the only thing allowed in the stringadgets.
BarryG
Addict
Addict
Posts: 4123
Joined: Thu Apr 18, 2019 8:17 am

Re: Block RightMouse Click on Stringagdget.

Post by BarryG »

GenRabbit wrote: Sat Dec 07, 2024 2:52 amnumbers is the only thing allowed in the stringadgets
In that case, just use the #PB_String_Numeric flag with them, so only numbers can be typed or pasted into them. No need for a callback or to block the right-click menu. You're going about it the hard way. ;)
GenRabbit
Enthusiast
Enthusiast
Posts: 151
Joined: Wed Dec 31, 2014 5:41 pm

Re: Block RightMouse Click on Stringagdget.

Post by GenRabbit »

Already done. But if someone either paste or hit a letter I get a message bubble poping up saying letters are not allowed. and the like.
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Block RightMouse Click on Stringagdget.

Post by breeze4me »

See the code.

Code: Select all

Procedure WndProcString(hWnd, uMsg, wParam, lParam)
  Protected old = GetProp_(hWnd, "OldWndProc")
  
  Select uMsg
    Case #WM_CHAR
      
      If wParam <> 8 And (wParam < '0' Or wParam > '9')   ; Only 0 through 9 and backspace are allowed.
        ProcedureReturn 0
      EndIf
      
    Case #WM_PASTE          ; Block paste.
      ProcedureReturn 0
      
    Case #WM_CONTEXTMENU    ; Block popup menu.
      ProcedureReturn 0
      
    Case #WM_NCDESTROY
      RemoveProp_(hWnd, "OldWndProc")
      
  EndSelect
  
  ProcedureReturn CallWindowProc_(old, hWnd, uMsg, wParam, lParam)
EndProcedure

If OpenWindow(11, 0, 0, 322, 205, "StringGadget Flags", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  StringGadget(0, 8,  10, 306, 20, "Normal StringGadget...")
  StringGadget(1, 8,  35, 306, 20, "1234567")
  StringGadget(2, 8,  60, 306, 20, "7654321")
  
  hWnd = GadgetID(1)
  SetProp_(hWnd, "OldWndProc", SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, @WndProcString()))
  
  hWnd = GadgetID(2)
  SetProp_(hWnd, "OldWndProc", SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, @WndProcString()))
  
  
  Repeat
    e = WaitWindowEvent()
    
  Until e = #PB_Event_CloseWindow
EndIf
GenRabbit
Enthusiast
Enthusiast
Posts: 151
Joined: Wed Dec 31, 2014 5:41 pm

Re: Block RightMouse Click on Stringagdget.

Post by GenRabbit »

@Breeze4me: Thanks, that helped a lot.
I worked on it a little and run into a new problem.
I use dynamic menu, in other word destroy and rebuild each time.
Now when I choose an Item in the menu, is there a way to get what item from popupmenu is chosen?

If I use my old WINAPI code from my VB6 which I'm converting, I could use that, but I'd prefer to use as little WINAPI is possible

At the moment the eventmenu() can get what I choose inside the main program loop, but that means If I have to go that way that I need to send info from the callback to the mainloop using globals. And I'd prefer to do it all inside the callback.
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Block RightMouse Click on Stringagdget.

Post by breeze4me »

Maybe something like this?

Code: Select all

Enumeration 
  #PopupMenu1
  #PopupMenu2
EndEnumeration

Procedure CreatePopupMenu1()
  If CreatePopupMenu(#PopupMenu1)
    MenuItem(1, "Menu Item 1")
    MenuItem(2, "Save")
    MenuBar()
    OpenSubMenu("Recent files")
      MenuItem(3, "PureBasic.exe")
      MenuItem(4, "Test.txt")
    CloseSubMenu()
  EndIf
EndProcedure

Procedure CreatePopupMenu2()
  If CreatePopupMenu(#PopupMenu2)
    MenuItem(11, "Menu Item 2")
    MenuItem(12, "Save as")
    MenuBar()
    MenuItem(13, "Quit")
  EndIf
EndProcedure

Procedure WndProcString(hWnd, uMsg, wParam, lParam)
  Protected old = GetProp_(hWnd, "OldWndProc")
  
  Select uMsg
    Case #WM_CHAR
      
      If wParam <> 8 And (wParam < '0' Or wParam > '9')   ; Only 0 through 9 and backspace are allowed.
        ProcedureReturn 0
      EndIf
      
    Case #WM_PASTE          ; Block paste.
      ProcedureReturn 0
      
    Case #WM_CONTEXTMENU
      
      Protected Gadget = GetWindowLongPtr_(hWnd, #GWLP_ID)
      Protected MenuItemID
      
      If GadgetID(Gadget) = hWnd
        Select Gadget
          Case 1
            SetActiveGadget(Gadget)
            
            If IsMenu(#PopupMenu1) = 0
              CreatePopupMenu1()
            EndIf
            
            MenuItemID = TrackPopupMenu_(MenuID(#PopupMenu1), #TPM_RETURNCMD, DesktopMouseX(), DesktopMouseY(), 0, WindowID(11), 0)
            
            If MenuItemID
              Debug "Selected MenuItemID = " + MenuItemID
            Else
              Debug "Canceled."
            EndIf
            
          Case 2
            SetActiveGadget(Gadget)
            
            If IsMenu(#PopupMenu2) = 0
              CreatePopupMenu2()
            EndIf
            
            MenuItemID = TrackPopupMenu_(MenuID(#PopupMenu2), #TPM_RETURNCMD, DesktopMouseX(), DesktopMouseY(), 0, WindowID(11), 0)
            
            If MenuItemID
              Debug "Selected MenuItemID = " + MenuItemID
            Else
              Debug "Canceled."
            EndIf
            
        EndSelect
        
      EndIf
      
      ProcedureReturn 0    ; Block system popup menu.
      
    Case #WM_NCDESTROY
      RemoveProp_(hWnd, "OldWndProc")
      
  EndSelect
  
  ProcedureReturn CallWindowProc_(old, hWnd, uMsg, wParam, lParam)
EndProcedure

If OpenWindow(11, 0, 0, 322, 205, "StringGadget Flags", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  StringGadget(0, 8,  10, 306, 20, "Normal StringGadget...")
  StringGadget(1, 8,  35, 306, 20, "1234567")
  StringGadget(2, 8,  60, 306, 20, "7654321")
  
  hWnd = GadgetID(1)
  SetProp_(hWnd, "OldWndProc", SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, @WndProcString()))
  
  hWnd = GadgetID(2)
  SetProp_(hWnd, "OldWndProc", SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, @WndProcString()))
  
  Repeat
    e = WaitWindowEvent()
    
  Until e = #PB_Event_CloseWindow
EndIf
GenRabbit
Enthusiast
Enthusiast
Posts: 151
Joined: Wed Dec 31, 2014 5:41 pm

Re: Block RightMouse Click on Stringagdget.

Post by GenRabbit »

Thanks, Hoped it could be done without using WINAPI, but TrackPopupMenu_ it is. The same one I used in my VB6 project I'm trying to transfer over. :D
Post Reply