Page 1 of 2
Detecting a mouseclick inside a ScrollAreaGadget()
Posted: Wed Dec 19, 2007 11:25 am
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!
Re: Detecting a mouseclick inside a ScrollAreaGadget()
Posted: Wed Dec 19, 2007 12:41 pm
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.
Posted: Wed Dec 19, 2007 1:52 pm
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

[/edit]
Posted: Wed Dec 19, 2007 2:10 pm
by srod
You're welcome.
Posted: Wed Dec 19, 2007 2:18 pm
by Dare
Nice code, nice insight. Thanks!
Posted: Wed Dec 19, 2007 2:27 pm
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!

Posted: Thu Dec 20, 2007 12:39 pm
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?
Posted: Thu Dec 20, 2007 12:58 pm
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
Posted: Thu Dec 20, 2007 1:00 pm
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!

Posted: Thu Dec 20, 2007 1:05 pm
by gnozal
srod wrote:**EDIT : too slow for 'quick draw' Gnozal!

No, I am too slow, just modified my post !
Posted: Thu Dec 20, 2007 1:13 pm
by srod
Ah, nice one; forgot about that!

Posted: Thu Dec 20, 2007 1:58 pm
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?
Posted: Thu Dec 20, 2007 2:23 pm
by srod
Doh, I just wrote a massive and detailed reply... and lost it!
B**lox!
Posted: Thu Dec 20, 2007 2:37 pm
by Dare
srod wrote:Doh, I just wrote a massive and detailed reply... and lost it!
B**lox!
* Takes careful aim. Eases finger on trigger. FIRES! *
Now it's B**lock, singular.
Posted: Thu Dec 20, 2007 2:40 pm
by srod
Rewriting...