Transparentes Overlay Window mit Alpha

Für allgemeine Fragen zur Programmierung mit PureBasic.
Derren
Beiträge: 557
Registriert: 23.07.2011 02:08

Transparentes Overlay Window mit Alpha

Beitrag von Derren »

Hallo zusammen,

ich weiß, zu dem Thema gibt es einige Threads, aber irgendwie nicht das, was ich suche.

Ich such nach einer Möglichkeit, ein vollständig transparentes Fenster zu erstellen, auf dem ich dann aber immer noch zeichnen kann.
Die Windows API bietet mit folgendem Code (danke RSBasic's API-Library) eine relativ simple Möglichkeit entweder eine Farbe transparent/unsichtbar zu machen (wie früher bei Sprites), oder das komplette Fenster transparenter zu machen.

Code: Alles auswählen

If OpenWindow(0,0,0,500,250,"Window",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  SetWindowLongPtr_(WindowID(0),#GWL_EXSTYLE,GetWindowLongPtr_(WindowID(0),#GWL_EXSTYLE) | #WS_EX_LAYERED)
  SetLayeredWindowAttributes_(WindowID(0), 0, (255 * 50) / 100, #LWA_ALPHA)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Erinnert sich noch jemand an diesen "App Launcher" nenne ich es mal, der transparente "Kugeln" in einem Kreis angeordnet hat? Das war ein schönes, komplett unsichtbares Fenster, mit Grafiken mit verschiedenen Alphawerten. Ich finde diesen Thread leider nicht :(

Im Prinzip möchte ich so etwas basteln. Hat da vielleicht jemand einen Tipp?

Danke :)
Bild
Signatur und so
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Re: Transparentes Overlay Window mit Alpha

Beitrag von hjbremer »

Hi, so was ?

Code: Alles auswählen

If OpenWindow(0, 0, 0, 400, 200, "VectorDrawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CanvasGadget(0, 0, 0, 400, 200)
    
    LoadFont(0, "Times", 20, #PB_Font_Bold)
    LoadImage(0, #PB_Compiler_Home + "examples/Sources/Data/PureBasicLogo.bmp")

    If StartVectorDrawing(CanvasVectorOutput(0))
    
      MovePathCursor(00, 00)
      DrawVectorImage(ImageID(0), $FF, 400, 200)
      
      VectorFont(FontID(0), 25)
      VectorSourceColor($FF000000+#White)

      MovePathCursor(20, 10): DrawVectorText("Hurra")
      MovePathCursor(20, 50): DrawVectorText("Hallo")
      
    
      VectorFont(FontID(0), 35)
      VectorSourceColor($FF000000+#Red)

      MovePathCursor(220, 110): DrawVectorText("Hallo")
      MovePathCursor(220, 150): DrawVectorText("Hallo")
      
      VectorFont(FontID(0), 10)
      VectorSourceColor($FF000000+#Black)
      MovePathCursor(150, 20): DrawVectorParagraph("Hallo du bist ein Glückspilz", 100, 66, #PB_VectorParagraph_Center)
      
    
      StopVectorDrawing()
    EndIf
    
    Repeat
      Event = WaitWindowEvent()
    Until Event = #PB_Event_CloseWindow
  EndIf
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
chi
Beiträge: 90
Registriert: 17.05.2007 09:30
Wohnort: Linz - Austria

Re: Transparentes Overlay Window mit Alpha

Beitrag von chi »

quick & dirty

Code: Alles auswählen

BlendMode.BLENDFUNCTION
BlendMode\SourceConstantAlpha = 255
BlendMode\AlphaFormat = #AC_SRC_ALPHA

OpenWindow(0, 0, 0, 150, 50, "", #PB_Window_BorderLess|#PB_Window_ScreenCentered|#PB_Window_Invisible, GetShellWindow_())
SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_TRANSPARENT)
HideWindow(0, #False)
AddWindowTimer(0, 0, 1000)

Repeat
  event = WaitWindowEvent()
  Select event
    Case #PB_Event_Timer
      Select EventTimer()
          
        Case 0
          hWnd = WindowID(0)
          GetWindowRect_(hWnd, wRect.RECT)
          OffsetRect_(wRect, -wRect\left, -wRect\top)
          hdc = GetWindowDC_(hWnd)
          mdc = CreateCompatibleDC_(hdc)
          CreateImage(0, wRect\right, wRect\bottom, 32, #PB_Image_Transparent)
          StartDrawing(ImageOutput(0))
            DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Outlined)
            Box(0, 0, OutputWidth(), OutputHeight(), RGBA(0,0,255,100))
            DrawText(10, 10, FormatDate("%hh:%ii:%ss", Date()), RGBA(255,0,0,255), RGBA(0,0,0,0))
            x + 1
            DrawText(10, 30, "Hello World" + LSet("", x % 4, "."), RGBA(255,0,0,255), RGBA(0,0,0,0))
          StopDrawing()
          old = SelectObject_(mdc, ImageID(0))
          UpdateLayeredWindow_(hWnd, 0, 0, @wRect+8, mdc, @ContextOffset.POINT, 0, @BlendMode, #ULW_ALPHA)
          SelectObject_(mdc, old)
          DeleteDC_(mdc)
          ReleaseDC_(hWnd, hdc)
          
      EndSelect
  EndSelect
Until event = #PB_Event_CloseWindow Or GetAsyncKeyState_(#VK_ESCAPE) & 1
[/size]
Derren
Beiträge: 557
Registriert: 23.07.2011 02:08

Re: Transparentes Overlay Window mit Alpha

Beitrag von Derren »

@chi: Oh, vielen Dank, ich glaube damit kann ich was anfangen :praise: :allright:
Signatur und so
Benutzeravatar
chi
Beiträge: 90
Registriert: 17.05.2007 09:30
Wohnort: Linz - Austria

Re: Transparentes Overlay Window mit Alpha

Beitrag von chi »

Derren hat geschrieben:@chi: Oh, vielen Dank, ich glaube damit kann ich was anfangen :praise: :allright:
Kein Problem ;)

2 kleine Änderungen:
  • SetWindowPos_(#HWND_BOTTOM) -> startet am Desktop
  • DesktopHandle() anstatt GetShellWindow_() -> somit funktioniert auch "Desktop anzeigen" wie erwartet

Code: Alles auswählen

Procedure DesktopHandle()
  Protected hProgman, hDesktopWnd, hShellViewWin, hWorkerW, hDesktopListView
  hProgman = GetShellWindow_()
  If hProgman
    hShellViewWin = FindWindowEx_(hProgman, 0, "SHELLDLL_DefView", 0)
    If hShellViewWin
      hDesktopListView = FindWindowEx_(hShellViewWin, 0, "SysListView32", 0)
    Else
      hDesktopWnd = GetDesktopWindow_()
      Repeat
        hWorkerW = FindWindowEx_(hDesktopWnd, hWorkerW, "WorkerW", #Null)
        hShellViewWin = FindWindowEx_(hWorkerW, 0, "SHELLDLL_DefView", 0)
      Until hShellViewWin <> #Null And hWorkerW <> #Null      
      hDesktopListView = FindWindowEx_(hShellViewWin, 0, "SysListView32", 0)
    EndIf    
    ProcedureReturn hDesktopListView
  EndIf
EndProcedure

BlendMode.BLENDFUNCTION
BlendMode\SourceConstantAlpha = 255
BlendMode\AlphaFormat = #AC_SRC_ALPHA

OpenWindow(0, 0, 0, 150, 50, "", #PB_Window_BorderLess|#PB_Window_ScreenCentered|#PB_Window_Invisible, DesktopHandle())
SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_TRANSPARENT)
HideWindow(0, #False)
SetWindowPos_(WindowID(0), #HWND_BOTTOM, 0, 0, 0, 0, #SWP_NOSIZE|#SWP_NOMOVE)
AddWindowTimer(0, 0, 1000)

Repeat
  event = WaitWindowEvent()
  Select event
    Case #PB_Event_Timer
      Select EventTimer()
          
        Case 0
          hWnd = WindowID(0)
          GetWindowRect_(hWnd, wRect.RECT)
          OffsetRect_(wRect, -wRect\left, -wRect\top)
          hdc = GetWindowDC_(hWnd)
          mdc = CreateCompatibleDC_(hdc)
          CreateImage(0, wRect\right, wRect\bottom, 32, #PB_Image_Transparent)
          StartDrawing(ImageOutput(0))
            DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Outlined)
            Box(0, 0, OutputWidth(), OutputHeight(), RGBA(0,0,255,100))
            DrawText(10, 10, FormatDate("%hh:%ii:%ss", Date()), RGBA(255,0,0,255), RGBA(0,0,0,0))
            x + 1
            DrawText(10, 30, "Hello World" + LSet("", x % 4, "."), RGBA(255,0,0,255), RGBA(0,0,0,0))
          StopDrawing()
          old = SelectObject_(mdc, ImageID(0))
          UpdateLayeredWindow_(hWnd, 0, 0, @wRect+8, mdc, @ContextOffset.POINT, 0, @BlendMode, #ULW_ALPHA)
          SelectObject_(mdc, old)
          DeleteDC_(mdc)
          ReleaseDC_(hWnd, hdc)
          
      EndSelect
  EndSelect
Until event = #PB_Event_CloseWindow Or GetAsyncKeyState_(#VK_ESCAPE) & 1
[/size]
Antworten