Deutsches AutoHotkey Homepage AutoHotkey Community
Wir helfen uns gegenseitig aus der Patsche
 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   RegistrierenRegistrieren 
 ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

TechDemo: AnimateGui ohne AnimateWindow

 
Neues Thema eröffnen   Neue Antwort erstellen    AutoHotkey Community Foren-Übersicht -> Skripte & Funktionen
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
denick



Anmeldedatum: 15.09.2006
Beiträge: 947
Wohnort: Berlin

BeitragVerfasst am: Fr März 21, 2008 9:28 am    Titel: TechDemo: AnimateGui ohne AnimateWindow Antworten mit Zitat

Moin,

angeregt durch Dbof's Thread, der ja unbedingt eine Gui mit Titelzeile animieren will, habe ich das folgende Spielzeug geschrieben, das zeigt, wie man Guis auch ohne DllCall "animieren" kann. Als Bonbon klappt das Fenster aus, wenn man mit der Maus über der Titelzeile verharrt, und wieder ein, wenn man das Fenster verlässt:

Code:
#NoEnv
; Pause zwischen Win-Anweisungen minimieren
SetWinDelay, 0
; Höhe einer niedrigen Titelzeile (ToolWindow)
SysGet, CH, 51
; Höhe eines normalen Rahmens
Sysget, BY, 8
; Vorgabe für Transparenz
TR := 120
; Vorgabe für Timerdurchläufe MausDrin/MausRaus bis zur Reaktion
ZMax := 3
; Vorgabe für Schrittweite beim Ein-/Ausklappen
DY := 1
; Fenstertitel
TITEL := "     Mein Klappfenster"

; Aktives Fenster sichern
WinGet, ID, ID, A
; Gui aufbauen
Gui, -SysMenu +AlwaysOnTop +ToolWindow
Gui, Margin, 0, 0
Gui, Add, Button, w50 h50 gKlick, 1
Gui, Add, Button, x+0 yp wp hp gKlick, 2
Gui, Add, Button, x+0 yp wp hp gKlick, 3
Gui, Add, Button, x+0 yp wp hp gKlick, 4
Gui, Add, Button, x+0 yp wp hp gKlick, 5
Gui, Add, Button, xm wp hp gKlick, 6
Gui, Add, Button, x+0 yp wp hp gKlick, 7
Gui, Add, Button, x+0 yp wp hp gKlick, 8
Gui, Add, Button, x+0 yp wp hp gKlick, 9
Gui, Add, Button, x+0 yp wp hp gKlick, 10
Gui, Show, AutoSize Hide, %TITEL%
Gui, +LastFound
; ID der Gui merken
GuiID := WinExist()
; Breite und maximale (aktuelle) Höhe bestimmen
WinGetPos, , , WMax, HMax
; Minimale Höhe := Titelzeile + unterer Rand
HMin := CH + BY
; Einblenden
GoSub, Einblenden
; Eine Sekunde anzeigen
Sleep, 1000
; Und einklappen
GoSub, Einklappen
; Gesichertes Fenster aktivieren
WinActivate, ahk_id %id%
Return
; ------------------------------------------------------------------------------
GuiClose:
GuiEscape:
ExitApp
; ------------------------------------------------------------------------------
Klick:
   Gui, +OwnDialogs
   MsgBox, 0, Button, % "Button " . A_GuiControl . " wurde geklickt!", 1
Return
; ------------------------------------------------------------------------------
Einblenden:
Gui, Show, w0 h0
; X-Position für erste Anzeige : zentriert
X := A_ScreenWidth // 2
; Minimale X-Position
XMin := (A_ScreenWidth - WMax) // 2
; Y-Position für die erste Anzeige : oben
Y := 0
; Delta für Breite
DW := DY * 2
; Grundstellung W und H
W := H := 0
Loop {
   W := (W + DW) <= WMax ? W + DW : WMax
   H := (H + DY) <= HMax ? H + DY : HMax
   X := (X - DY) >= XMin ? X - DY : XMin
   WinMove, ahk_id %GuiID%, , X, Y, W, H
   ; Wenn maximale Breite und Höhe erreicht sind: Tschüss!
   If (W = WMax And H = HMax) {
      Break
   }
}
Return
; ------------------------------------------------------------------------------
Ausklappen:
   ; Ausgangshöhe setzen
   H := HMin
   ; Tranparenz ausschalten
   WinSet, Transparent, Off, ahk_id %GuiID%
   ; Ausklappen
   Loop {
      ; Höhe + Schrittweite
      H += DY
      ; Wenn die maximale Höhe erreicht ist: maximale Höhe setzen und Tschüss!
      If (H > HMax) {
         WinMove, ahk_id %GuiID% , , , , , HMax
         Break
      }
      ; Fensterhöhe vergrößern
      WinMove, ahk_id %GuiID% , , , , , H
   }
   ; Timerzähler auf Null
   Z := 0
   ; Mausüberwachung "außerhalb" einschalten
   SetTimer, MausRaus, On
