Detecting a mouseclick inside a ScrollAreaGadget()

Everything else that doesn't fall into one of the other PB categories.
merendo
Enthusiast
Enthusiast
Posts: 449
Joined: Sat Apr 26, 2003 7:24 pm
Location: Germany
Contact:

Detecting a mouseclick inside a ScrollAreaGadget()

Post by merendo »

Hello everyone,

in my app, I have a large ScrollAreaGadget, and need to detect when the user clicks the mouse inside it (LMB and RMB also need to be distinguished).

Since normal Window-Events won't help me out, could someone give me an example of doing sth. like this with API functions?

Thanks a lot!
The truth is never confined to a single number - especially scientific truth!
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Detecting a mouseclick inside a ScrollAreaGadget()

Post by srod »

merendo wrote:...could someone give me an example of doing sth. like this with API functions?
Aye, no problem! :)

Code: Select all

Global gOldPRoc

Procedure.l panelProc(hWnd, uMsg, wParam, lParam)
  Protected result = CallWindowProc_(gOldProc, hWnd, uMsg, wParam, lParam)

  Select uMsg
    Case #WM_LBUTTONDOWN
      Debug "Left button down!"
    Case #WM_RBUTTONDOWN
      Debug "Right button down!"
  EndSelect

  ProcedureReturn result
EndProcedure



