Seite 1 von 1

Button in der Statusbar

Verfasst: 06.04.2007 14:25
von legion
Hallo !

Hab wieder mal ne Frage !
Ich möchte einen Button in der Statusbar.
Das ist mit "SetParent" zwar grundsätzlich kein Problem, aber wie bekomme ich das Event von diesem Button ?

Hab es auch schon mit einem Callback versucht, aber die einzige Message die ich abfangen kann ist "#WM_KILLFOCUS" !

Danke für eure Unterstützung !

Lg. Legion

Code: Alles auswählen

Enumeration
  #Window_0
EndEnumeration

Enumeration
  #StatusBar_0
  #Button_0
EndEnumeration

Procedure Open_Window_0()
  If OpenWindow(#Window_0, 299, 191, 433, 268, "Button in der Statusbar",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
    If CreateStatusBar(#StatusBar_0, WindowID(#Window_0))
      EndIf
      If CreateGadgetList(WindowID(#Window_0))
       ButtonGadget(#Button_0,1,4, 50, 15, "Close")
       SetParent_(GadgetID(#Button_0),StatusBarID(#StatusBar_0))       
      EndIf
    EndIf
EndProcedure

Open_Window_0()

Repeat
  
  Event = WaitWindowEvent()  
  WindowID = EventWindow()  
  GadgetID = EventGadget() 
  EventType = EventType()
  
  If Event = #PB_Event_Gadget
   If GadgetID = #Button_0 : Break
   EndIf   
  EndIf
  
Until Event = #PB_Event_CloseWindow

End

Verfasst: 06.04.2007 18:54
von ts-soft
Das Gadget-Ereignis wird ans nächste höhere Fenster geleitet, in diesem Fall
die Statusbar und nicht das Hauptfenster.
Hierfür gibts mehrere Lösungen, eine wäre das Subclassen der Statusbar,
hierfür benötigst Du den Code dieses Tipps von edel:
http://www.purebasic.fr/german/viewtopi ... t=subclass
Dein Code sieht dann aus, wie folgt:

Code: Alles auswählen

XIncludeFile "subclass.pbi"

Enumeration
  #Window_0
EndEnumeration

Enumeration
  #StatusBar_0
  #Button_0
EndEnumeration

Procedure SUBCLASSPROC(hwnd,uMsg,wParam,lParam,uId,dwData)
  
  If uId = #Button_0 And uMsg = #WM_COMMAND
    ProcedureReturn SendMessage_(GetParent_(hwnd),uMsg,wParam,lParam)
  EndIf
  
  ProcedureReturn DefSubclassProc(hwnd, uMsg , wParam, lParam)
EndProcedure


Procedure Open_Window_0()
  If OpenWindow(#Window_0, 299, 191, 433, 268, "Button in der Statusbar",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
    If CreateStatusBar(#StatusBar_0, WindowID(#Window_0))
      EndIf
      If CreateGadgetList(WindowID(#Window_0))
       ButtonGadget(#Button_0,1,4, 50, 15, "Close")
       SetParent_(GadgetID(#Button_0),StatusBarID(#StatusBar_0))       
      EndIf
    SetWindowSubclass(StatusBarID(#StatusBar_0),@SUBCLASSPROC(),#Button_0,0)
    EndIf
EndProcedure

Open_Window_0()

Repeat
 
  Event = WaitWindowEvent() 
  WindowID = EventWindow() 
  GadgetID = EventGadget()
  EventType = EventType()
 
  If Event = #PB_Event_Gadget
   If GadgetID = #Button_0 : Break
   EndIf   
  EndIf
 
Until Event = #PB_Event_CloseWindow

End 
Ich hoffe mal, damit kommste klar :wink:

PS: Die Statusbar ist kein Gadget, gehört also auch nicht in die
Enumeration, ist zwar nicht schlimm, klaut aber ein paar Bytes Speicher.

Verfasst: 06.04.2007 19:09
von Hugo
Es sollt gehen, wenn der Button in einem Container ist.

Code: Alles auswählen

Enumeration 1
  #Window_0 
EndEnumeration 

Enumeration 
  #StatusBar_0 
  #Container_0
  #Button_0 
EndEnumeration 

Procedure Open_Window_0() 
  If OpenWindow( #Window_0, 299, 191, 433, 268, "Button in der Statusbar",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar ) 
    If CreateStatusBar( #StatusBar_0, WindowID( #Window_0 ) ) 
      If CreateGadgetList( WindowID( #Window_0 ) ) 
        ContainerGadget( #Container_0, 0, 0, 50, 16, #PB_Container_BorderLess )
        ButtonGadget( #Button_0, 1, 4, 50, 16, "Close" ) 
        SetParent_( GadgetID( #Container_0 ), StatusBarID( #StatusBar_0 ) )        
      EndIf
    EndIf 
  EndIf 
EndProcedure 

Open_Window_0() 


Repeat 
  
  Event     = WaitWindowEvent()  
  WindowID  = EventWindow()  
  GadgetID  = EventGadget() 
   
  If Event = #PB_Event_Gadget 
    If GadgetID = #Button_0 : Break  :  EndIf    
  EndIf
  
Until Event = #PB_Event_CloseWindow 

End 
Gruß,
Hugo

Verfasst: 06.04.2007 20:16
von legion
Super Leute ! Ihr seit echte Profis !

Das mit den "Subclasses" ist sicher die professionelle Lösung, ist mir aber momentan noch eine Nummer zu groß.
Der Trick mit dem Container von Hugo ist genial, genau das richtige für
mich !

Danke für die tollen Tipps !

Lg. Legion

Verfasst: 06.04.2007 20:19
von ts-soft
Der Container funktioniert im endeffekt auf dieselbe Art, nur das PB die
Arbeit erledigt. Die Subclassing lösung ist auf Dauer flexibler, aber
Hauptsache es funktioniert :wink:

Verfasst: 06.04.2007 20:33
von legion
ts-soft hat geschrieben:Die Subclassing lösung ist auf Dauer flexibler
Da hast du vollkommen recht !
Habe aber schon zu meiner Delphi-Zeit einen Bogen um Subclassing gemacht, aber irgend wann werde ich mich auch damit beschäftigen
müssen. Neige leider immer dazu den einfacheren Weg zu gehen.

PureBasic macht auf alle Fälle Spaß und ihr in diesem Forum seit SPITZE !
Bin leider noch kein Profi im Programmieren, aber mit Hypnose könnte ich
euch helfen, Ha, Ha, Ha ... :lol:

Danke !

Lg. Legion

Verfasst: 07.04.2007 04:25
von PureLust
Da der Button in Hugos Beispiel bei meiner Systemkonfiguration etwas unschön aussah (schlecht platziert und beschnitten), hier nochmal eine etwas abgewandelte Version, bei der der Button ähnlich gut wie in ts-softs Beispiel dargestellt wird und sich auch automatisch der Höhe der Statuszeile anpasst:

Code: Alles auswählen

Enumeration 1 
  #Window_0 
EndEnumeration 

Enumeration 
  #StatusBar_0 
  #Container_0 
  #Button_0 
EndEnumeration 

Procedure Open_Window_0() 
  If OpenWindow( #Window_0, 299, 191, 433, 268, "Button in der Statusbar",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar ) 
    If CreateStatusBar( #StatusBar_0, WindowID( #Window_0 ) ) 
      If CreateGadgetList( WindowID( #Window_0 ) ) 
        ContainerGadget( #Container_0, 1, 3, 50, StatusBarHeight(#StatusBar_0)-3, #PB_Container_BorderLess ) 
        ButtonGadget( #Button_0, 0, 0, GadgetWidth(#Container_0), GadgetHeight(#Container_0), "Close" ) 
        SetParent_( GadgetID( #Container_0 ), StatusBarID( #StatusBar_0 ) )        
      EndIf 
    EndIf 
  EndIf 
EndProcedure 

Open_Window_0() 


Repeat 
  
  Event     = WaitWindowEvent()  
  WindowID  = EventWindow()  
  GadgetID  = EventGadget() 
    
  If Event = #PB_Event_Gadget 
    If GadgetID = #Button_0 : Break  :  EndIf    
  EndIf 
  
Until Event = #PB_Event_CloseWindow 

End
Ansonsten vielen Dank an Thomas & Hugo für die tollen Codebeispiele. :allright:
Greetz, PL.

Verfasst: 07.04.2007 05:44
von Fluid Byte
Warum eigentlich in einem Container? Raff ich nicht...

Code: Alles auswählen

OpenWindow(0,0,0,400,300,"untitled",#WS_OVERLAPPEDWINDOW | 1)
CreateGadgetList(WindowID(0))
ButtonGadget(0,0,0,100,25,"fuck off")
hwndStatusbar = CreateStatusBar(0,WindowID(0))
SetParent_(GadgetID(0),hwndStatusbar)

While WaitWindowEvent() ! 16 : Wend

Verfasst: 07.04.2007 06:00
von edel
Weil so WindowEvent nichts von dem Button mitbekommt. Steht aber
auch oben.

Verfasst: 07.04.2007 09:48
von legion
Hallo !

Der Trick mit dem Container funktioniert auch mit anderen Gadgets !
Hier ein Beispiel mit einem Panelgadget:

Code: Alles auswählen

Enumeration
  #Window_0
EndEnumeration

Enumeration
  #Panel_0
  #Container_0
  #Button_0
  #Button_1
  #Button_2
EndEnumeration

Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 353, 310, 512, 345, "Test-Window", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_MaximizeGadget)
    If CreateGadgetList(WindowID(#Window_0))
      PanelGadget(#Panel_0, 0, 0, 512, 345) 
         AddGadgetItem(#Panel_0, -1, "MyTap1")
         AddGadgetItem(#Panel_0, -1, "MyTap2")
         AddGadgetItem(#Panel_0, -1, "MyTap3")
         AddGadgetItem(#Panel_0, -1, "MyTap4")
      ContainerGadget(#Container_0,350,1,170,19,#PB_Container_BorderLess)
        ButtonGadget(#Button_0,0,0,50,18,"Close")
        ButtonGadget(#Button_1,55,0,50,18,"Close")
        ButtonGadget(#Button_2,110,0,50, 18,"Close")
      SetParent_(GadgetID(#Container_0),GadgetID(#Panel_0))             
      CloseGadgetList()
        PureRESIZE_SetGadgetResize(#Panel_0, 1, 1, 1, 1)
        PureRESIZE_SetGadgetResize(#Container_0, 1, 1, 1, 0)
        PureRESIZE_SetGadgetResize(#Button_0, 0, 1, 1, 0)
        PureRESIZE_SetGadgetResize(#Button_1, 0, 1, 1, 0)
        PureRESIZE_SetGadgetResize(#Button_2, 0, 1, 1, 0)
    EndIf
  EndIf
EndProcedure

OpenWindow_Window_0()

Repeat
 
  Event     = WaitWindowEvent() 
  WindowID  = EventWindow() 
  GadgetID  = EventGadget()

    If Event = #PB_Event_Gadget
      If GadgetID = #Panel_0
      ElseIf  GadgetID = #Button_0 : Break
      ElseIf  GadgetID = #Button_1 : Break
      ElseIf  GadgetID = #Button_2 : Break
      EndIf
    EndIf

Until Event = #PB_Event_CloseWindow
Ohne Container gab es auch hier keine Eventrückmeldung !

Lg. Legion