Seite 1 von 2

ButtonHoverGadget (Testlib)

Verfasst: 24.10.2005 12:34
von ts-soft
Ein sehr kleine GadgetLib :) zum Testen

Syntax:

Code: Alles auswählen

ButtonHoverGadget(Gadget, x, y, With, Height, DefaultImageID, HoverImageID[, PressedImageID])
Die ersten 6 Parameter entsprechen dem ButtonImageGadget (#PB_Any wird unterstützt)
HoverImageID erscheint, wenn der Mauszeiger sich über dem Button erscheint
PressedImageID (Optional) erscheint beim Drücken des Buttons (Maus oder Taste)

Beschreibung:
Es wurde das Original ButtonImageGadget gewrapped, um auch Einsteigern ein 3 State Button zu ermöglichen, ohne Kenntnisse der Windows-API

Example:

Code: Alles auswählen

DataSection
  DefImg:
  IncludeBinary "Button_Default.bmp" ;die Bilder befinden sich im Librarie-Archiv
  HovImg:
  IncludeBinary "Button_Hover.bmp"
EndDataSection

; Windows Konstanten
Enumeration
  #frmMain
EndEnumeration

; Gadget Konstanten
Enumeration
  #btnHover
EndEnumeration

If OpenWindow(#frmMain, #CW_USEDEFAULT, #CW_USEDEFAULT, 185, 70, #PB_Window_SystemMenu, "Hover-Test") = #False : End : EndIf

If CreateGadgetList(WindowID(#frmMain))
  ButtonHoverGadget(#btnHover, 10, 10, 163, 47, UseImage(CatchImage(#PB_Any, ?DefImg)), UseImage(CatchImage(#PB_Any, ?HovImg)))
EndIf

Repeat
  EventID   = WaitWindowEvent()
  MenuID    = EventMenuID()
  GadgetID  = EventGadgetID()
  Select EventID
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      Select GadgetID
        Case #btnHover
          MessageRequester("HoverTest", "Danke für das testen")
      EndSelect
  EndSelect
ForEver
End
Über Feedback, Anregungen und Wünsche würde ich mich freuen. Bei Interesse werden weitere Gadgets erstellt!

HoverButton
(15 KiBi)

Re: ButtonHoverGadget (Testlib)

Verfasst: 24.10.2005 12:53
von Kiffi
> Über Feedback, Anregungen und Wünsche würde ich mich freuen. Bei
> Interesse werden weitere Gadgets erstellt!

schönen Dank für Deine Lib! :D

Mir ist folgendes aufgefallen: Fährt man mit der Maus innerhalb des Buttons
herum, so kommt es ab und an zu Flackereffekten (ein 'grauer' Streifen
scrollt von oben nach unten durch). Mit scheint, dass Du bei MouseMove
ständig das Hover-Bildchen neu malst. Ist das so?

Ansonsten: :allright:

Kommen wir nun zu den Anregungen:

* Hovereffekt mit verschiedenen Farben (also HoverColor anstelle von HoverImage)

* Sanftes Ein- und Ausfaden zwischen Hover- und Nichthover-Status

Grüße ... Kiffi

Re: ButtonHoverGadget (Testlib)

Verfasst: 24.10.2005 13:10
von ts-soft
Kiffi hat geschrieben: Mir ist folgendes aufgefallen: Fährt man mit der Maus innerhalb des Buttons herum, so kommt es ab und an zu Flackereffekten (ein 'grauer' Streifen scrollt von oben nach unten durch). Mit scheint, dass Du bei MouseMove ständig das Hover-Bildchen neu malst. Ist das so?
Ist nicht so, hab ein Flag gesetzt, so das das Bild nur einmal getauscht wird, werde aber versuchen den Fehler noch zu beseitigen
Kiffi hat geschrieben: Ansonsten: :allright:
Danke
Kiffi hat geschrieben: Kommen wir nun zu den Anregungen:

* Hovereffekt mit verschiedenen Farben (also HoverColor anstelle von HoverImage)

* Sanftes Ein- und Ausfaden zwischen Hover- und Nichthover-Status

Grüße ... Kiffi
Schöne Vorschläge, werde es mir durch den Kopf gehen, wie ich es umsetzen kann. Evtl. soll es ja mal eine etwas grössere Lib werden, wo dann mehr Gadgets gewrapped werden. Mit dieser ersten Version wollte ich eigentlich meine Vorgehensweise des Wrappens per Subclassing testen. Ich denke auf diese Weise erhalten alle Gadgets ihre PB-Defaultmethoden automatisch, so das die Syntax nicht gelernt werden braucht. Bei Interesse will ich ja ein Gemeinschaftsprojekt draus machen.

PS: Das Beispiel enhält noch keine Unterstützung für ButtonPressed, ist aber integriert, hab bloß kein passendes Image gefunden :(

Verfasst: 24.10.2005 18:18
von ts-soft
Mit dem Flickern komme ich nicht so recht weiter, vielleicht kennt ja von euch einer die Lösung. Hier der Library-Source HoverButton.pb :

Code: Alles auswählen

Structure Hover
  hWnd.l
  DefaultImage.l
  PressedImage.l
  HoverImage.l
EndStructure

ProcedureDLL HoverButton_Init()
  NewList Hover.Hover()
EndProcedure

Procedure HoverCallback(hWnd, Msg, lParam, wParam)
  Protected Found
  Shared OldProc
  ForEach Hover()
    If Hover()\hWnd = hWnd
      Found = #True
      Break
    EndIf
  Next
  If Found
    If Msg = #WM_MOUSEMOVE
      GetCursorPos_(pt.POINT)
      GetWindowRect_(hWnd,re.RECT)
      If PtInRect_(re,pt\x,pt\y)
        SetCapture_(hWnd)
        If Hover()\HoverImage
          If GetGadgetState(GetDlgCtrlID_(Hover()\hWnd)) <> Hover()\HoverImage
            SetGadgetState(GetDlgCtrlID_(Hover()\hWnd),Hover()\HoverImage)
          EndIf
        EndIf
      Else
        ReleaseCapture_()
        If GetGadgetState(GetDlgCtrlID_(Hover()\hWnd)) <> Hover()\DefaultImage
          SetGadgetState(GetDlgCtrlID_(Hover()\hWnd),Hover()\DefaultImage)
        EndIf
      EndIf
    EndIf
  ElseIf Msg = #WM_KEYDOWN Or Msg = #WM_LBUTTONDOWN Or Msg = #WM_RBUTTONDOWN
    If Hover()\PressedImage
      If GetGadgetState(GetDlgCtrlID_(Hover()\hWnd)) <> Hover()\PressedImage
        SetGadgetState(GetDlgCtrlID_(Hover()\hWnd),Hover()\PressedImage)
      EndIf
    EndIf
  ElseIf Msg = #WM_KEYUP Or Msg = #WM_LBUTTONUP Or Msg = #WM_RBUTTONUP
    If Hover()\DefaultImage
      If GetGadgetState(GetDlgCtrlID_(Hover()\hWnd)) <> Hover()\DefaultImage
        SetGadgetState(GetDlgCtrlID_(Hover()\hWnd),Hover()\DefaultImage)
      EndIf
    EndIf
  EndIf
  ProcedureReturn CallFunctionFast(OldProc, hWnd, Msg, lParam, wParam)
EndProcedure

ProcedureDLL ButtonHoverGadget2(Gadget, x, y, With, Height, DefaultImageID, HoverImageID, PressedImageID)
  Protected hWnd, Result
  Shared OldProc
  Result = ButtonImageGadget(Gadget, x, y, With, Height, DefaultImageID)
  If Result
    If Gadget = #PB_Any 
      hWnd = GadgetID(Result)
    Else
      hWnd = Result
    EndIf
    AddElement(Hover())
    Hover()\hWnd = hWnd
    Hover()\DefaultImage = DefaultImageID
    Hover()\PressedImage = PressedImageID
    Hover()\HoverImage = HoverImageID
    OldProc = GetWindowLong_(hWnd, #GWL_WNDPROC)
    SetWindowLong_(hWnd, #GWL_WNDPROC, @HoverCallback())
  EndIf
  ProcedureReturn Result
EndProcedure

ProcedureDLL ButtonHoverGadget(Gadget, x, y, With, Height, DefaultImageID, HoverImageID)
  ProcedureReturn ButtonHoverGadget2(Gadget, x, y, With, Height, DefaultImageID, HoverImageID, 0)
EndProcedure

Bin für jede Hilfe dankbar, weil mit dem geflicker macht der HoverButton keine Spaß :wink:

Verfasst: 24.10.2005 18:30
von edel
Vielleicht waere es besser wenn du eigene Events abschickst bei einem
"hover" und "leave". So wird immer nur bei deinem Event das Bild
gewechselt und nicht wie jetzt bei jeder Bewegung ueber dem Gadget.
Ebenso wie trackmouseevent es macht.

oder so:

Code: Alles auswählen

  Structure Hover
    hwnd.l
    DefaultImage.l
    PressedImage.l
    HoverImage.l
    ishover.l ;<----
  EndStructure
  
  ProcedureDLL HoverButton_Init()
    NewList Hover.Hover()
  EndProcedure
  
  Procedure HoverCallback(hwnd, msg, lParam, wParam)
    Protected Found
    Shared OldProc
    ForEach Hover()
      If Hover()\hwnd = hwnd
        Found = #True
        Break
      EndIf
    Next
    If Found
      If msg = #WM_MOUSEMOVE
        GetCursorPos_(pt.POINT)
        GetWindowRect_(hwnd,re.RECT)
        If PtInRect_(re,pt\x,pt\y)
          SetCapture_(hwnd)
          If Hover()\HoverImage And Hover()\ishover = #False ;<----
            If GetGadgetState(GetDlgCtrlID_(Hover()\hwnd)) <> Hover()\HoverImage
              SetGadgetState(GetDlgCtrlID_(Hover()\hwnd),Hover()\HoverImage)
              Hover()\ishover = #True ;<----
            EndIf
          EndIf
        Else
          ReleaseCapture_()
          Hover()\ishover = #False;<----
          If GetGadgetState(GetDlgCtrlID_(Hover()\hwnd)) <> Hover()\DefaultImage
            SetGadgetState(GetDlgCtrlID_(Hover()\hwnd),Hover()\DefaultImage)
          EndIf
        EndIf
      EndIf
    ElseIf msg = #WM_KEYDOWN Or msg = #WM_LBUTTONDOWN Or msg = #WM_RBUTTONDOWN 
      If Hover()\PressedImage 
        If GetGadgetState(GetDlgCtrlID_(Hover()\hwnd)) <> Hover()\PressedImage
          SetGadgetState(GetDlgCtrlID_(Hover()\hwnd),Hover()\PressedImage) 
        EndIf
      EndIf
    ElseIf msg = #WM_KEYUP Or msg = #WM_LBUTTONUP Or msg = #WM_RBUTTONUP
      If Hover()\DefaultImage 
        If GetGadgetState(GetDlgCtrlID_(Hover()\hwnd)) <> Hover()\DefaultImage
          SetGadgetState(GetDlgCtrlID_(Hover()\hwnd),Hover()\DefaultImage)
          Hover()\ishover = #False ;<----
        EndIf
      EndIf
    EndIf
    ProcedureReturn CallFunctionFast(OldProc, hwnd, msg, lParam, wParam)
  EndProcedure
  
  ProcedureDLL ButtonHoverGadget2(Gadget, x, y, With, Height, DefaultImageID, HoverImageID, PressedImageID)
    Protected hwnd, Result
    Shared OldProc
    Result = ButtonImageGadget(Gadget, x, y, With, Height, DefaultImageID)
    If Result
      If Gadget = #PB_Any
        hwnd = GadgetID(Result)
      Else
        hwnd = Result
      EndIf
      AddElement(Hover())
      Hover()\hwnd = hwnd
      Hover()\DefaultImage = DefaultImageID
      Hover()\PressedImage = PressedImageID
      Hover()\HoverImage = HoverImageID
      OldProc = GetWindowLong_(hwnd, #GWL_WNDPROC)
      SetWindowLong_(hwnd, #GWL_WNDPROC, @HoverCallback())
    EndIf
    ProcedureReturn Result
  EndProcedure
  
  ProcedureDLL ButtonHoverGadget(Gadget, x, y, With, Height, DefaultImageID, HoverImageID)
    ProcedureReturn ButtonHoverGadget2(Gadget, x, y, With, Height, DefaultImageID, HoverImageID, 0)
  EndProcedure
  
  DataSection
  DefImg:
  IncludeBinary "Button_Default.bmp" ;die Bilder befinden sich im Librarie-Archiv
  HovImg:
  IncludeBinary "Button_Hover.bmp"
  EndDataSection
  
  ; Windows Konstanten
  Enumeration
    #frmMain
  EndEnumeration
  
  ; Gadget Konstanten
  Enumeration
    #btnHover
  EndEnumeration
  
  If OpenWindow(#frmMain, #CW_USEDEFAULT, #CW_USEDEFAULT, 185, 70, #PB_Window_SystemMenu, "Hover-Test") = #False : End : EndIf
  
  HoverButton_Init()
  
  If CreateGadgetList(WindowID(#frmMain))
    ButtonHoverGadget(#btnHover, 10, 10, 163, 47, UseImage(CatchImage(#PB_Any, ?DefImg)), UseImage(CatchImage(#PB_Any, ?HovImg)))
  EndIf
  
  Repeat
    EventID   = WaitWindowEvent()
    MenuID    = EventMenuID()
    GadgetID  = EventGadgetID()
    Select EventID
      Case #PB_Event_CloseWindow
        Break
      Case #PB_Event_Gadget
        Select GadgetID
          Case #btnHover
            MessageRequester("HoverTest", "Danke für das testen")
        EndSelect
    EndSelect
  ForEver
  End



Verfasst: 24.10.2005 18:40
von ts-soft
Danke hallodri, aber das funktioniert ja so nicht. Hab aber so ähnlich auch schon probiert, wo es funktioniert hat, aber das geflicker wahr dasselbe. Das Bild wird nicht bei jedem MouseMove ausgetauscht. Das flickern kommt durch irgendwas anderes, wobei ich nicht weiß was :freak:

Mit Trackmouseevent, weiß ich nicht wie das aussehen soll, wenn Du da ein kleines Beispiel hättest.

Verfasst: 24.10.2005 18:44
von edel
Ich hatte eben etwas vergessen und ausgebessert , bei mir klappt es , es fehlt allerdings noch eine Abfrage fuer leave.

Verfasst: 24.10.2005 18:48
von edel
Ist schon etwas aelter , daher keine Garantie ;-)
Wie Danilo schon erwaehnte funktioniert das unter Windows 95 nicht .

Code: Alles auswählen

Enumeration
  #Font_1
  #Font_2
  #Window
  #button
  #button1
EndEnumeration

Structure _TRACKMOUSEEVENT
  cbSize.l
  dwFlags.l
  hwndTrack.l
  dwHoverTime.l
EndStructure

Structure _Hover
  TME._TRACKMOUSEEVENT
  OldProc.l
EndStructure

#WM_MOUSEHOVER    = $000002A1
#WM_MOUSELEAVE    = $000002A3
#TME_HOVER        = $00000001
#TME_LEAVE        = $00000002

Procedure __callback(hwnd,msg,wParam,lParam)
  *temp._Hover = GetWindowLong_(hwnd,#GWL_USERDATA)
  Select msg
    Case #WM_MOUSEHOVER
      *temp\TME\dwFlags = #TME_LEAVE 
      ;- Beispiel
      SetGadgetFont(GetDlgCtrlID_(hwnd),UseFont(#Font_2))
    Case #WM_MOUSELEAVE
      *temp\TME\dwFlags = #TME_HOVER 
      ;- Beispiel
      SetGadgetFont(GetDlgCtrlID_(hwnd),UseFont(#Font_1))
  EndSelect
  TrackMouseEvent_(*temp\TME)
  ProcedureReturn CallWindowProc_(*temp\OldProc,hwnd,msg,wParam,lParam)
EndProcedure

Procedure Hover(Gadget)
  *temp._Hover             = AllocateMemory(SizeOf(_Hover))
  *temp\TME\cbSize         = SizeOf(_TRACKMOUSEEVENT)
  *temp\TME\dwFlags        = #TME_HOVER ; hover event einfuegen
  *temp\TME\hwndTrack      = GadgetID(Gadget) ; handle des gadget
  *temp\TME\dwHoverTime    = 10 ; millisekunden bis event ausgeloest wird.
  *temp\OldProc            = SetWindowLong_(GadgetID(Gadget),#GWL_WNDPROC,@__callback())
  SetWindowLong_(GadgetID(Gadget),#GWL_USERDATA,*temp) ; *temp wird in das gadget gespeichert und im callback wieder ausgelesen
  TrackMouseEvent_(*temp\TME)
  ;- Beispiel
  SetGadgetFont(Gadget,UseFont(#Font_1))
EndProcedure


;- test

LoadFont(#Font_1,"verdana",8)
LoadFont(#Font_2,"verdana",11)

If OpenWindow(#Window, 216, 0, 602, 504, #PB_Window_SystemMenu| #PB_Window_TitleBar | #PB_Window_ScreenCentered , "New window ")
  If CreateGadgetList(WindowID())
    ButtonGadget(#button,10,10,100,23,"lala")  : Hover(#button)
    ButtonGadget(#button1,110,10,100,23,"lulu"): Hover(#button1)
  EndIf
EndIf


Repeat
  Event = WaitWindowEvent()
Until Event = #PB_EventCloseWindow 
Sorry fuer den Doppelpost.

Verfasst: 24.10.2005 18:55
von ts-soft
Danke, werde es mir morgen mal ansehen, sieht ja komisch aus. Mal sehen, wie ich die gepointerte Struktur integriere :freak:
Gibts da keine simple Lösung :?:

Verfasst: 24.10.2005 19:06
von edel
[...] Das Bild wird nicht bei jedem MouseMove ausgetauscht [...]
Stimmt , habe mich in einer Zeile vertan :oops:

Danke, werde es mir morgen mal ansehen, sieht ja komisch aus. Mal sehen, wie ich die gepointerte Struktur integriere Freak
Gibts da keine simple Lösung
Du kannst die Struktur auch ganz normal in deiner Linkedlist unterbringen