If OpenWindow(0, 0, 0, 305, 140, "ScrollAreaGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
    ScrollAreaGadget(0, 10, 10, 290,120, 375, 155, 30)
      ButtonGadget  (1, 10, 10, 230, 30,"Button 1")
      ButtonGadget  (2, 50, 50, 230, 30,"Button 2")
      ButtonGadget  (3, 90, 90, 230, 30,"Button 3")
      TextGadget    (4,130,130, 230, 20,"This is the content of a ScrollAreaGadget!",#PB_Text_Right)
    CloseGadgetList() 

    ;Grab the handle of the 'inner area' of the scroll area.
      phWnd = FindWindowEx_(GadgetID(0), 0, "PureScrollAreaChild",0)
    ;Subclass the panel.
      gOldProc = SetWindowLong_(phWnd, #GWL_WNDPROC, @panelProc())

    Repeat 
      Select WaitWindowEvent() 
        Case  #PB_Event_CloseWindow 
          End 
        Case  #PB_Event_Gadget 
          Select EventGadget()
          EndSelect
      EndSelect 
    ForEver 
  EndIf
Note, if you require to trap double-clicks then you will need to set the #CS_DBLCLKS class style of the 'inner panel' first.
I may look like a mule, but I'm not a complete ass.
merendo
Enthusiast
Enthusiast
Posts: 449
Joined: Sat Apr 26, 2003 7:24 pm
Location: Germany
Contact:

Post by merendo »

Very good, I think this is what I've been looking for. Thanks a lot!

[edit]Just implemented it into my code, and it works fine. You've saved my life 8)[/edit]
The truth is never confined to a single number - especially scientific truth!
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

You're welcome.
I may look like a mule, but I'm not a complete ass.
Dare
Addict
Addict
Posts: 1965
Joined: Mon May 29, 2006 1:01 am
Location: Outback

Post by Dare »

Nice code, nice insight. Thanks!
Dare2 cut down to size
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

No probs.

With scroll-areas I generally always subclass the 'inner panel' as shown above, usually to combat a lot of the flicker you can get with these beasties by performing all erasing myself etc.

It is one of the most flexible gadgets in the PB gadget library, but does occasionally require beating with a big stick in order to get it to behave as required! :)
I may look like a mule, but I'm not a complete ass.
merendo
Enthusiast
Enthusiast
Posts: 449
Joined: Sat Apr 26, 2003 7:24 pm
Location: Germany
Contact:

Post by merendo »

One issue: The function doesn't seem to detect mouseclicks that are inside the ScrollAreaGadget if there is an ImageGadget below it. I've seen it work with TextGadgets though, is there a way to get the function to recognize clicks on an ImageGadget inside the ScrollAreaGadget?
The truth is never confined to a single number - especially scientific truth!
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

merendo wrote:I've seen it work with TextGadgets though, is there a way to get the function to recognize clicks on an ImageGadget inside the ScrollAreaGadget?

Subclass image

Code: Select all

Global gOldPRoc, fOldPRoc

Procedure.l panelProc(hwnd, uMsg, wParam, lParam) 
  Protected result = CallWindowProc_(gOldPRoc, hwnd, uMsg, wParam, lParam) 
  Select uMsg 
    Case #WM_LBUTTONDOWN 
      Debug "Left button down!" 
    Case #WM_RBUTTONDOWN 
      Debug "Right button down!" 
  EndSelect 
  
  ProcedureReturn result 
EndProcedure 

Procedure.l imageProc(hwnd, uMsg, wParam, lParam) 
  Protected result = CallWindowProc_(fOldPRoc, hwnd, uMsg, wParam, lParam) 
  
  Select uMsg 
    Case #WM_LBUTTONDOWN 
      Debug "Left button down!" 
    Case #WM_RBUTTONDOWN 
      Debug "Right button down!" 
  EndSelect 
  
  ProcedureReturn result 
EndProcedure 



If OpenWindow(0, 0, 0, 305, 140, "ScrollAreaGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  ScrollAreaGadget(0, 10, 10, 290,120, 375, 155, 30) 
  ButtonGadget  (1, 10, 10, 230, 30,"Button 1") 
  ImageGadget  (2, 50, 50, 230, 30, LoadImage(0, #PB_Compiler_Home + "Examples\Sources\Data\AlphaChannel.bmp"))
  TextGadget    (4,130,150, 230, 20,"This is the content of a ScrollAreaGadget!",#PB_Text_Right) 
  CloseGadgetList() 
  
  ;Grab the handle of the 'inner area' of the scroll area. 
  phWnd = FindWindowEx_(GadgetID(0), 0, "PureScrollAreaChild",0) 
  ;Subclass the panel. 
  gOldPRoc = SetWindowLong_(phWnd, #GWL_WNDPROC, @panelProc()) 
  ; subclass image
  fOldPRoc = SetWindowLong_(GadgetID(2), #GWL_WNDPROC, @imageProc()) 
  
  Repeat 
    Select WaitWindowEvent() 
      Case  #PB_Event_CloseWindow 
        End 
      Case  #PB_Event_Gadget 
        Select EventGadget() 
        EndSelect 
    EndSelect 
  ForEver 
EndIf
Use parentNotify

Code: Select all

Global gOldPRoc

Procedure.l panelProc(hwnd, uMsg, wParam, lParam) 
  Protected result = CallWindowProc_(gOldPRoc, hwnd, uMsg, wParam, lParam) 
  
  Select uMsg 
    Case #WM_PARENTNOTIFY 
      fwEvent = wParam & $FFFF
      Select fwEvent
        Case #WM_LBUTTONDOWN 
          Debug "Left button down!" 
        Case #WM_RBUTTONDOWN 
          Debug "Right button down!" 
      EndSelect
    Case #WM_LBUTTONDOWN 
      Debug "Left button down!" 
    Case #WM_RBUTTONDOWN 
      Debug "Right button down!" 
  EndSelect 
  
  ProcedureReturn result 
EndProcedure 

If OpenWindow(0, 0, 0, 305, 140, "ScrollAreaGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  ScrollAreaGadget(0, 10, 10, 290,120, 375, 155, 30) 
  ButtonGadget  (1, 10, 10, 230, 30,"Button 1") 
  ImageGadget  (2, 50, 50, 230, 30, LoadImage(0, #PB_Compiler_Home + "Examples\Sources\Data\AlphaChannel.bmp"))
  TextGadget    (4,130,150, 230, 20,"This is the content of a ScrollAreaGadget!",#PB_Text_Right) 
  CloseGadgetList() 
  
  ;Grab the handle of the 'inner area' of the scroll area. 
  phWnd = FindWindowEx_(GadgetID(0), 0, "PureScrollAreaChild",0) 
  ;Subclass the panel. 
  gOldPRoc = SetWindowLong_(phWnd, #GWL_WNDPROC, @panelProc()) 
  
  Repeat 
    Select WaitWindowEvent() 
      Case  #PB_Event_CloseWindow 
        End 
      Case  #PB_Event_Gadget 
        Select EventGadget() 
        EndSelect 
    EndSelect 
  ForEver 
EndIf
Last edited by gnozal on Thu Dec 20, 2007 1:12 pm, edited 2 times in total.
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I'm not sure what you're after. If you wish to detect a mouse click on an image gadget then it depends where you wish to pick up on this?

If you wish to pick up on it in a Purebasic event loop then you must remove the #SS_NOTIFY style as in the following :

Code: Select all

If OpenWindow(0, 0, 0, 245, 105, "ImageGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
    If LoadImage(0, "bm1.bmp")    ; change 2nd parameter to the path/filename of your image
      ImageGadget(0,  10, 10, 100, 83, ImageID(0))                      ; imagegadget standard
    EndIf
    ;Remove the #SS_NOTIFY style.
      SetWindowLong_(GadgetID(0), #GWL_STYLE, GetWindowLong_(GadgetID(0), #GWL_STYLE)&~#SS_NOTIFY)
    Repeat
      event = WaitWindowEvent()
      Select event
        Case #WM_LBUTTONDOWN
          Debug "Left - click!"
      EndSelect    
    Until event = #PB_Event_CloseWindow
  EndIf
From here you will need to do some hit-testing to determine which gadget the mouse is over etc.

Alternatively you'll have to subclass the image gadget in a similar way to the scrollarea inner panel etc.


**EDIT : too slow for 'quick draw' Gnozal! :)
I may look like a mule, but I'm not a complete ass.
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

srod wrote:**EDIT : too slow for 'quick draw' Gnozal! :)
No, I am too slow, just modified my post !
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Ah, nice one; forgot about that! :)
I may look like a mule, but I'm not a complete ass.
Dare
Addict
Addict
Posts: 1965
Joined: Mon May 29, 2006 1:01 am
Location: Outback

Post by Dare »

Apologies, merendo, that I keep butting in here.

Guys, if it doesn't require too much of your time and involve your having to write a book - what exactly does CallWindowProc do? I have read the SDK help and still don't follow. So in

Code: Select all

Procedure.l panelProc(hwnd, uMsg, wParam, lParam)
  Protected result = CallWindowProc_(gOldPRoc, hwnd, uMsg, wParam, lParam)
we advise CallWindowProc about panelProc (via gOldProc) - to do what?

Does it backtrack along some list to get to the point where it notifies big momma? And in this case is big momma the purebasic message handling? And if so, why does it bother/need to do that?
Dare2 cut down to size
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Doh, I just wrote a massive and detailed reply... and lost it!

B**lox!
I may look like a mule, but I'm not a complete ass.
Dare
Addict
Addict
Posts: 1965
Joined: Mon May 29, 2006 1:01 am
Location: Outback

Post by Dare »

srod wrote:Doh, I just wrote a massive and detailed reply... and lost it!

B**lox!
:D

* Takes careful aim. Eases finger on trigger. FIRES! *

Now it's B**lock, singular.
Dare2 cut down to size
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Rewriting...
I may look like a mule, but I'm not a complete ass.
Post Reply