Return
; ------------------------------------------------------------------------------
Einklappen:
   ; Ausgangshöhe setzen
   H := HMax
   ; Einklappen
   Loop {
      ; Höhe - Schrittweite
      H -= DY
      ; Wenn die minimale Höhe erreicht ist: minimale Höhe setzen und Tschüss!
      If (H < HMin) {
         WinMove, ahk_id %GuiID% , , , , , HMin
         Break
      }
      ; Fensterhöhe verringern
      WinMove, ahk_id %GuiID% , , , , , H
   }
   ; Transparenz einschalten
   WinSet, Transparent, %TR%, ahk_id %GuiID%
   ; Timerzähler auf Null
   Z := 0
   ; Mausüberwachung "innerhalb" einschalten
   SetTimer, MouseDrin, On
Return
; ------------------------------------------------------------------------------
MausRaus:
   ; Maus außerhalb des Fensters ?
   MouseGetPos, , , ID
   If (ID = GuiID) {
      Z := 0
   } Else {
      Z++
   }
   If (Z < ZMax) {
      Return
   }
   SetTimer, MausRaus, Off
   GoSub, Einklappen
Return
; ------------------------------------------------------------------------------
MouseDrin:
   ; Bei gedrückter linker Maustaste nichts tun
   If (GetKeyState("LButton", "P")) {
      Z := 0
      Return
   }
   ; Maus innerhalb des Fensters ?
   MouseGetPos, , , ID
   If (ID = GuiID) {
      Z++
   } Else {
      Z := 0
   }
   If (Z < ZMax) {
      Return
   }
   SetTimer, MouseDrin, Off
   GoSub, Ausklappen
Return


EDIT:

Hier ist noch die auf das Wesentliche reduzierte und von Chucky gewünschte Funktion:

