Page 1 of 1

Block RightMouse Click on Stringagdget.

Posted: Sat Dec 07, 2024 12:28 am
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

Re: Block RightMouse Click on Stringagdget.

Posted: Sat Dec 07, 2024 2:45 am
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.

Re: Block RightMouse Click on Stringagdget.

Posted: Sat Dec 07, 2024 2:52 am
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.

Re: Block RightMouse Click on Stringagdget.

Posted: Sat Dec 07, 2024 3:46 am
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. ;)

Re: Block RightMouse Click on Stringagdget.

Posted: Sat Dec 07, 2024 4:40 am
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.

Re: Block RightMouse Click on Stringagdget.

Posted: Sat Dec 07, 2024 12:14 pm
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

Re: Block RightMouse Click on Stringagdget.

Posted: Sun Jan 05, 2025 8:19 am
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.

Re: Block RightMouse Click on Stringagdget.

Posted: Sun Jan 05, 2025 10:55 am
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

Re: Block RightMouse Click on Stringagdget.

Posted: Mon Jan 13, 2025 10:35 pm
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