DetectStatusBar Events

Share your advanced PureBasic knowledge/code with the community.
QuimV
Enthusiast
Enthusiast
Posts: 337
Joined: Mon May 29, 2006 11:29 am
Location: BARCELONA - SPAIN

DetectStatusBar Events

Post by QuimV »

Code updated For 5.20+

Hello,

Could anybody help me in order to detect the StatusBar events?

Here it is an example from fsw, but if we add a TreeGadget, the detection goes wrong.

Code: Select all

; Example Of A Statusbar Click Event
; (c) 2003 - By FSW
;
; Tested under WinXP
; do whatever you want with it
;
#Window = 10
#StatusbarFocus = 528
#StatusBar = 1
#Tree = 2

Procedure  LoWord (var)
  ProcedureReturn var & $FFFF
EndProcedure


Procedure MyWindowCallback(WindowID, Message, wParam, lParam)
  Result = #PB_ProcessPureBasicEvents
  
  wParamLo = LoWord(wParam)
  lParamLo = LoWord(lParam)
  
  ;513 = $201
  
  If Message = #StatusbarFocus ;#StatusbarFocus  ;528 = $210 = #WM_PARENTNOTIFY
    If wParamLo = #WM_LBUTTONDOWN And lParamLo < 270 ; 270 is the width of field 1
      MessageRequester("Message", "Left Mouse Click In StatusBar Field 1. "+"MousePos: "+Str(lParamLo))
    ElseIf wParamLo = 513 And lParamLo > 270 + 2 ; there is a BAR between the 2 fields...
      MessageRequester("Message", "Left Mouse Click In StatusBar Field 2. "+"MousePos: "+Str(lParamLo))
    ElseIf wParamLo = 516
      MessageRequester("Message", "Right Mouse Click In StatusBar. "+"MousePos: "+Str(lParamLo))
    EndIf
    
  EndIf
  
  ProcedureReturn Result
EndProcedure


If OpenWindow(#Window,0,0,355,180,"Statusbar Click",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  
  CreateStatusBar(#StatusBar, WindowID(#Window))
  AddStatusBarField(90)
  
  StatusBarText(#StatusBar, 0, "Hello World!")
  AddStatusBarField(270)
  AddStatusBarField(80)
  
  TreeGadget(#Tree,10,45,100,100,#PB_Tree_AlwaysShowSelection)
  SendMessage_(GadgetID(#Tree),$111D,0,14675967)
  
  
  SetWindowCallback(@MyWindowCallback())
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  
EndIf


Thanks in advanced.

QuimV
QuimV
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Looks like a message is getting processed as a statusbar click that shouldn't be. Other childwindows can generate #wm_parentnotify messages. You can always add a quick check to make sure the active child window is the status bar:

Code: Select all

; Example Of A Statusbar Click Event 
; (c) 2003 - By FSW 
; 
; Tested under WinXP 
; do whatever you want with it 
; 
#Window = 10 
#StatusbarFocus = 528 
#StatusBar = 1 
#Tree = 2 

Global Statusbar

Procedure.l  LoWord (var.l) 
  ProcedureReturn var & $FFFF 
EndProcedure 

Procedure MyWindowCallback(WindowID, Message, wParam, lParam) 
  Result = #PB_ProcessPureBasicEvents 

  wParamLo = LoWord(wParam) 
  lParamLo = LoWord(lParam) 

  ;513 = $201 

    If Message = #StatusbarFocus ;#StatusbarFocus  ;528 = $210 = #WM_PARENTNOTIFY 
      If ChildWindowFromPoint_(WindowID(#Window),WindowMouseX(#Window),WindowMouseY(#Window)) = Statusbar
        If wParamLo = #WM_LBUTTONDOWN And lParamLo < 270 ; 270 is the width of field 1 
          MessageRequester("Message", "Left Mouse Click In StatusBar Field 1. "+"MousePos: "+Str(lParamLo)) 
        ElseIf wParamLo = 513 And lParamLo > 270 + 2 ; there is a BAR between the 2 fields... 
          MessageRequester("Message", "Left Mouse Click In StatusBar Field 2. "+"MousePos: "+Str(lParamLo)) 
        ElseIf wParamLo = 516 
          MessageRequester("Message", "Right Mouse Click In StatusBar. "+"MousePos: "+Str(lParamLo)) 
        EndIf 
      EndIf 
    EndIf
  
  ProcedureReturn Result 
EndProcedure 

If OpenWindow(#Window,0,0,355,180,"Statusbar Click",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
  If CreateGadgetList(WindowID(#Window))    
   Statusbar = CreateStatusBar(#StatusBar, WindowID(#Window)) 
    StatusBarText(#StatusBar, 0, "Hello World!") 
      AddStatusBarField(270) 
      AddStatusBarField(80) 
      
    TreeGadget(#Tree,10,45,100,100,#PB_Tree_AlwaysShowSelection) 
      SendMessage_(GadgetID(#Tree),$111D,0,14675967) 
  EndIf    
    
  SetWindowCallback(@MyWindowCallback()) 
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 
    
EndIf 
A global var and ChildWindowFromPoint seems the most efficient solution as #WM_PARENTNOTIFY messages don't carry the childwindow identifier with them for buttondown events.

A somewhat cleaner solution imho would be to subclass the statusbar and then its callback is only catching events for it and there's no need to test for the right childwindow. I have to go out right now for a couple hours but I can post code for that if nobody beats me to it in the meantime.
BERESHEIT
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Here is the subclassed version, I think it's much cleaner this way:

Code: Select all

#Window = 10 
#StatusBar = 1 
#Tree = 2 

Global OldStatusBar

Procedure.l  LoWord (var.l) 
  ProcedureReturn var & $FFFF 
EndProcedure 

Procedure SubClassedStatusBar(hwnd, msg, wParam, lParam) 
  result = CallWindowProc_(OldStatusBar, hwnd, msg, wparam, lparam) 
  lParamLo = LoWord(lParam) 
  Select msg 
    Case #WM_LBUTTONDOWN 
      If lParamLo < 270 ; 270 is the width of field 1 
        MessageRequester("Message", "Left Mouse Click In StatusBar Field 1. "+"MousePos: "+Str(lParamLo)) 
      ElseIf lParamLo > 270 + 2 ; there is a BAR between the 2 fields... 
        MessageRequester("Message", "Left Mouse Click In StatusBar Field 2. "+"MousePos: "+Str(lParamLo)) 
      EndIf
    Case #WM_RBUTTONDOWN
      MessageRequester("Message", "Right Mouse Click In StatusBar. "+"MousePos: "+Str(lParamLo)) 
  EndSelect
  ProcedureReturn Result 
EndProcedure 

If OpenWindow(#Window,0,0,355,180,"Statusbar Click",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
  If CreateGadgetList(WindowID(#Window))    
    StatusBar = CreateStatusBar(#StatusBar, WindowID(#Window)) 
    StatusBarText(#StatusBar, 0, "Hello World!") 
      AddStatusBarField(270) 
      AddStatusBarField(80) 
    TreeGadget(#Tree,10,45,100,100,#PB_Tree_AlwaysShowSelection) 
    SendMessage_(GadgetID(#Tree),$111D,0,14675967) 
  EndIf    
    
  OldStatusBar = SetWindowLong_(StatusBar, #GWL_WNDPROC, @SubclassedStatusBar()) 
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 
    
EndIf 
BERESHEIT
Post Reply