Code:
; -------------------------------------------------------------------------------
; Funktion: DropDown_GUI()
; Beschreibung:
;    Macht eine Gui zu einem "Ausklappfenster", d.h., das Fenster wird zunächst
;    auf die semitransparente Titelleiste reduziert, "klappt" wieder auf, wenn
;    man mit der Maus über diesem Segment verharrt, und "klappt" schließlich
;    wieder ein, wenn die Maus das Fenster verlässt
; Funktionsaufruf:
;    DropDown_GUI(GuiNum [, PTR=128, PTM=4, PDP=1])
; Funktionsparameter:
;   GuiNum       : Gui-Nummer
;                  -1 schaltet die Animation aus
;   Optional PTR : Transparenz
;                  Standard: 128, Wertebereich: 80 - 180
;                  -1 für Standard
;   Optional PTM : Timerdurchläufe für das Auslösen der Aktion
;                  Standard: 4, Wertebereich: 1 - 8
;                  -1 für Standard
;   Optional PDP : Schrittweite bei Animation in Prozent
;                  Standard: 1, Wertebereich: 0.2 - 5
;                  -1 für Standard
; Rückgabewerte:
;   1 / True     : Aufruf fehlerfrei ausgeführt
;   0 / False    : Fehler beim Aufruf der Funktion festgestellt.
;   ErrorLevel   : Beim Rückgabewert 0 wird ErrorLevel zusätzlich auf einen der
;                  folgenden Werte gesetzt:
;                  -1 = Die Funktion ist bereits aktiv (GuiNum > 0)
;                  -2 = Die Funktion ist nicht aktiv (GuiNum = -1)
;                   1 = Guifehler, für die übergebene Guinummer existiert kein
;                       Fenster oder es ist minimiert oder verborgen
;                   2 = Parameter PTR ist ungültig
;                   3 = Parameter PTM ist ungültig
;                   4 = Parameter PDP ist ungültig
; -------------------------------------------------------------------------------
DropDown_GUI(GuiNum, PTR=128, PTM=3, PDP=1) {
   ; Variable für Initialisierung
   Static Init := True
   ; Variable für die Speicherung der Gui-ID
   Static ID
   ; Transparenz bei eingeklapptem Gui
   Static TR
   ; Timerdurchläufe MausDrin/MausRaus bis zur Reaktion
   Static TM
   ; Schrittweite beim Ein-/Ausklappen in Prozent
   Static DP
   ; Variable für Delta-Y
   Static DY
   ; Variable für maximale Höhe
   Static HMax
   ; Variable für minimale Höhe
   Static HMin
   ; Variable für aktuellen Klappstatus (EIN/AUS)
   Static Status
   ; Timerdurchlaufzähler
   Static Z
   ; Gui mit Sysmenu?
   Static SM
   ; Gui mit AlwaysOnTop
   Static AT
   ; Werte für Style/ExStyle
   Static WS_SYSMENU       := 0x00080000
   Static WS_VISIBLE       := 0x10000000
   Static WS_THICKFRAME    := 0x00040000
   Static WS_DLGFRAME      := 0x00400000
   Static WS_EX_TOOLWINDOW := 0x00000080
   Static WS_EX_TOPMOST    := 0x00000008
   ; ----------------------------------------------------------------------------
   ; Animation abschalten?
   ; ----------------------------------------------------------------------------
   If (GuiNum = -1) {
      ; Ist die Funktion aktiv?
      If (ID) {
         ; Funktion deaktivieren
         GoSub, _DG_EXIT
         Init := True
         ErrorLevel := False
         Return True
      } Else {
         ErrorLevel := -2
         Return False
      }
   }
   ; ----------------------------------------------------------------------------
   ; Funktion initialisieren?
   ; ----------------------------------------------------------------------------
   If Not Init {
      ErrorLevel := -1
      Return False
   }
   GoSub, _DG_INIT
   GoSub, _DG_PARAMS
   GoSub, _DG_GUI
   GoSub, _DG_EINKLAPPEN
   Init := False
   ErrorLevel := False
   Return True
   ; ----------------------------------------------------------------------------
   ; Funktion deaktivieren
   ; ----------------------------------------------------------------------------
   _DG_EXIT:
      ; Timer abschalten
      SetTimer, _DG_MAUSDRIN, Off
      SetTimer, _DG_MAUSRAUS, Off
      ; Gui ggf. ausklappen
      If (Status = "EIN") {
         GoSub, _DG_AUSKLAPPEN
         SetTimer, _DG_MAUSRAUS, Off
      }
      ; Gui-Eigenschaften ggf. restaurieren
      WinExist("ahk_id " . ID)
      If (SM)
         WinSet, Style, %SM%%WS_SYSMENU%
      If (AT)
         WinSet, ExStyle, %AT%%WS_EX_TOPMOST%
      ; Variablen initialisieren
      GoSub, _DG_INIT
   Return
   ; ----------------------------------------------------------------------------
   ; Funktion initialisieren
   ; ----------------------------------------------------------------------------
   _DG_INIT:
      ID := 0
      TR := 128
      TM := 4
      DP := 1
      SM := ""
      AT := ""
      DY := 0
      HMin := 0
      HMax := 0
      Z := 0
      Status := "AUS"
   Return
   ; ----------------------------------------------------------------------------
   ; Parameter auswerten
   ; ----------------------------------------------------------------------------
   _DG_PARAMS:
      If PTR Is Not Integer
      {
         ErrorLevel := 2
         Return False
      }
      If PTM Is Not Integer
      {
         ErrorLevel := 3
         Return False
      }
      If PDP Is Not Integer
      {
         If PDP Is Not Float
         {
            ErrorLevel := 4
            Return False
         }
      }
      ; Gibt es ein Guifenster? Wenn nein: Tschüss!
      Gui, %GuiNum%:+LastFoundExist
      If Not (ID := WinExist()) {
         ErrorLevel := 1
         Return False
      }
      ; Ist das Fenster mimimiert? Wenn ja: Tschüss
      WinGet, MM, MinMax
      If (MM = -1) {
         ErrorLevel := 1
         Return False
      }
      ; Ist das Fenster verborgen? Wenn ja: Tschüss!
      WinGet Style, Style
      If Not (Style & WS_VISIBLE) {
         ErrorLevel := 1
         Return False
      }
      ; Transparenz nur 80 bis 180
      If (PTR = -1)
         TR := 128
      Else
         TR := (PTR < 80) ? 80 : (PTR > 180) ? 180 : PTR
      ; Timerdurchläufe nur 1 bis 8
      If (PTM = -1)
         TM := 4
      Else
         TM := (PTM < 1) ? 1 : (PTM > 8) ? 8 : PTM
      ; Schrittweite nur 0.5 bis 5 Prozent
      If (PDP = -1)
         DP := 1
      Else
         DP := (PDP < 0.2) ? 0.2 : (PDP > 5) ? 5 : PDP
   Return
   ; ----------------------------------------------------------------------------
   ; Ggf. Gui anpassen
   ; ----------------------------------------------------------------------------
   _DG_GUI:
      ; Ggf. Sysmenü ausschalten
      WinGet, Style, Style
      If (Style & WS_SYSMENU) {
         SM := "+"
         WinSet, Style, -%WS_SYSMENU%
      }
      ; Ggf. AlwaysOnTop setzen
      WinGet, ExStyle, ExStyle
      If Not (ExStyle & WS_EX_TOPMOST) {
         AT := "-"
         WinSet, ExStyle, +%WS_EX_TOPMOST%
      }
   Return
   ; ----------------------------------------------------------------------------
   ; Einklappen
   ; ----------------------------------------------------------------------------
   _DG_EINKLAPPEN:
      ; LastFoundWindow setzen
      WinExist("ahk_id " . ID)
      ; Erweiterte Fenstereigenschaften abfragen
      WinGet, ExStyle, ExStyle
      ; Ist es ein ToolWindow ?
      If (ExStyle & WS_EX_TOOLWINDOW)
         SysGet, CH, 51
      Else
         SysGet, CH, 4
      ; Welche Rahmenart hat das Fenster?
      If (Style & WS_THICKFRAME)
         SysGet, BH, 33
      Else If (Style & WS_DLGFRAME)
         SysGet, BH, 8
      Else
         BH := 1
      ; Minimale Höhe = Höhe der Titelleiste + Rahmenhöhe
      HMin := CH + BH
      ; Ausgangshöhe setzen
      WinGetPos, , , , HMax
      H := HMax
      ; Schrittweite setzen
      DY := (HMax * DP) / 100
      ; Einklappen
      AWD := A_WinDelay
      SetWinDelay, 0
      Loop {
         ; Höhe - Schrittweite
         H -= DY
         ; Wenn die minimale Höhe erreicht ist: minimale Höhe setzen und Tschüss!
         If (H < HMin) {
            WinMove, , , , , , HMin
            Break
         }
         ; Fensterhöhe verringern
         WinMove, , , , , , H
      }
      SetWinDelay, %AWD%
      Status := "EIN"
      ; Transparenz einschalten
      WinSet, Transparent, %TR%
      Z := 0
      ; Mausüberwachung "innerhalb" einschalten
      SetTimer, _DG_MAUSDRIN, On
   Return
   ; ----------------------------------------------------------------------------
   ; Ausklappen
   ; ----------------------------------------------------------------------------
   _DG_AUSKLAPPEN:
      ; LastFoundWindow setzen
      WinExist("ahk_id " . ID)
     ; Ausgangshöhe setzen
      WinGetPos, , , , H
      ; Tranparenz ausschalten
      WinSet, Transparent, Off
      ; Ausklappen
      AWD := A_WinDelay
      SetWinDelay, 0
      Loop {
         ; Höhe + Schrittweite
         H += DY
         ; Wenn die max. Höhe erreicht ist: max. Höhe setzen und Tschüss!
         If (H > HMax) {
            WinMove, , , , , , HMax
            Break
         }
         ; Fensterhöhe vergrößern
         WinMove, , , , , , H
      }
      SetWinDelay, %AWD%
      Status := "AUS"
      ; Timerzähler auf Null
      Z := 0
      ; Mausüberwachung "außerhalb" einschalten
      SetTimer, _DG_MAUSRAUS, On
   Return
   ; ----------------------------------------------------------------------------
   ; Timer Mauskontrolle außerhalb
   ; ----------------------------------------------------------------------------
   _DG_MAUSRAUS:
      ; Maus außerhalb des Fensters?
      MouseGetPos, , , MID
      If (MID = ID)
         Z := 0
      Else
         Z++
      If (Z < TM)
         Return
      SetTimer, _DG_MAUSRAUS, Off
      GoSub, _DG_EINKLAPPEN
   Return
   ; ----------------------------------------------------------------------------
   ; Timer Mauskontrolle innerhalb
   ; ----------------------------------------------------------------------------
   _DG_MAUSDRIN:
      ; Bei gedrückter linker Maustaste nichts tun
      If (GetKeyState("LButton", "P")) {
         Z := 0
         Return
      }
      ; Maus innerhalb des Fensters?
      MouseGetPos, , , MID
      If (MID = ID)
         Z++
      Else
         Z := 0
      If (Z < TM)
         Return
      SetTimer, _DG_MAUSDRIN, Off
      GoSub, _DG_AUSKLAPPEN
   Return
}
; ----------------------------------------------------------------------------
; Ende Funktion DropDown_GUI()
; ----------------------------------------------------------------------------


