Seite 2 von 3
Re: "Reichweite" des DateGadgets
Verfasst: 18.12.2015 11:41
von Kurzer
Hallo RSBasic,
diese Version funktioniert bei mir mit dem CalendarGadget() leider auch nicht. Mit dem DateGadget geht es zwar, aber das geht ja auch schon ohne Callback.
Tausche in Deinem Code mal das DateGadget() gegen das hier aus:
Geht das dann bei Dir immer noch?
Re: "Reichweite" des DateGadgets
Verfasst: 18.12.2015 12:44
von edel
Warum sollte das funktionieren? Es ist doch ein ganz anderes Control.
Statt #DTN_DATETIMECHANGE benutze #MCN_SELCHANGE (-749)
Re: "Reichweite" des DateGadgets
Verfasst: 18.12.2015 13:23
von RSBasic
@Kurzer
Jetzt hab ich mich zu sehr auf das Ursprungsthema konzentriert. Mein Code funktioniert nur mit dem DateGadget.
CalendarGadget ist ein anderes Gadget, wie edel bereits sagte, und da musst du andere WinAPI-Konstanten verwenden.
Hier der Code für CalendarGadget:
Code: Alles auswählen
EnableExplicit
#MCN_SELCHANGE = #MCN_FIRST + 1
#MCN_SELECT = #MCN_FIRST + 4
Procedure WinCallback(hWnd, uMsg, wParam, lParam)
Protected *NMHDR.NMHDR
Protected SYSTEMTIME.SYSTEMTIME
Select uMsg
Case #WM_NOTIFY
*NMHDR = lParam
Select *NMHDR\hwndFrom
Case GadgetID(1)
Select *NMHDR\code
Case #MCN_SELECT
SendMessage_(GadgetID(1), #MCM_GETCURSEL, 0, SYSTEMTIME)
Debug Str(SYSTEMTIME\wDay) + "." + Str(SYSTEMTIME\wMonth) + "." + Str(SYSTEMTIME\wYear)
EndSelect
EndSelect
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CalendarGadget(1, 10, 10, 200, 200, Date())
SetWindowCallback(@WinCallback())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
EndSelect
ForEver
EndIf
Kurzer hat geschrieben:Mit dem DateGadget geht es zwar, aber das geht ja auch schon ohne Callback.
Nicht ganz, das ist eben genau der Grund, warum ich es mit dem Callback gemacht habe. Hast du schon mal versucht, mit dem Code von edel einen beliebigen Tag vor 1969 oder nach 2038 auszuwählen? Da wird kein PB-Event mehr ausgelöst.
Re: "Reichweite" des DateGadgets
Verfasst: 18.12.2015 21:40
von Kurzer
Edel, danke für den Hinweis. Ich stecke nicht in der API Programmierung, daher meine naive Annahme es müsse auch bei einem anderen GadgetTypen funktionieren.
RSBasic hat geschrieben:Kurzer hat geschrieben:Mit dem DateGadget geht es zwar, aber das geht ja auch schon ohne Callback.
Nicht ganz, das ist eben genau der Grund, warum ich es mit dem Callback gemacht habe. Hast du schon mal versucht, mit dem Code von edel einen beliebigen Tag vor 1969 oder nach 2038 auszuwählen? Da wird kein PB-Event mehr ausgelöst.
Ja, das geht beim DateGadget mit Edels code. Irgend eine Art von Event wird dort offenbar auch bei Daten jenseits von 2038 erzeugt. Nur beim CalendarGadget zuckt sich nach 2038 nichts mehr.
Hmm das mit dem Callback ist ja nicht so optimal, wenn man innerhalb einer Datums-Lib ein GetDate() / SetDate() realisieren will.
Ich hatte mich bzgl. eines anderen threads letztendlich doch für Wilberts 64 bit Date-Funktionen entschieden und gehofft, dass ich dafür nun passende Set- und Get-Routinen erstellen kann. Ist aber wohl doch nicht so einfach realisierbar, wenn man dabei völlige Unabhängigkeit vom Hauptcode haben möchte.
Re: "Reichweite" des DateGadgets
Verfasst: 18.12.2015 21:50
von RSBasic
In der "WinAPI-Welt" ist Callback die Eventabfrage. PB hat seine eigene, separate Ereignisschleife.
Du kannst alternativ im Callback ein eigenes Event mit PostEvent() auslösen und die ausgelesenen Datumswerte weiterleiten, so dass du wieder in der "PureBasic-Welt" bist und weiterhin wie gewohnt in der typischen PB-Schleife das Event abfragen und auswerten kannst.
Re: "Reichweite" des DateGadgets
Verfasst: 18.12.2015 22:01
von Kurzer
Ja, aber man muss sein CalendarGadget vorher irgendwo registrieren, damit der Callback die Gadgetnummer kennt, oder nicht? Die Set/Get Prozeduren sollen eigentlich in einem unabhängigen Modul liegen und sich neutral zum Hauptcode verhalten.
Wenn ich das mit dem Callback richtig verstehe, braucht es doch mindestens noch eine Prozedur ála RegisterDateGadget(GadgetNrMeinesCalendarGadgets) die nötig ist, damit die Sache mit dem Callback funktioniert.
Re: "Reichweite" des DateGadgets
Verfasst: 18.12.2015 22:09
von RSBasic
Wenn der Code neutral und unabhängig sein soll:
Code: Alles auswählen
EnableExplicit
Global CalendarProc
Procedure CalendarProc(hWnd, uMsg, wParam, lParam)
Protected SYSTEMTIME.SYSTEMTIME
Select uMsg
Case #WM_LBUTTONUP
SendMessage_(hWnd, #MCM_GETCURSEL, 0, SYSTEMTIME)
Debug Str(SYSTEMTIME\wDay) + "." + Str(SYSTEMTIME\wMonth) + "." + Str(SYSTEMTIME\wYear)
EndSelect
ProcedureReturn CallWindowProc_(CalendarProc, hWnd, uMsg, wParam, lParam)
EndProcedure
If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CalendarGadget(1, 10, 10, 200, 200, Date())
CalendarProc = SetWindowLongPtr_(GadgetID(1), #GWL_WNDPROC, @CalendarProc())
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Ein anderes Event als "#WM_LBUTTONUP" habe ich nicht gefunden.
Re: "Reichweite" des DateGadgets
Verfasst: 18.12.2015 22:13
von Kurzer
Aha, ich habe gerade festgestellt, dass diese Windowsstruktur NMHDR auch die GadgetNummer enthält.
Damit kann ich dynamisch jedes CalendarGadget bearbeiten.
Code: Alles auswählen
Procedure WinCallback(hWnd, uMsg, wParam, lParam)
Protected *NMHDR.NMHDR
Protected SYSTEMTIME.SYSTEMTIME
If uMsg = #WM_NOTIFY
*NMHDR = lParam
If GadgetType(*NMHDR\idFrom) = #PB_GadgetType_Calendar And *NMHDR\code = #MCN_SELECT
SendMessage_(GadgetID(*NMHDR\idFrom), #MCM_GETCURSEL, 0, SYSTEMTIME)
Debug Str(SYSTEMTIME\wDay) + "." + Str(SYSTEMTIME\wMonth) + "." + Str(SYSTEMTIME\wYear)
EndIf
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Einziger "Schwachpunkt" ist halt das explizite Setzen des Callbacks außerhalb des Moduls bevor man die Set/Get Routnen benutzen kann. Dann muss ich halt eine Init Routine bereitstellen, die den Callback installiert.
Re: "Reichweite" des DateGadgets
Verfasst: 18.12.2015 23:39
von Kurzer
@RSBasic / Edel:
Erstmal vielen Dank für Deinen Input, das bringt mich auf jeden Fall weiter.
Noch eine Frage: Was muss/darf der Callback zurückgeben, wenn das PureBasic Event explizit nicht verarbeitet werden soll? Bei meinem Test habe ich den Fall, dass das DateGadget im gültigen Datumsbereich (1970 - 2038) selbst auch noch einen Event feuert und man so im Eventloop einen doppelten Event bekommt.
Möglicherweise bekomme ich damit auch die umständliche Unterdrückung der doppelten Ausgabe des Datums im Callback geregelt (dLastDateGadgetDate und dLastCalendarGadgetDate). Da das aber nur Testausgaben sind, ist das später eh irrelevant.
Code: Alles auswählen
EnableExplicit
#MCN_SELCHANGE = #MCN_FIRST + 1
;#MCN_SELECT = #MCN_FIRST + 4
Procedure WinCallback(hWnd, uMsg, wParam, lParam)
Static.d dLastCalendarGadgetDate, dLastDateGadgetDate
Protected *NMHDR.NMHDR
Protected SYSTEMTIME.SYSTEMTIME
If uMsg = #WM_NOTIFY
*NMHDR = lParam
If GadgetType(*NMHDR\idFrom) = #PB_GadgetType_Calendar And *NMHDR\code = #MCN_SELCHANGE
SendMessage_(GadgetID(*NMHDR\idFrom), #MCM_GETCURSEL, 0, SYSTEMTIME)
If dLastCalendarGadgetDate <> PeekQ(@SYSTEMTIME)
PostEvent(#PB_Event_Gadget, GetParent_(*NMHDR\hwndFrom), *NMHDR\idFrom, #PB_EventType_Change)
dLastCalendarGadgetDate = PeekQ(@SYSTEMTIME)
Debug Str(SYSTEMTIME\wDay) + "." + Str(SYSTEMTIME\wMonth) + "." + Str(SYSTEMTIME\wYear)
EndIf
ElseIf GadgetType(*NMHDR\idFrom) = #PB_GadgetType_Date And *NMHDR\code = #DTN_DATETIMECHANGE
SendMessage_(GadgetID(*NMHDR\idFrom), #DTM_GETSYSTEMTIME, 0, SYSTEMTIME)
If dLastDateGadgetDate <> PeekQ(@SYSTEMTIME)
PostEvent(#PB_Event_Gadget, GetParent_(*NMHDR\hwndFrom), *NMHDR\idFrom, #PB_EventType_Change)
dLastDateGadgetDate = PeekQ(@SYSTEMTIME)
Debug Str(SYSTEMTIME\wDay) + "." + Str(SYSTEMTIME\wMonth) + "." + Str(SYSTEMTIME\wYear)
EndIf
EndIf
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CalendarGadget(1, 10, 10, 200, 200, Date())
DateGadget(2, 220, 10, 250, 20)
SetWindowCallback(@WinCallback())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #PB_Event_Gadget
If EventType() = #PB_EventType_Change
Debug "Event: " + Str(EventGadget())
EndIf
EndSelect
ForEver
EndIf
Re: "Reichweite" des DateGadgets
Verfasst: 18.12.2015 23:48
von RSBasic
Zum Beispiel:
Code: Alles auswählen
EnableExplicit
#MCN_SELCHANGE = #MCN_FIRST + 1
;#MCN_SELECT = #MCN_FIRST + 4
#PB_EventType_Calendar_Change = #PB_Event_FirstCustomValue + #PB_EventType_Change
Procedure WinCallback(hWnd, uMsg, wParam, lParam)
Static.d dLastCalendarGadgetDate, dLastDateGadgetDate
Protected *NMHDR.NMHDR
Protected SYSTEMTIME.SYSTEMTIME
If uMsg = #WM_NOTIFY
*NMHDR = lParam
If GadgetType(*NMHDR\idFrom) = #PB_GadgetType_Calendar And *NMHDR\code = #MCN_SELCHANGE
SendMessage_(GadgetID(*NMHDR\idFrom), #MCM_GETCURSEL, 0, SYSTEMTIME)
If dLastCalendarGadgetDate <> PeekQ(@SYSTEMTIME)
PostEvent(#PB_Event_Gadget, GetParent_(*NMHDR\hwndFrom), *NMHDR\idFrom, #PB_EventType_Calendar_Change)
dLastCalendarGadgetDate = PeekQ(@SYSTEMTIME)
Debug Str(SYSTEMTIME\wDay) + "." + Str(SYSTEMTIME\wMonth) + "." + Str(SYSTEMTIME\wYear)
EndIf
ElseIf GadgetType(*NMHDR\idFrom) = #PB_GadgetType_Date And *NMHDR\code = #DTN_DATETIMECHANGE
SendMessage_(GadgetID(*NMHDR\idFrom), #DTM_GETSYSTEMTIME, 0, SYSTEMTIME)
If dLastDateGadgetDate <> PeekQ(@SYSTEMTIME)
PostEvent(#PB_Event_Gadget, GetParent_(*NMHDR\hwndFrom), *NMHDR\idFrom, #PB_EventType_Calendar_Change)
dLastDateGadgetDate = PeekQ(@SYSTEMTIME)
Debug Str(SYSTEMTIME\wDay) + "." + Str(SYSTEMTIME\wMonth) + "." + Str(SYSTEMTIME\wYear)
EndIf
EndIf
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CalendarGadget(1, 10, 10, 200, 200, Date())
DateGadget(2, 220, 10, 250, 20)
SetWindowCallback(@WinCallback())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #PB_Event_Gadget
If EventType() = #PB_EventType_Calendar_Change
Debug "Event: " + Str(EventGadget())
EndIf
EndSelect
ForEver
EndIf