Erstellen eines Date-Requesters

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Erstellen eines Date-Requesters

Beitrag von Kurzer »

Hall ozusammen,
ich hab grad mal wieder "Schaltschwierigkeiten".

Ich möchte mir einen Datums-Auswahlrequester bauen, der aus einem kleinen Fenster, einem Datumsgadget und einem OK Button besteht.

Code: Alles auswählen

  If OpenWindow(#Window_Input, 100, 100, 150, 40, "Eingabe",  #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_WindowCentered )
    If CreateGadgetList(WindowID(#Window_Input))
      DateGadget(#Date_Input, 10, 10, 90, 20, "%mm/%dd/%yyyy", Date())
      ButtonGadget(#Button_Input_Ok, 110, 10, 30, 20, "OK")
    EndIf
  EndIf
Nun hat mein eigentliches Programm, in dem ich diesen Requester brauche, schon einen recht heftigen Eventloop.

Wie realisiere ich so einen selbstgebauten Requester, ohne daß ich die Eventabfrage in meinen großen Eventloop einflechten muß?
OpenWindow, CloseWindow Proceduren kann ich ja unterbringen, aber um den OK Button abzufragen, muß ich auf die Events reagieren.

Eigentlich schwebt mir ein modaler Dialog vor ala:
Datum = EigenerDatumsRequester (x, y, breite, hoehe, Defaultdatum)

Aber wie mache ich das mit dem Eventloop ohne meinen Haupteventloop nutzen zu müssen.
Ich hätte alles, was zu dem EingabeRequester gehört gern irgendwo gekapselt (eigenes Include oder so...).

Markus
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

Okay, sorry... Blick ins Codearchiv hat geholfen...

(Blöd, wenn man unter Zeitdruck was machen muß und an einer Stelle plötzlich nicht weiterkommt... da kommt dann nen bisserl Panik auf)

Markus
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
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 »

Jetzt wo ich mich mit Beispiel abgequält habe :cry:
Mußte trotzdem gucken :wink:

Code: Alles auswählen

Procedure DateRequester(MainID.l)
  Protected win.l, date.l, btn.l, result.l
  win = OpenWindow(#PB_Any, 100, 100, 150, 40, "Eingabe",  #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_WindowCentered , WindowID(MainID))
  If win And CreateGadgetList(WindowID(win))
    date = DateGadget(#PB_Any, 10, 10, 90, 20, "%mm/%dd/%yyyy", Date())
    btn = ButtonGadget(#PB_Any, 110, 10, 30, 20, "OK")
    
    DisableWindow(MainID, #True)
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          If EventWindow() = win
            Break
          EndIf
        Case #PB_Event_Gadget
          If EventGadget() = btn
            Break
          EndIf
      EndSelect
    ForEver
    result = GetGadgetState(date)
    CloseWindow(win)
    DisableWindow(MainID, #False)
    ProcedureReturn result
  EndIf
EndProcedure

If OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "Main")
  Debug DateRequester(0)
EndIf 
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
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

Man bist Du fix. :allright: Danke!

Soll auch nicht vergeblich gewesen sein, daher werde ich Dein Beispiel als Vorlage nutzen. ;)
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

@ts
ich würde das aber ggf durch nen cancel button ergänzen.
auch beim schließen über CloseWindow sollte der wert im date-gadget nicht übernommen werden...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr 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 »

Kaeru Gaman hat geschrieben:@ts
ich würde das aber ggf durch nen cancel button ergänzen.
auch beim schließen über CloseWindow sollte der wert im date-gadget nicht übernommen werden...
Bissel kann er auch selber korrigieren :mrgreen: , hab ja nur seine Styles
übernommen, besser wäre es so:

Code: Alles auswählen

Procedure DateRequester(MainID.l)
  Protected win.l, date.l, btn.l, result.l

  win = OpenWindow(#PB_Any, 100, 100, 150, 40, "Eingabe",  #PB_Window_SystemMenu | #PB_Window_WindowCentered , WindowID(MainID))

  If win And CreateGadgetList(WindowID(win))

    SetWindowLong_(WindowID(win), #GWL_EXSTYLE, GetWindowLong_(WindowID(win), #GWL_EXSTYLE) | #WS_EX_TOOLWINDOW)
    SetWindowPos_(WindowID(win), 0, 0, 0, 0, 0, #SWP_FRAMECHANGED | #SWP_NOMOVE | #SWP_NOSIZE)

    AddKeyboardShortcut(win, #PB_Shortcut_Escape, 100)

    date = DateGadget(#PB_Any, 10, 10, 90, 20, "%mm/%dd/%yyyy", Date())
    btn = ButtonGadget(#PB_Any, 110, 10, 30, 20, "OK")

    DisableWindow(MainID, #True)

    Repeat

      Select WaitWindowEvent()

        Case #PB_Event_CloseWindow
          If EventWindow() = win
            CloseWindow(win)
            DisableWindow(MainID, #False)
            ProcedureReturn #False
          EndIf
        Case #PB_Event_Menu
          If EventMenu() = 100
            CloseWindow(win)
            DisableWindow(MainID, #False)
            ProcedureReturn #False
          EndIf
        Case #PB_Event_Gadget
          If EventGadget() = btn
            result = GetGadgetState(date)
            CloseWindow(win)
            DisableWindow(MainID, #False)
            ProcedureReturn result
          EndIf

      EndSelect

    ForEver

  EndIf
EndProcedure

If OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "Main")
  Debug DateRequester(0)
EndIf
Wobei ich es auch nicht window-centered machen würde
Zuletzt geändert von ts-soft am 27.06.2007 14:03, insgesamt 1-mal geändert.
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
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

Anpassungen machen ist klar... ich brauchte nur einen Wink in die richtige Richtung.

Ich setze den Requester jetzt so ein:

Code: Alles auswählen

Procedure.l InputDate(CallerWindowID.l, X.l, Y.l, Title$, DefaultDate.l)
  Protected Window.l, Date.l, Button.l, Result.l, Ok.b = #False
  
  Window = OpenWindow(#PB_Any, X, Y, 150, 40, Title$,  #PB_Window_SystemMenu | #PB_Window_TitleBar, WindowID(CallerWindowID))

  If Window And CreateGadgetList(WindowID(Window))
    Date = DateGadget(#PB_Any, 10, 10, 90, 20, "%mm/%dd/%yyyy", DefaultDate)
    Button = ButtonGadget(#PB_Any, 110, 10, 30, 20, "OK")
   
    DisableWindow(CallerWindowID, #True)

    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          If EventWindow() = Window : Break : EndIf
        Case #PB_Event_Gadget 
          If EventGadget() = Button : Ok = #True : Break : EndIf
      EndSelect
    ForEver
    
    Result = GetGadgetState(Date)
    CloseWindow(Window)
    DisableWindow(CallerWindowID, #False)
    If Ok = #True : ProcedureReturn Result : EndIf
  EndIf

EndProcedure
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

/:-> Noch'n Gedicht:

Warum gibt es in dieser Version des DatumsrRequesters Probleme mit der Abfrage, wenn zuvor im DateGadget die Cursortasten benutzt worden sind...

Code: Alles auswählen

Procedure.l InputDate(CallerWindowID.l, CallerItemID.l, X.l, Y.l, Title$, DefaultDate.l)
  Protected Event.l, EventwParam.l, EventWindow.l, EventGadget.l, Window.l, Date.l, Button.l, Result.l = -1
  
  Window = OpenWindow(#PB_Any, X, Y, 150, 40, Title$,  #PB_Window_SystemMenu | #PB_Window_TitleBar, WindowID(CallerWindowID))

  If Window And CreateGadgetList(WindowID(Window))
    Date = DateGadget(#PB_Any, 10, 10, 90, 20, "%mm/%dd/%yyyy", DefaultDate)
    Button = ButtonGadget(#PB_Any, 110, 10, 30, 20, "OK")
   
    DisableWindow(CallerWindowID, #True)
    SetActiveGadget(Date)

    Repeat
      Event       = WaitWindowEvent()
      EventWindow = EventWindow()
      EventwParam = EventwParam()
      EventGadget = EventGadget()

      If EventWindow = Window                  ; ############################
        Select Event
          Case #PB_Event_CloseWindow
            Result = 0
          Case #WM_KEYUP
            If EventwParam = #VK_ESCAPE : Result = 0 : EndIf
            If EventwParam = #VK_RETURN : Result = GetGadgetState(Date) : EndIf
            Debug EventwParam
          Case #PB_Event_Gadget
            If EventGadget = Button : Result = GetGadgetState(Date) : EndIf
        EndSelect
      EndIf                                    ; ############################
    Until Result > -1
    
    CloseWindow(Window)
    DisableWindow(CallerWindowID, #False)
    SetActiveGadget(CallerItemID)

    ProcedureReturn Result
  EndIf

EndProcedure
... und in dieser Version nicht?

Code: Alles auswählen

Procedure.l InputDate(CallerWindowID.l, CallerItemID.l, X.l, Y.l, Title$, DefaultDate.l)
  Protected Event.l, EventwParam.l, EventWindow.l, EventGadget.l, Window.l, Date.l, Button.l, Result.l = -1
  
  Window = OpenWindow(#PB_Any, X, Y, 150, 40, Title$,  #PB_Window_SystemMenu | #PB_Window_TitleBar, WindowID(CallerWindowID))

  If Window And CreateGadgetList(WindowID(Window))
    Date = DateGadget(#PB_Any, 10, 10, 90, 20, "%mm/%dd/%yyyy", DefaultDate)
    Button = ButtonGadget(#PB_Any, 110, 10, 30, 20, "OK")
   
    DisableWindow(CallerWindowID, #True)
    SetActiveGadget(Date)

    Repeat
      Event       = WaitWindowEvent()
      EventWindow = EventWindow()
      EventwParam = EventwParam()
      EventGadget = EventGadget()

      Select Event
        Case #PB_Event_CloseWindow
          If EventWindow = Window : Result = 0 : EndIf        ; ##########################
        Case #WM_KEYUP
          If EventwParam = #VK_ESCAPE : Result = 0 : EndIf
          If EventwParam = #VK_RETURN : Result = GetGadgetState(Date) : EndIf
          Debug EventwParam
        Case #PB_Event_Gadget
          If EventGadget = Button : Result = GetGadgetState(Date) : EndIf
      EndSelect
    Until Result > -1
    
    CloseWindow(Window)
    DisableWindow(CallerWindowID, #False)
    SetActiveGadget(CallerItemID)

    ProcedureReturn Result
  EndIf

EndProcedure
Die Unterschiede sind mit # markiert.

In der ersten Version (mit dem "WindowID-If" drumherum) reagieren ESC und RETURN nicht mehr, wenn ich mittels Cursor im DatumsGadget rumgekurft bin.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
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 »

Du solltest besser immer das Fenster unterscheiden, auch wenn das andere
deaktiviert ist, ich weiß nicht ob alle API events deaktiviert sind.

Also immer erst prüfen, ob Dein Requester gemeint ist, auch für alle #WM_
ereignisse.

Ausserdem solltest Du shortcuts nehmen für Escape und Return. Für Escape
ist es in meinem Beispiel schon eingebaut.
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
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

ts-soft hat geschrieben:Du solltest besser immer das Fenster unterscheiden, auch wenn das andere
deaktiviert ist, ich weiß nicht ob alle API events deaktiviert sind.

Also immer erst prüfen, ob Dein Requester gemeint ist, auch für alle #WM_
ereignisse.
Witzigerweise gibts die Probleme ja in der Version, die nur die Events des Requesters-Fensters abfragt:

If EventWindow = Window
... Eventbearbeitung
EndIf

Aber evtl. relativiert sich das bei der Benutzung von Shortcuts.

edit: [kurze Zeit später...] Supi, so gehts jetzt einwandfrei!

Code: Alles auswählen

Procedure.l InputDate(CallerWindowID.l, CallerItemID.l, X.l, Y.l, Title$, DefaultDate.l)
  Protected Event.l, EventWindow.l, EventGadget.l, EventMenu.l, Window.l, Date.l, Button.l, Result.l = -1
  
  Window = OpenWindow(#PB_Any, X, Y, 150, 40, Title$,  #PB_Window_SystemMenu | #PB_Window_TitleBar, WindowID(CallerWindowID))
  AddKeyboardShortcut(Window, #PB_Shortcut_Escape, #VK_ESCAPE) 
  AddKeyboardShortcut(Window, #PB_Shortcut_Return, #VK_RETURN) 
  
  If Window And CreateGadgetList(WindowID(Window))
    Date = DateGadget(#PB_Any, 10, 10, 90, 20, "%mm/%dd/%yyyy", DefaultDate)
    Button = ButtonGadget(#PB_Any, 110, 10, 30, 20, "OK")
   
    DisableWindow(CallerWindowID, #True)
    SetActiveGadget(Date)

    Repeat
      Event       = WaitWindowEvent()
      EventWindow = EventWindow()
      EventGadget = EventGadget()
      EventMenu   = EventMenu()

      If EventWindow = Window
        Select Event
          Case #PB_Event_CloseWindow
             Result = 0
          Case #PB_Event_Menu
            If EventMenu = #VK_RETURN : Result = GetGadgetState(Date) : EndIf
            If EventMenu = #VK_ESCAPE : Result = 0 : EndIf
          Case #PB_Event_Gadget
            If EventGadget = Button : Result = GetGadgetState(Date) : EndIf
        EndSelect
      EndIf
    Until Result > -1
    
    CloseWindow(Window)
    DisableWindow(CallerWindowID, #False)
    SetActiveGadget(CallerItemID)

    ProcedureReturn Result
  EndIf

EndProcedure
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
Antworten