Seite 1 von 1
Fenster überlappend einsetzen
Verfasst: 21.07.2012 20:36
von Lambda
Habe diesen Effekt professorisch schon erreicht. Ein rahmenloses+leicht transparentes Fenster wird in ein normales Fenster mit Rand eingesetzt.
Mit SetParent_() geht es nur leider nicht da das Fenster sich dann unterhalb aller Steuerelmente befindet. Meine professorische Lösung bewegt/dimensioniert das Fenster nach seinem Parent. Wenn jetzt aber ein (z.B) Explorer(Ordner) Fenster überlapt und ich das transparente Fenster aktiviert, befindet sich das Explorer Fenster natürlich zwischen Parent und dem transparentem Fenster.
Wie setze ich nun das transparente Fenster in das andere ein, sodass es innerhalb dieses Fensters immer im Vordergrund bleibt? Sehr geschickt wäre noch, wenn das transparente Fenster dann auch nicht dem Parent den Fokus klauen würde.
Re: Fenster überlappend einsetzen
Verfasst: 21.07.2012 21:50
von HeX0R
Du meinst nicht zufällig "provisorisch"?
Nicht, dass ich jetzt den Oberlehrer spielen will (Gott bewahre), aber ich hab echt ne Weile gebraucht, um dahinter zu kommen, was du mit professorisch meinen könntest.
...um aber auf dein eigentliches Problem zu kommen:
Das ist alles recht verwirrend erklärt, einfacher wäre es, du zeigst mal ein Codebeispiel.
Re: Fenster überlappend einsetzen
Verfasst: 21.07.2012 22:42
von Lambda
Äh, ja klar, provisorisch meinte ich. ^^
Der selbe Effekt tritt z.B auf wenn ein Fenster (Vista/7) einfriert.. dann wird das innere zum Teil weiß ausgeblendet. Genau das will ich erreichen und auf dieser halb-druchsichtigen Fläche Steuerelemente setzen.
Re: Fenster überlappend einsetzen
Verfasst: 22.07.2012 03:51
von Regenduft
Meinst Du sowas? Hab' ich mal aus einem Projekt gezogen und "runterreduziert", könnte evtl. buggy sein. Außerdem "hinkt" das Fenster hinterher, da ich keinen Callback verwendet habe.
Code: Alles auswählen
; Regenduft 22.07.2012 - http://forums.purebasic.com/german/viewtopic.php?p=303827#p303827
EnableExplicit
;xFF = GetSystemMetrics_(#SM_CXFIXEDFRAME) ; Rahmenbreite bei Fenster OHNE Sizegadget
;yFF = GetSystemMetrics_(#SM_CYFIXEDFRAME) ; Rahmenhöhe bei Fenster OHNE Sizegadget
Global xSF = GetSystemMetrics_(#SM_CXSIZEFRAME) ; Rahmenbreite bei Fenster MIT Sizegadget
Global ySF = GetSystemMetrics_(#SM_CYSIZEFRAME) ; Rahmenhöhe bei Fenster MIT Sizegadget
Global yC = GetSystemMetrics_(#SM_CYCAPTION) ; Höhe der Titelzeile (OHNE Rahmenhöhe)
#WIN_Parent = 0 : #WIN_Child = 1
Procedure.i AntagonistResize(EvntWin)
Select EvntWin
Case #WIN_Parent, #WIN_Child
Protected WxP = WindowX (#WIN_Parent)
Protected WyP = WindowY (#WIN_Parent)
Protected WwP = WindowWidth (#WIN_Parent)
Protected WhP = WindowHeight(#WIN_Parent)
Protected WxC = WindowX( #WIN_Child)
Protected WyC = WindowY( #WIN_Child)
Protected WwC = WindowWidth( #WIN_Child)
Protected WhC = WindowHeight(#WIN_Child)
; << WICHTIG >> Nur Fenstergröße ändern, wenn tatsächlich
; nötig, da sonst eine "Endlos-Resize-Schleife" entsteht!
Select EvntWin
Case #WIN_Parent
If WxC<>WxP+xSF : WxC=WxP+xSF : Else : WxC=#PB_Ignore : EndIf
If WyC<>WyP+ySF+yC : WyC=WyP+ySF+yC : Else : WyC=#PB_Ignore : EndIf
If WwC<>WwP : WwC=WwP : Else : WwC=#PB_Ignore : EndIf
If WhC<>WhP : WhC=WhP : Else : WhC=#PB_Ignore : EndIf
ResizeWindow(#WIN_Child,WxC,WyC,WwC,WhC)
ProcedureReturn #WIN_Child
Case #WIN_Child
If WxP<>WxC-xSF : WxP=WxC-xSF : Else : WxP=#PB_Ignore : EndIf
If WyP<>WyC-ySF-yC : WyP=WyC-ySF-yC : Else : WyP=#PB_Ignore : EndIf
If WwP<>WwC : WwP=WwC : Else : WwP=#PB_Ignore : EndIf
If WhP<>WhC : WhP=WhC : Else : WhP=#PB_Ignore : EndIf
ResizeWindow(#WIN_Parent,WxP,WyP,WwP,WhP)
ProcedureReturn #WIN_Parent
EndSelect
EndSelect
ProcedureReturn -1
EndProcedure
Procedure.i Antagonist(Win)
Select Win
Case #WIN_Parent : ProcedureReturn #WIN_Child
Case #WIN_Child : ProcedureReturn #WIN_Parent
Default : ProcedureReturn -1
EndSelect
EndProcedure
Procedure.i SetWindowTransparency(WindowID, AlphaValue.l, TransparentColor.l, Flags=#LWA_ALPHA|#LWA_COLORKEY)
Static Init
If Init=0 And GetWindowLongPtr_(WindowID,#GWL_EXSTYLE)<>#WS_EX_LAYERED
Init=-1 : SetLastError_(0)
If SetWindowLongPtr_(WindowID,#GWL_EXSTYLE,#WS_EX_LAYERED)=0 And GetLastError_()
Init=0 : ProcedureReturn #False
EndIf
EndIf
ProcedureReturn SetLayeredWindowAttributes_(WindowID, TransparentColor, AlphaValue, Flags)
EndProcedure
Macro SetWindowState2(Window, State)
If GetWindowState(Window) <> State : SetWindowState(Window, State) : EndIf
EndMacro
OpenWindow(#WIN_Parent,0,0,300,200,"Parent",#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget)
OpenWindow(#WIN_Child,WindowX(#WIN_Parent)+xSF,WindowY(#WIN_Parent)+yC+ySF,WindowWidth(#WIN_Parent),WindowHeight(#WIN_Parent),"Child",#PB_Window_BorderLess,WindowID(#WIN_Parent))
SetWindowColor(#WIN_Parent,$0000FF) ; Rot
SetWindowColor(#WIN_Child ,$FF0000) ; Blau
SetWindowTransparency(WindowID(#WIN_Child),128,0,#LWA_ALPHA) ; Rot + Blau = Lila
DisableWindow(#WIN_Child,1)
Define EvntWin
Repeat
Select WaitWindowEvent()
Case #PB_Event_MaximizeWindow
Debug "#PB_Event_MaximizeWindow"
Select EventWindow()
Case #WIN_Parent
AntagonistResize(#WIN_Parent)
Case #WIN_Child
If GetWindowState(#WIN_Parent) <> #PB_Window_Maximize
SetWindowState(#WIN_Parent, #PB_Window_Maximize)
EndIf
EndSelect
Case #PB_Event_MinimizeWindow
Debug "#PB_Event_MinimizeWindow"
EvntWin = Antagonist(EventWindow())
If EvntWin >= 0 And GetWindowState(EvntWin) <> #PB_Window_Minimize
SetWindowState(EvntWin, #PB_Window_Minimize)
EndIf
Case #PB_Event_RestoreWindow
Debug "#PB_Event_RestoreWindow"
EvntWin = Antagonist(EventWindow())
If EvntWin >= 0
SetWindowState2(EvntWin,#PB_Window_Normal)
AntagonistResize(EvntWin)
EndIf
Case #PB_Event_MoveWindow, #PB_Event_SizeWindow
Debug "#PB_Event_MoveWindow, #PB_Event_SizeWindow"
AntagonistResize(EventWindow())
Case #PB_Event_CloseWindow
End
EndSelect
ForEver
Re: Fenster überlappend einsetzen
Verfasst: 22.07.2012 12:43
von Lambda
Das trifft es sehr genau

wobei das verschieben hier fehlt, aber da sieht man wie das ganze gelöst ist.
Und es löst gleichzeitig das Problmem mit der anderen Fenstern die zwischen den beiden rutschen konnten.
Wäre nur noch die Frage ob man es nicht noch einen kleinen tick schöner lösen kann, indem das Fenster echt eingsetzt wird.
GELÖSCHT
Verfasst: 22.07.2012 13:45
von mirca
GELÖSCHT
Re: Fenster überlappend einsetzen
Verfasst: 22.07.2012 21:45
von Regenduft
mirca hat geschrieben:cOoki3druqs: Was ist das Ziel deiner halb-druchsichtigen Fläche ? Was willst du damit ereichen oder anders gesagt wofür brauchst du so was?
Also ich kann zwar nicht für cOoki3druqs sprechen, aber ich hatte damit vor ein "alternatives"
DisableWindow() zu erstellen, da ich es extrem nervig finde, dass man nach einem "echten"
DisableWindow() das Fenster nichtmehr verschieben, bzw. minimieren und maximieren oder "wiederherstellen" kann. Es ist immer im Weg und bei einem Klick macht es nur "Biiing!".
Außerdem kann man (z.B.) ein
ProgressBarGadget() draufsetzen, damit der Benutzer weiß, wie lange er noch warten muss, bis die Eingabe wieder freigegeben ist. Die "rot+blau=lila" Farbgebung in meinem Code ist nur für Debuggingzwecke.
cOoki3druqs hat geschrieben:(1.) wobei das verschieben hier fehlt
(2.) Wäre nur noch die Frage ob man es nicht noch einen kleinen tick schöner lösen kann, indem das Fenster echt eingsetzt wird.
zu 1.: Bei mir funktioniert das Verschieben, nur dass das Child erst bei loslassen der Maustaste sozusagen "hinterherspringt". Mit einem Windowcallback sollte man das aber lösen können. Ich glaube Kiffi hatte da mal irgendwo einen schönen Code gepostet. (Generell wurden Callbacks schon öfters "durchgekaut".)
zu 2.: Das ging glaube ich irgendwie per API (evtl. mit
SetParent_()?), so dass das Child wie in einem
MDIGadget() direkt im Fenster sitzt (also nicht über den Rand geschoben werden kann).
Wäre schön, wenn Du später Deine Lösung posten könntest! Da wäre ich sehr daran interessiert, auch wenn das Projekt in dem ich es benötige z.Zt. auf dem virtuellen Abstellgleis geparkt ist.
Re: Fenster überlappend einsetzen
Verfasst: 23.07.2012 03:08
von Lambda
zu 1. Das hab ich bereits gelöst ^^
zu 2. SetParent_ alleine tuts natürlich nicht, da muss scheinbar noch eine Statusänderung etc stattfinden.. schreibe dir dann die Lösung
Warum soetwas? Na weil ich dadurch 1. eine erzwungene Oberfläche habe (z.B Passwort Eingage für Zugriff) und 2. weil es schick aussieht
Bild wieder entfernt