Die Animation wird mit einem Funktionsaufruf angestoßen. Die Parameter sind:
1. Die Nummer der Gui
2. (Optional) Die gewünschte Tranzparenz
3. (Optional) Die gewünschte Verzögerung (Timerdurchläufe) bis zum Auslösen der Animation
4. (Optional) Die gewünschte Schrittweite beim Aus- und Einklappen (%)

Durch Aufruf mit Gui Nummer -1 kann die Animation wieder abgeschaltet werden.

Funktionsupdate:
2008-03-25:
Bug bei willkürlicher Aurufreihenfolge beseitigt.
Fehlerbehandlung auf Returncode und ErrorLevel umgestellt. (MsgBoxen sind ja für den Test äußerst brauchbar, für den "produktiven" Betrieb aber eher störend!)
_________________
Hilfe zur Hilfe

(de)nick


Zuletzt bearbeitet von denick am Di März 25, 2008 7:04 am, insgesamt 2-mal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
BoBo¨
Gast





BeitragVerfasst am: Fr März 21, 2008 10:21 am    Titel: Antworten mit Zitat

GVery HappyIL
Nach oben
IsNull



Anmeldedatum: 20.12.2006
Beiträge: 914
Wohnort: CH

BeitragVerfasst am: Fr März 21, 2008 10:46 am    Titel: Antworten mit Zitat

"mausraus" hehe

Ganz nice! Very Happy
_________________

http://securityvision.ch
www.forum.securityvision.ch
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Chucky



Anmeldedatum: 07.01.2006
Beiträge: 576
Wohnort: Powerland

BeitragVerfasst am: Fr März 21, 2008 1:15 pm    Titel: Re: TechDemo: AnimateGui ohne AnimateWindow Antworten mit Zitat

Hi denick,
super Cool ! Ich glaube, ich mache mir einen Ordner namens "Denicks Scripts"!

Um diese Funktionalität einfacher in bestehende Scripts einbauen zu können, habe ich mal alles in eine Funktion zusammengefaßt, die ohne globale Variablen auskommt. Als Parameter kann man Transparenz und gewünschte Fensterposition angeben. (Anmerkung: Die X-Position begrenze ich eigenmächtig auf 'XMin := 0' statt auf 'XMin := (A_ScreenWidth - WMax) // 2'.)
Ich würde mich freuen, wenn Du es mal ausprobierst bzw. drüberguckst, was die Aufteilung der Unterfunktionen und die Wahl der Parameter angeht.
Code:
#NoEnv

; Fenstertitel
TITEL := "     Mein Klappfenster"

