CalenderGadget und MCHITTESTINFO

Anfängerfragen zum Programmieren mit PureBasic.
Häns
Beiträge: 47
Registriert: 27.10.2007 14:30
Wohnort: Kölle

CalenderGadget und MCHITTESTINFO

Beitrag von Häns »

Hallo Forum,

ich bin auf der Suche nach einer Möglichkeit, am CalenderGadget Doppelklick-Aktionen ausführen zu lassen. Leider wird Event-Type() nicht unterstützt, auch nicht mit #WM_LBUTTONDBLCLK. Ziel meines Projekts ist, dass dem Anwender erst nach Doppelklick auf den Monatskalender ein weiteres Fenster geöffnet wird.

Ich habe in den Foren nur folgenden Ansatz (bzw. hier) gefunden: die Struktur #MCM_HITTEST mit seinen entsprechenden Values.

Nur werde ich einfach nicht schlau, wie ich einerseits die Abfrage, wo der Anwender am Kalender geklickt hat, und andererseits die Reaktion, die erst nach einem Doppelklick ausgeführt werden soll, zusammenbringen kann. Win-API ist nicht gerade meine Stärke...

Kann mir einer helfen oder einen Gedankenstoss geben?

Dankesgruß, Häns
PB 5.6
Windows 7 Professional
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Es gibt kein #WM_LBUTTONDBLCLK Event weil der Fensterklasse der #CS_DBLCLKS-Stil fehlt. Das macht auch Sinn da sonst die Funktionalität beeinträchtigt wird. Es nun wichtig zu wissen wo genau ein Doppelklick registriert werden soll. Überall? Buttons? Weißfläche?
Windows 10 Pro, 64-Bit / Outtakes | Derek
Häns
Beiträge: 47
Registriert: 27.10.2007 14:30
Wohnort: Kölle

Beitrag von Häns »

@Fluid Byte:

Danke für deine Erklärung! :D
Auf deine Frage, wo genau der Doppelklick sein soll:

Bild

Beim Doppelklick auf einen der Tage eines momentan angezeigten Monats (im Rahmen dargestellt) soll das Programm reagieren, nicht auf die Leiste oben, nicht auf "inaktiven" bzw. hellgrauen Ziffern und nicht auf den Hintergrund. Wäre damit MCHT_CALENDARDATE gemeint?

Häns
PB 5.6
Windows 7 Professional
Häns
Beiträge: 47
Registriert: 27.10.2007 14:30
Wohnort: Kölle

Beitrag von Häns »

Ich habe mal anhand des o.g. Forums ein wenig gebastelt, und bin zumindest bis dahin gekommen:

Code: Alles auswählen

;- Zum großen Teil aus dem engl. Forum von Sparkie:
    
    #MCHT_TITLE = $10000
    #MCM_HITTEST = #MCM_FIRST + 14
    #MCHT_CALENDAR         = $20000 
    #MCHT_CALENDARDATE     = #MCHT_CALENDAR | $0001  ;- <-- damit hat sich meine Frage geklärt!
		
Structure _MCHITTESTINFO
  cbSize.l
  pt.POINT
  uHIt.l
  st.SYSTEMTIME
EndStructure

mcht._MCHITTESTINFO\cbSize = SizeOf(_MCHITTESTINFO)

If OpenWindow(0, 0, 0, 300, 300,"CalendarGadget Hit Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
  CalendarGadget(1, 50, 20, 200, 180)
  TextGadget(2, 10, 230, 200, 25, "")
  Repeat
    event = WaitWindowEvent()
    If event = #PB_Event_Gadget And EventGadget() = 1
      SetGadgetText(2, "")
      ; --> Get mouse location
      mcht\pt\x = DesktopMouseX()
      mcht\pt\y = DesktopMouseY()
      ; --> Convert mouse location to CalendarGadget coordinates
      ScreenToClient_(GadgetID(1), @mcht\pt)
      SendMessage_(GadgetID(1), #MCM_HITTEST, 0, @mcht)
      Select mcht\uHit
        Case #MCHT_CALENDARDATE
        Debug "Du hast auf den " + FormatDate("%dd.%mm.%yyyy",GetGadgetState(1)) + " geklickt."
      EndSelect
    EndIf
  Until event = #PB_Event_CloseWindow
EndIf
End
Was mir jetzt noch fehlt, ist die Möglichkeit, im Kalender nur auf Doppelklick reagieren zu lassen....

Häns
PB 5.6
Windows 7 Professional
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

So vielleicht?

Code: Alles auswählen

 #MCM_HITTEST = #MCM_FIRST + 14
 #MCHT_CALENDAR = $20000
 #MCHT_CALENDARDATE = #MCHT_CALENDAR | $0001
 
Structure MCHITTESTINFO
	cbSize.l
	pt.POINT
	uHIt.l
	st.SYSTEMTIME
EndStructure

Global lpPrevFunc

Procedure ChildSubProc(hWnd,uMsg,wParam,lParam)
	Select uMsg
		Case #WM_LBUTTONDBLCLK
		mcht.MCHITTESTINFO\cbSize = SizeOf(MCHITTESTINFO)
      mcht\pt\x = DesktopMouseX()
      mcht\pt\y = DesktopMouseY()
      
      ScreenToClient_(GadgetID(0), @mcht\pt)
      SendMessage_(GadgetID(0),#MCM_HITTEST,0,mcht)
     
      If mcht\uHit = #MCHT_CALENDARDATE
        Debug "Du hast auf den " + FormatDate("%dd.%mm.%yyyy",GetGadgetState(0)) + " geklickt."
      EndIf
	EndSelect
	  
	ProcedureReturn CallWindowProc_(lpPrevFunc,hWnd,uMsg,wParam,lParam)
EndProcedure

OpenWindow(0,0,0,300,300,"CalendarGadget Hit Test",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
CalendarGadget(0,50,20,200,180)

lpPrevFunc = SetWindowLong_(GadgetID(0),#GWL_WNDPROC,@ChildSubProc())

SetClassLong_(GadgetID(0),#GCL_STYLE,GetClassLong_(GadgetID(0),#GCL_STYLE) | #CS_DBLCLKS)

While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
Oder soll auch die grafische Aktualisierung bei einem einfachen Klick unterbunden werden?
Windows 10 Pro, 64-Bit / Outtakes | Derek
Häns
Beiträge: 47
Registriert: 27.10.2007 14:30
Wohnort: Kölle

Beitrag von Häns »

@Fluit Byte

Yepp, das ist es! :allright: :allright: :allright:
Die grafische Aktualisierung spielt im meinem Projekt keine Rolle, daher reicht mir Dein Code vollkommen!

Nochmals Danke!

Häns
PB 5.6
Windows 7 Professional
Antworten