Button in der Statusbar

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
legion
Beiträge: 467
Registriert: 08.10.2006 18:04
Computerausstattung: Intel Core i5-6500 @ 4x 3.6GHz mit Windows 10 Pro, Intel Core-i7 mit Ubuntu 18.04 bionic, x86_64 Linux 4.18.0-16-generic, Microsoft Surface Pro - Windows 10 Pro
Wohnort: Wien
Kontaktdaten:

Button in der Statusbar

Beitrag 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
PB 5.71 LTS Windows 10 Pro & Ubuntu 18.04.2 LTS & Linux Mint 19.3
-----------------------------------------------------
Alles ist, wie man glaubt, dass es ist!
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Hugo
Beiträge: 56
Registriert: 30.03.2005 12:07
Wohnort: Nähe München

Beitrag 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
Benutzeravatar
legion
Beiträge: 467
Registriert: 08.10.2006 18:04
Computerausstattung: Intel Core i5-6500 @ 4x 3.6GHz mit Windows 10 Pro, Intel Core-i7 mit Ubuntu 18.04 bionic, x86_64 Linux 4.18.0-16-generic, Microsoft Surface Pro - Windows 10 Pro
Wohnort: Wien
Kontaktdaten:

Beitrag 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
PB 5.71 LTS Windows 10 Pro & Ubuntu 18.04.2 LTS & Linux Mint 19.3
-----------------------------------------------------
Alles ist, wie man glaubt, dass es ist!
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
legion
Beiträge: 467
Registriert: 08.10.2006 18:04
Computerausstattung: Intel Core i5-6500 @ 4x 3.6GHz mit Windows 10 Pro, Intel Core-i7 mit Ubuntu 18.04 bionic, x86_64 Linux 4.18.0-16-generic, Microsoft Surface Pro - Windows 10 Pro
Wohnort: Wien
Kontaktdaten:

Beitrag 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
PB 5.71 LTS Windows 10 Pro & Ubuntu 18.04.2 LTS & Linux Mint 19.3
-----------------------------------------------------
Alles ist, wie man glaubt, dass es ist!
Benutzeravatar
PureLust
Beiträge: 1145
Registriert: 21.07.2005 00:02
Computerausstattung: Hab aktuell im Grunde nur noch 'nen Lenovo Yoga 2 Pro im Einsatz.
Wohnort: am schönen Niederrhein

Beitrag 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.
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag 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
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Weil so WindowEvent nichts von dem Button mitbekommt. Steht aber
auch oben.
Benutzeravatar
legion
Beiträge: 467
Registriert: 08.10.2006 18:04
Computerausstattung: Intel Core i5-6500 @ 4x 3.6GHz mit Windows 10 Pro, Intel Core-i7 mit Ubuntu 18.04 bionic, x86_64 Linux 4.18.0-16-generic, Microsoft Surface Pro - Windows 10 Pro
Wohnort: Wien
Kontaktdaten:

Beitrag 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
PB 5.71 LTS Windows 10 Pro & Ubuntu 18.04.2 LTS & Linux Mint 19.3
-----------------------------------------------------
Alles ist, wie man glaubt, dass es ist!
Antworten