; Gui aufbauen
Gui, Add, Button, w50 h50 gKlick, 1
Gui, Add, Button, x+0 yp wp hp gKlick, 2
Gui, Add, Button, x+0 yp wp hp gKlick, 3
Gui, Add, Button, x+0 yp wp hp gKlick, 4
Gui, Add, Button, x+0 yp wp hp gKlick, 5
Gui, Add, Button, xm wp hp gKlick, 6
Gui, Add, Button, x+0 yp wp hp gKlick, 7
Gui, Add, Button, x+0 yp wp hp gKlick, 8
Gui, Add, Button, x+0 yp wp hp gKlick, 9
Gui, Add, Button, x+0 yp wp hp gKlick, 10
Gui, Show, AutoSize Hide, %TITEL%
Gui, +LastFound

; Initialisieren    Transparenz  x-Position       y-Position
;                   |            |                |
DAG("INIT",         120,         A_ScreenWidth/2, 0 )

; Einblenden
DAG("EINBLENDEN")

; Eine Sekunde anzeigen
Sleep, 1000

; Und einklappen
DAG("EINKLAPPEN")
Return


; ------------------------------------------------------------------------------
GuiClose:
GuiEscape:
ExitApp
; ------------------------------------------------------------------------------
Klick:
   Gui, +OwnDialogs
   MsgBox, 0, Button, % "Button " . A_GuiControl . " wurde geklickt!", 1
Return
; ------------------------------------------------------------------------------
MausRaus:
  DAG("MAUSRAUS")
Return
; ------------------------------------------------------------------------------
MouseDrin:
  DAG("MAUSDRIN")
Return

; -----------------------------------------------------------------------------------
; DAG() DenicksAnimatedGui
;
; Animiert ein GUI
;
; DAG("SubCommand" [, p1=0, p2=0, p3=0])
;
; Parameter:
;
;   SubCommand  "INIT"        Initialisiert Vorgaben und Fensterkoordinaten
;               "EINBLENDEN"  Blendet das Fenster ein, beachtet dabei Fenstergrenzen
;               "AUSKLAPPEN"  Klappt das Fenster langsam aus
;               "EINKLAPPEN"  Klappt das Fenster langsam ein
;               "MAUSRAUS"    Sorgt dafür, daß das Fenster automatisch eingeklappt wird,
;                             wenn sich die Maus außerhalb des Fenster befindet.
;               "MAUSDRIN"    Sorgt dafür, daß das Fenster automatisch ausgeklappt wird,
;                             wenn sich die Maus innerhalb des Fenster befindet und
;                             die linkle Maustaste nicht gedrückt ist.
;
;   p1          bei SubCommand "INIT": Transparenz
;
;   p2          bei SubCommand "INIT": x-Position des Fensters
;
;   p3          bei SubCommand "INIT": y-Position des Fensters
;
DAG(SubCommand, p1=0, p2=0, p3=0)
{
  Static CH, BY, TR
       , ZMax=3     ; Vorgabe für Timerdurchläufe MausDrin/MausRaus bis zur Reaktion
       , DY=1       ; Vorgabe für Schrittweite beim Ein-/Ausklappen
       , HMin, ID, GuiID, WMax, HMax, H, Z, X, Y

  If (SubCommand == "INIT") {
    ; Pause zwischen Win-Anweisungen minimieren
    SetWinDelay, 0
    ; Höhe einer niedrigen Titelzeile (ToolWindow)
    SysGet, CH, 51
    ; Höhe eines normalen Rahmens
    Sysget, BY, 8

    ; Vorgabe für Transparenz
    TR := p1
   
    ; Fenster-Koordinaten
    X  := p2
    Y  := p3

    ; Aktives Fenster sichern
    WinGet, ID, ID, A
    ; Voreinstellungen für animiertes GUI
    Gui, -SysMenu +AlwaysOnTop +ToolWindow
    Gui, Margin, 0, 0
   
    ; ID der Gui merken
    GuiID := WinExist()
    ; Breite und maximale (aktuelle) Höhe bestimmen
    WinGetPos, , , WMax, HMax

    ; Minimale Höhe := Titelzeile + unterer Rand
    HMin := CH + BY
    }

  If (SubCommand == "EINBLENDEN") {
    Gui, Show, w0 h0

    ; Minimale X-Position
    XMin := 0

    ; Delta für Breite
    DW := DY * 2
    ; Grundstellung W und H
    W := H := 0
    Loop {
       W := (W + DW) <= WMax ? W + DW : WMax
       H := (H + DY) <= HMax ? H + DY : HMax
       X := (X - DY) >= XMin ? X - DY : XMin
       WinMove, ahk_id %GuiID%, , X, Y, W, H

       ; Wenn maximale Breite und Höhe erreicht sind: Tschüss!
       If (W = WMax And H = HMax) {
          Break
       }
    }
    Return
    }

  If (SubCommand == "AUSKLAPPEN") {
   ; Ausgangshöhe setzen
   H := HMin
   ; Tranparenz ausschalten
   WinSet, Transparent, Off, ahk_id %GuiID%
   ; Ausklappen
   Loop {
      ; Höhe + Schrittweite
      H += DY
      ; Wenn die maximale Höhe erreicht ist: maximale Höhe setzen und Tschüss!
      If (H > HMax) {
         WinMove, ahk_id %GuiID% , , , , , HMax
         Break
      }
      ; Fensterhöhe vergrößern
      WinMove, ahk_id %GuiID% , , , , , H
   }
   ; Timerzähler auf Null
   Z := 0
   ; Mausüberwachung "außerhalb" einschalten
   SetTimer, MausRaus, On
    Return
    }

  If (SubCommand == "EINKLAPPEN") {
   ; Ausgangshöhe setzen
   H := HMax
   ; Einklappen
   Loop {
      ; Höhe - Schrittweite
      H -= DY
      ; Wenn die minimale Höhe erreicht ist: minimale Höhe setzen und Tschüss!
      If (H < HMin) {
         WinMove, ahk_id %GuiID% , , , , , HMin
         Break
      }
      ; Fensterhöhe verringern
      WinMove, ahk_id %GuiID% , , , , , H
   }
   ; Transparenz einschalten
   WinSet, Transparent, %TR%, ahk_id %GuiID%
   ; Timerzähler auf Null
   Z := 0
   ; Mausüberwachung "innerhalb" einschalten
   SetTimer, MouseDrin, On
   ; Gesichertes Fenster aktivieren
   WinActivate, ahk_id %id%
   Return
   }

  If (SubCommand == "MAUSRAUS") {
   ; Maus außerhalb des Fensters ?
   MouseGetPos, , , ID
   If (ID = GuiID) {
      Z := 0
   } Else {
      Z++
   }
   If (Z < ZMax) {
      Return
   }
   SetTimer, MausRaus, Off
   DAG("EINKLAPPEN")
   }

  Else If (SubCommand == "MAUSDRIN") {
   ; Bei gedrückter linker Maustaste nichts tun
   If (GetKeyState("LButton", "P")) {
      Z := 0
      Return
   }
   ; Maus innerhalb des Fensters ?
   MouseGetPos, , , ID
   If (ID = GuiID) {
      Z++
   } Else {
      Z := 0
   }
   If (Z < ZMax) {
      Return
   }
   SetTimer, MouseDrin, Off
   DAG("AUSKLAPPEN")
   }

}
Edit: Funktionskommentar korrigiert
__________________________________________
Created with BBCodeWriter 7.0 - the one and only Very Happy


