 |
AutoHotkey Community Wir helfen uns gegenseitig aus der Patsche
|
| Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
| Autor |
Nachricht |
denick
Anmeldedatum: 15.09.2006 Beiträge: 947 Wohnort: Berlin
|
Verfasst am: Fr März 21, 2008 9:28 am Titel: TechDemo: AnimateGui ohne AnimateWindow |
|
|
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 |
|
 |
BoBo¨ Gast
|
Verfasst am: Fr März 21, 2008 10:21 am Titel: |
|
|
G IL |
|
| Nach oben |
|
 |
IsNull
Anmeldedatum: 20.12.2006 Beiträge: 914 Wohnort: CH
|
|
| Nach oben |
|
 |
Chucky
Anmeldedatum: 07.01.2006 Beiträge: 576 Wohnort: Powerland
|
Verfasst am: Fr März 21, 2008 1:15 pm Titel: Re: TechDemo: AnimateGui ohne AnimateWindow |
|
|
Hi denick,
super ! 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 
Zuletzt bearbeitet von Chucky am Fr März 21, 2008 4:19 pm, insgesamt 2-mal bearbeitet |
|
| Nach oben |
|
 |
denick
Anmeldedatum: 15.09.2006 Beiträge: 947 Wohnort: Berlin
|
Verfasst am: Fr März 21, 2008 2:36 pm Titel: |
|
|
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!  _________________ Hilfe zur Hilfe
(de)nick |
|
| Nach oben |
|
 |
Chucky
Anmeldedatum: 07.01.2006 Beiträge: 576 Wohnort: Powerland
|
Verfasst am: Fr März 21, 2008 4:21 pm Titel: |
|
|
| 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.  | 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  |
|
| Nach oben |
|
 |
denick
Anmeldedatum: 15.09.2006 Beiträge: 947 Wohnort: Berlin
|
Verfasst am: So März 23, 2008 11:57 am Titel: |
|
|
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 |
|
 |
Chucky
Anmeldedatum: 07.01.2006 Beiträge: 576 Wohnort: Powerland
|
Verfasst am: So März 23, 2008 2:36 pm Titel: |
|
|
| denick hat Folgendes geschrieben: | | Probier doch mal, ob sie Dir gefällt. | Boah ey, aber hallo, noch besser als erwartet! 
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 )
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.
 - 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  |
|
| Nach oben |
|
 |
denick
Anmeldedatum: 15.09.2006 Beiträge: 947 Wohnort: Berlin
|
Verfasst am: Di März 25, 2008 7:20 am Titel: |
|
|
Moin Chucky,
danke für die Blumen!
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 |
|
 |
|
|
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
|