Seite 1 von 1

Rahmenloses Fenster mit eigenem Skin ohne Region (WinAPI)

Verfasst: 29.04.2010 23:41
von Kurzer
Hallo zusammen,

bei der Suche nach einer Lösung zu einem geskinnten PB-Fenster habe ich nur Beispiele gefunden, die mit der Region-Funktion der WinAPI Fensterbereiche durchsichtig gemacht haben.

Hier meine Lösung, die dem PB-Fenster ein eigenes Hintergrundbild verpasst und mittels Colorkey bestimmte Bereiche transparent schaltet. Im Beispiel alles, was die RGB-Farbe $FF00FF aufweist. Dort wirkt dann auch die Maus auf den drunterliegenden Bereich. Also so, wie man sich das i.d.R. wünscht.

Hier der code dazu:

Code: Alles auswählen

EnableExplicit

Global iEvent.i, iEventGadget.i
Global iQuit.i, iImage.i, iPatternBrush.i
Global iMainWindow.i, iButton.i

iMainWindow = OpenWindow(#PB_Any, 100, 100, 105, 195, "", #PB_Window_BorderLess)

If iMainWindow
  iButton = ButtonGadget(#PB_Any, 38, 70, 35, 20, "Quit")

	; Den Patternbrush für den Fensterhintergrund aus dem Image erzeugen
	iImage = LoadImage(#PB_Any, "D:\Image.bmp")
	iPatternBrush = CreatePatternBrush_(ImageID(iImage))
	; Den Patternbrush als Fensterhintergrund zuordnen.
	SetClassLongPtr_(WindowID(iMainWindow), #GCL_HBRBACKGROUND, iPatternBrush)
	; Das Image brauchen wir jetzt nicht mehr
	FreeImage(iImage)
	
	; Jetzt das Fenster an allen Stellen mit Farbe $FF00FF durchsichtig machen (#LWA_COLORKEY)
	SetWindowLongPtr_(WindowID(iMainWindow), #GWL_EXSTYLE, #WS_EX_LAYERED)
	SetLayeredWindowAttributes_(WindowID(iMainWindow), $FF00FF, 1, #LWA_COLORKEY)

  Repeat
    iEvent = WaitWindowEvent()
	  iEventGadget = EventGadget()

	  Select iEvent
	  Case #PB_Event_Gadget
	    Select iEventGadget
	      Case iButton : iQuit = 1
	    EndSelect
	
	  Case #WM_LBUTTONDOWN 
	  	Debug "In das Window geklickt!"
	  	SendMessage_(WindowID(iMainWindow), #WM_NCLBUTTONDOWN, #HTCAPTION, 0) 
	  EndSelect

  Until iQuit = 1
  
	If iPatternBrush
		DeleteObject_(iPatternBrush)
	EndIf

	CloseWindow(iMainWindow)

EndIf
Und hier das BIld, welches nachgeladen wird:
Bild


Das ganze sieht dann so aus:
Bild

Viele Spaß damit.

PS: Wie man auch den Button skinnen kann, habe ich leider nicht rausbekommen.
ImageButton hab ich noch nicht getestet.
Verbesserungen sind herzlich willkommen.

PS2: Durch Verarbeiten der #WM_LBUTTONDOWN Message kann das Fenster an beliebiger Stelle angefasst und verschoben werden.

Re: Rahmenloses Fenster mit eigenem Skin ohne Region (WinAPI

Verfasst: 29.04.2010 23:49
von Kaeru Gaman
für einen geskinten Button verwendet man dann keinen normalen Button, sondern etwas OwnerDrawn oder simpel ein ImageGadget mit einer Click-Auswertung. ;)
du brauchst keinen "echten" Button, um ein anklickbares Fensterelement zu haben.

Re: Rahmenloses Fenster mit eigenem Skin ohne Region (WinAPI

Verfasst: 29.04.2010 23:54
von Kurzer
Jo, aber beim Imagegadget fehlt mir der "Reindrück-Effekt", der bei einem Button exisitert.
Kann man aber sicherlich nachempfinden?

Bei einem echten Button kannst Du es Dir mit dem Drücken ja auch nochmal überlegen, solange Du den Mausknopf noch nicht wieder losgelassen hast.

Ich hab es mit einem Image noch nicht ausgiebig gestestet (war wieder so ein Mittagspausenhack).

Re: Rahmenloses Fenster mit eigenem Skin ohne Region (WinAPI

Verfasst: 30.04.2010 00:01
von ts-soft
Wundert mich jetzt aber, das hier noch keine Beispiele mit Layered Windows waren. Im engl. Forum gibts
da wohl ein paar.

Die Codes mit Region stammen ja größtenteils aus Zeiten, wo man auf ältere Windows Versionen noch
Rücksicht nahm :wink:

PS: Du solltest Dir angewöhnen SetClassLongPtr_, GetWindowLongPtr_ usw. zu nutzen, dann brauchste beim portieren auf x64 nicht mehr ändern!

Schönes Beispiel :allright:

Gruß
Thomas

Re: Rahmenloses Fenster mit eigenem Skin ohne Region (WinAPI

Verfasst: 30.04.2010 19:08
von Kurzer
Jo, danke für die Hinweise, Thomas.

Ich muß dazu sagen, daß ich nicht permanent mit PB oder Prorammierung zu tun habe. Das hat unterschiedliche Gründe.

Fakt ist aber, daß sich daher auch nur schwer ein kontinuierlicher Lerneffekt durch wiederholtes Anwenden einstellt - ähm, was vielleicht dem ein oder anderen erklärt, warum ich ab und zu im Anfängerforum poste. <)

Wenn mal wieder ein PB-Projekt ansteht und ich nicht weiterkomme, dann kratze ich mir meist die Infos aus Beispielen und dem Forum zusammen. Aber gerade im Bereich WinAPI kann ich deshalb fehlerhaften oder veralteten code nicht immer als solchen erkennen.

Was ich sagen will: Ich bin dankbar, wenn Beispiele mit Verbesserungen kommentiert werden, so wie ts-soft das in senem Beitrag getan hat.
Zu dem Fenster-Layerzeug habe ich sicherlich einen Teil auch aus dem Forum erfahren, aber eben nicht als komplettes Beispiel. Daß man den Patternbrush z.B. später wieder mit DeleteObjekt_() freigeben muß, war in keinem der Beispiele zu sehen - das habe ich aus der MSDN erfahren.

Das Beispiel oben habe ich jetzt angepaßt bzgl. SetWindowLongPtr_

Gruß vom Frosch (bzw. Markus, falls es jemand famliärer mag :wink:)