Zuletzt bearbeitet von Chucky am Fr März 21, 2008 4:19 pm, insgesamt 2-mal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
denick



Anmeldedatum: 15.09.2006
Beiträge: 947
Wohnort: Berlin

BeitragVerfasst am: Fr März 21, 2008 2:36 pm    Titel: Antworten mit Zitat

Moin Chucky,

gute Idee. Ich würde allerdings die Timer mit einem sprechenden Präfix einfach innerhalb der Funktion definieren. XMin sollte relativ zur Anzeigeposition sein, damit die Gui bei ungünstigen Seitenverhältnissen nicht aus dem Zentrum wandert. Ein paar weitere Kleinigkeiten finde ich innerhalb der Funktion nicht gut aufgehoben.

Deshalb hier mein erster Gegenentwurf:

Code:
#NoEnv

; Fenstertitel
TITEL := "     Mein Klappfenster"

; Aktives Fenster sichern
WinGet, ID, ID, A

; Gui aufbauen
Gui, -SysMenu +AlwaysOnTop +ToolWindow
Gui, Margin, 0, 0
Gui, Add, Button, w50 h50 gKlick, 1
Gui, Add, Button, x+0 yp wp hp gKlick, 2
Gui, Add, Button, x+0 yp wp hp gKlick, 3
Gui, Add, Button, x+0 yp wp hp gKlick, 4
Gui, Add, Button, x+0 yp wp hp gKlick, 5
Gui, Add, Button, xm wp hp gKlick, 6
Gui, Add, Button, x+0 yp wp hp gKlick, 7
Gui, Add, Button, x+0 yp wp hp gKlick, 8
Gui, Add, Button, x+0 yp wp hp gKlick, 9
Gui, Add, Button, x+0 yp wp hp gKlick, 10
Gui, Show, AutoSize Hide, %TITEL%
Gui, +LastFound

; Initialisieren    Transparenz  x-Position       y-Position
;                   |            |                |
DAG("INIT",         120,         A_ScreenWidth/2, 0 )

; Einblenden
DAG("EINBLENDEN")

; Eine Sekunde anzeigen
Sleep, 1000

; Und einklappen
DAG("EINKLAPPEN")

; Gesichertes Fenster aktivieren
WinActivate, ahk_id %ID%
Return

; ------------------------------------------------------------------------------
GuiClose:
GuiEscape:
ExitApp

; ------------------------------------------------------------------------------
Klick:
   Gui, +OwnDialogs
   MsgBox, 0, Button, % "Button " . A_GuiControl . " wurde geklickt!", 1
Return

; -----------------------------------------------------------------------------------
; DAG() DenicksAnimatedGui
;
; Animiert ein GUI
;
; DAG("SubCommand" [, p1=0, p2=0, p3=0])
;
; Parameter:
;
;   SubCommand  "INIT"        Initialisiert Vorgaben und Fensterkoordinaten
;               "EINBLENDEN"  Blendet das Fenster ein, beachtet dabei Fenstergrenzen
;               "AUSKLAPPEN"  Klappt das Fenster langsam aus
;               "EINKLAPPEN"  Klappt das Fenster langsam ein
;
;   p1          bei SubCommand "INIT": Transparenz
;
;   p2          bei SubCommand "INIT": x-Position des Fensters
;
;   p2          bei SubCommand "INIT": y-Position des Fensters
;
DAG(SubCommand, p1=0, p2=0, p3=0)
{
   Static CH, BY, TR
       , ZMax=3     ; Vorgabe für Timerdurchläufe MausDrin/MausRaus bis zur Reaktion
       , DY=1       ; Vorgabe für Schrittweite beim Ein-/Ausklappen
       , HMin, ID, GuiID, WMax, HMax, H, Z, X, Y
   ; ---------------------------------------------------------------------------
   If (SubCommand == "INIT") {
      ; Pause zwischen Win-Anweisungen minimieren
      SetWinDelay, 0
      ; Höhe einer niedrigen Titelzeile (ToolWindow)
      SysGet, CH, 51
      ; Höhe eines normalen Rahmens
      Sysget, BY, 8
      ; Vorgabe für Transparenz
      TR := p1
      ; Fenster-Koordinaten
      X  := p2
      Y  := p3
      ; ID der Gui merken
      GuiID := WinExist()
      ; Breite und maximale (aktuelle) Höhe bestimmen
      WinGetPos, , , WMax, HMax
      ; Minimale Höhe := Titelzeile + unterer Rand
      HMin := CH + BY
      Return
   }
   ; ---------------------------------------------------------------------------
   If (SubCommand == "EINBLENDEN") {
      Gui, Show, w0 h0
      ; Minimale X-Position
      XMin := X - (WMax // 2)
      ; Delta für Breite
      DW := DY * 2
      ; Grundstellung W und H
      W := H := 0
      Loop {
         W := (W + DW) <= WMax ? W + DW : WMax
         H := (H + DY) <= HMax ? H + DY : HMax
         X := (X - DY) >= XMin ? X - DY : XMin
         WinMove, ahk_id %GuiID%, , X, Y, W, H
         ; Wenn maximale Breite und Höhe erreicht sind: Tschüss!
         If (W = WMax And H = HMax) {
            Break
         }
      }
      Return
   }
   ; ---------------------------------------------------------------------------
   If (SubCommand == "AUSKLAPPEN") {
      ; Ausgangshöhe setzen
      H := HMin
      ; Tranparenz ausschalten
      WinSet, Transparent, Off, ahk_id %GuiID%
      ; Ausklappen
      Loop {
         ; Höhe + Schrittweite
         H += DY
         ; Wenn die maximale Höhe erreicht ist: maximale Höhe setzen und Tschüss!
         If (H > HMax) {
            WinMove, ahk_id %GuiID% , , , , , HMax
            Break
         }
         ; Fensterhöhe vergrößern
         WinMove, ahk_id %GuiID% , , , , , H
      }
      ; Timerzähler auf Null
      Z := 0
      ; Mausüberwachung "außerhalb" einschalten
      SetTimer, DAG_MausRaus, On
      Return
   }
   ; ---------------------------------------------------------------------------
   If (SubCommand == "EINKLAPPEN") {
      ; Ausgangshöhe setzen
      H := HMax
      ; Einklappen
      Loop {
         ; Höhe - Schrittweite
         H -= DY
         ; Wenn die minimale Höhe erreicht ist: minimale Höhe setzen und Tschüss!
         If (H < HMin) {
            WinMove, ahk_id %GuiID% , , , , , HMin
            Break
         }
         ; Fensterhöhe verringern
         WinMove, ahk_id %GuiID% , , , , , H
      }
      ; Transparenz einschalten
      WinSet, Transparent, %TR%, ahk_id %GuiID%
      ; Timerzähler auf Null
      Z := 0
      ; Mausüberwachung "innerhalb" einschalten
      SetTimer, DAG_MAUSDRIN, On
      ; Gesichertes Fenster aktivieren
      WinActivate, ahk_id %id%
      Return
   }
   ; ---------------------------------------------------------------------------
   DAG_MAUSRAUS:
      ; Maus außerhalb des Fensters?
      MouseGetPos, , , ID
      If (ID = GuiID) {
         Z := 0
      } Else {
         Z++
      }
      If (Z < ZMax) {
         Return
      }
      SetTimer, DAG_MAUSRAUS, Off
      DAG("EINKLAPPEN")
   Return
   ; ---------------------------------------------------------------------------
   DAG_MAUSDRIN:
      ; Bei gedrückter linker Maustaste nichts tun
      If (GetKeyState("LButton", "P")) {
         Z := 0
         Return
      }
      ; Maus innerhalb des Fensters?
      MouseGetPos, , , ID
      If (ID = GuiID) {
         Z++
      } Else {
         Z := 0
      }
      If (Z < ZMax) {
         Return
      }
      SetTimer, DAG_MAUSDRIN, Off
      DAG("AUSKLAPPEN")
   Return
}

Allerdings hat mich Deine Funktion noch auf allerhand Ideen für Erweiterungen gebracht! Wink
_________________
Hilfe zur Hilfe

(de)nick
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Chucky



Anmeldedatum: 07.01.2006
Beiträge: 576
Wohnort: Powerland

BeitragVerfasst am: Fr März 21, 2008 4:21 pm    Titel: Antworten mit Zitat

denick hat Folgendes geschrieben:
Ich würde allerdings die Timer mit einem sprechenden Präfix einfach innerhalb der Funktion definieren.
Das sowas geht, wußte ich noch nicht, gerade habe ich es in der Doku gefunden. Gut zu wissen, eine Möglichkeit mehr, Funktionen als Container für alles Mögliche zu mißbrauchen. Wink
Zitat:
Ein paar weitere Kleinigkeiten finde ich innerhalb der Funktion nicht gut aufgehoben.

Ich habe dabei folgende Anwendung im Kopf: Man baut sich Script mit einem Standard-GUI zusammen. Wenn alles funktioniert und man denn ein animiertes Gui haben will, wechselt man einfach 2 - 3 AHK-Gui-Befehle mit ihren DAG-Pendants aus und fertig ist das animierte GUI.
Und damit man sich nicht um dafür notwendige neue Variablen kümmern muß, können diese ruhig "unsichtbar" bleiben, nämlich als statische Variablen innerhalb der Funktion, z. B. abrufbar mit 'DAG("GETID")'.
Das sind aber eher Implementierungsfragen.

Vor die erste Timer-Routine sollte ein Return gesetzt werden, damit sie nicht bei einem unbekannten SubCommand aufgerufen wird. Und: im Funktionskopf muß
Code:
;   p3          bei SubCommand "INIT": y-Position des Fensters
stehen (mein Fehler, in meinem Posting habe ich's korrigiert).
__________________________________________
Created with BBCodeWriter 7.0 - the one and only Very Happy
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
denick



Anmeldedatum: 15.09.2006
Beiträge: 947
Wohnort: Berlin

BeitragVerfasst am: So März 23, 2008 11:57 am    Titel: Antworten mit Zitat

Moin Chucky,

ich habe oben eine Funktion eingestellt, wie ich sie mir vorstelle. Das "Einblenden" ist dabei auf der Strecke geblieben, weil es nicht wirklich dazugehört. Probier doch mal, ob sie Dir gefällt.
_________________
Hilfe zur Hilfe

(de)nick
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Chucky



Anmeldedatum: 07.01.2006
Beiträge: 576
Wohnort: Powerland

BeitragVerfasst am: So März 23, 2008 2:36 pm    Titel: Antworten mit Zitat

denick hat Folgendes geschrieben:
Probier doch mal, ob sie Dir gefällt.
Boah ey, aber hallo, noch besser als erwartet! ShockedCool

Eine einzige Funktion, sparsam aufgerufen, mit der Verwaltung mehrerer GUIs, Du hast ja an alles gedacht! Hat so ziemlich alle Eigenschaften eines Add-ons für AutoHotkey! (und auf meinem PC einen festen Platz Smile )

Wie ich gesehen habe, nutzt Du auch lokale Subroutinen, die im Gegensatz zu den Timer-Routinen von außen unsichtbar sind - ein Vorteil. Generell gewinne ich dieser Art von Implementation per allumfassender Funktion immer mehr ab:
  • Eine Funktion kann sich selber "Gedanken" um eventuelle Voreinstellungen, (De-)Initialisierungen, Speicherverwaltung usw. machen und belastet nicht den Programmierer damit. Das ist ja sowieso ein grundsätzliches AutoHotkey-Prinzip. Wink
  • Um eine Funktionalität (so etwas wie Dein DropDown-GUI) einzubauen, sind kaum Änderungen am vorhandenen Quelltext nötig.
  • Es gibt praktisch keine Namens-Konflikte mit schon vorhandenem Code.
  • Umgekehrt kann man die Funktionalität auch leicht wieder entfernen, ohne daß der Rest des Scripts zusammenbricht.
  • Last but not least: Die Dokumentation/Kommentierung ist zielgenauer, und zwar intern (innerhalb der Funktion geht es wirklich nur um die Funktion) und extern (weil man die Implementation anhand der Funktionsaufrufe leicht erkennen und kommentieren kann.)
__________________________________________
Created with BBCodeWriter 7.0 - the one and only Very Happy
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
denick



Anmeldedatum: 15.09.2006
Beiträge: 947
Wohnort: Berlin

BeitragVerfasst am: Di März 25, 2008 7:20 am    Titel: Antworten mit Zitat

Moin Chucky,

danke für die Blumen! Wink

Ich habe noch einen Bug beseitigt und die Fehlerbehandlung "professionalisiert" (s.o.).

Zitat:
Eine einzige Funktion, sparsam aufgerufen, mit der Verwaltung mehrerer GUIs, Du hast ja an alles gedacht!
Soweit ist es noch nicht ganz. Mehrere Gui's können bisher nicht zeitgeich verwaltet werden. Es wäre wohl möglich, ich hatte bei DropDown_GUI() aber eher spezielle Anwendungen im Sinn, die mit einem Fenster auskommen sollten.

Zitat:
Wie ich gesehen habe, nutzt Du auch lokale Subroutinen, die im Gegensatz zu den Timer-Routinen von außen unsichtbar sind - ein Vorteil.
Die funktionslokalen Subroutinen sind von außen durchaus sichtbar, nur nicht aufrufbar. Man muss ihnen funktionsbezogene und möglichts eindeutige Namen geben, um das Problem der "duplicate labels" zu minimieren.
_________________
Hilfe zur Hilfe

(de)nick
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    AutoHotkey Community Foren-Übersicht -> Skripte & Funktionen Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de