Page 1 of 1

Draw to partially transparent screen?

Posted: Thu Aug 01, 2024 4:39 pm
by matalog
Is it possible to draw to a partially transparent screen? For example, I would like to draw 3 rectangles on 3 different areas of the screen, then have that on top of all other windows and those 3 rectangles being the only visible part of the running program. Is something like that possible?

Re: Draw to partially transparent screen?

Posted: Thu Aug 01, 2024 5:07 pm
by firace
Not sure if this is what you want, but this draws to a transparent window:

Code: Select all


OpenWindow(3,0,0,0, 0,"HiddenWindow",#PB_Window_Invisible|#PB_Window_NoActivate) 

width = 190 : height = 60


hWnd2=OpenWindow(1, 300, 0, width, height, "",#PB_Window_BorderLess|#PB_Window_Invisible,WindowID(3))
SetWindowLongPtr_(hWnd2,#GWL_EXSTYLE,GetWindowLongPtr_(hWnd2,#GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_TRANSPARENT|#WS_EX_TOOLWINDOW|$08000000) 


SetWindowColor(1, 23) : OpenLibrary(1, "user32.dll") : CallFunction(1, "SetLayeredWindowAttributes", hwnd2, 23, 0, #LWA_COLORKEY) 


HideWindow(1,#False, #PB_Window_NoActivate)
StickyWindow(1,1)

AddWindowTimer(1,1,300)

Repeat
  
  EventID = WaitWindowEvent()
  
  Select EventID
    Case  #PB_Event_CloseWindow : End
      
    Case  #PB_Event_Timer  , 12
      
      hdc = StartDrawing(WindowOutput(1))
      If hdc
        
        Box(0, 0, width, height, 23)
        
        box(20, 20, 30, 30,  $832121)
        box(80, 20, 30, 30,  $832121)
        box(140, 20, 30, 30, $832121)
        
        StopDrawing() 
      EndIf
  EndSelect
  
ForEver

Re: Draw to partially transparent screen?

Posted: Thu Aug 01, 2024 8:15 pm
by TI-994A
matalog wrote: Thu Aug 01, 2024 4:39 pm...I would like to draw 3 rectangles on 3 different areas of the screen, then have that on top of all other windows and those 3 rectangles being the only visible part of the running program.
A slightly different approach for MacOS:

Code: Select all

CreateImage(0, 800, 600, 32, #PB_Image_Transparent)
If StartDrawing(ImageOutput(0))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  Box(100, 100, 200, 100, RGBA(255, 0, 0, 255))
  Box(300, 300, 200, 100, RGBA(0, 255, 0, 255))
  Box(500, 500, 200, 100, RGBA(0, 0, 255, 255))
  StopDrawing()
EndIf

winWidth = ImageWidth(0)
winHeight = ImageHeight(0)

OpenWindow(0, 100, 100, winWidth, winHeight, "", #PB_Window_BorderLess)
ButtonGadget(0, 0, 0, 100, 50, "QUIT")
StickyWindow(0, #True)

windowShape = CocoaMessage(0, 0, "NSColor colorWithPatternImage:", ImageID(0))
CocoaMessage(0, WindowID(0), "setOpaque:", #NO)
CocoaMessage(0, WindowID(0), "setHasShadow:", #YES)  
CocoaMessage(0, WindowID(0), "setMovableByWindowBackground:", #YES)  
CocoaMessage(0, WindowID(0), "setBackgroundColor:", windowShape)  

Repeat     
  Select WaitWindowEvent()      
    Case #PB_Event_Gadget
      If EventGadget() = 0 
        appQuit = #True
      EndIf        
  EndSelect  
Until appQuit

Re: Draw to partially transparent screen?

Posted: Thu Aug 01, 2024 10:28 pm
by matalog
firace wrote: Thu Aug 01, 2024 5:07 pm Not sure if this is what you want, but this draws to a transparent window:

Code: Select all


OpenWindow(3,0,0,0, 0,"HiddenWindow",#PB_Window_Invisible|#PB_Window_NoActivate) 

width = 190 : height = 60


hWnd2=OpenWindow(1, 300, 0, width, height, "",#PB_Window_BorderLess|#PB_Window_Invisible,WindowID(3))
SetWindowLongPtr_(hWnd2,#GWL_EXSTYLE,GetWindowLongPtr_(hWnd2,#GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_TRANSPARENT|#WS_EX_TOOLWINDOW|$08000000) 


SetWindowColor(1, 23) : OpenLibrary(1, "user32.dll") : CallFunction(1, "SetLayeredWindowAttributes", hwnd2, 23, 0, #LWA_COLORKEY) 


HideWindow(1,#False, #PB_Window_NoActivate)
StickyWindow(1,1)

AddWindowTimer(1,1,300)

Repeat
  
  EventID = WaitWindowEvent()
  
  Select EventID
    Case  #PB_Event_CloseWindow : End
      
    Case  #PB_Event_Timer  , 12
      
      hdc = StartDrawing(WindowOutput(1))
      If hdc
        
        Box(0, 0, width, height, 23)
        
        box(20, 20, 30, 30,  $832121)
        box(80, 20, 30, 30,  $832121)
        box(140, 20, 30, 30, $832121)
        
        StopDrawing() 
      EndIf
  EndSelect
  
ForEver

Yes, that is what I was asking for, thanks for sharing it.

Re: Draw to partially transparent screen?

Posted: Thu Aug 01, 2024 10:29 pm
by matalog
TI-994A wrote: Thu Aug 01, 2024 8:15 pm
matalog wrote: Thu Aug 01, 2024 4:39 pm...I would like to draw 3 rectangles on 3 different areas of the screen, then have that on top of all other windows and those 3 rectangles being the only visible part of the running program.
A slightly different approach for MacOS:

Code: Select all

CreateImage(0, 800, 600, 32, #PB_Image_Transparent)
If StartDrawing(ImageOutput(0))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  Box(100, 100, 200, 100, RGBA(255, 0, 0, 255))
  Box(300, 300, 200, 100, RGBA(0, 255, 0, 255))
  Box(500, 500, 200, 100, RGBA(0, 0, 255, 255))
  StopDrawing()
EndIf

winWidth = ImageWidth(0)
winHeight = ImageHeight(0)

OpenWindow(0, 100, 100, winWidth, winHeight, "", #PB_Window_BorderLess)
ButtonGadget(0, 0, 0, 100, 50, "QUIT")
StickyWindow(0, #True)

windowShape = CocoaMessage(0, 0, "NSColor colorWithPatternImage:", ImageID(0))
CocoaMessage(0, WindowID(0), "setOpaque:", #NO)
CocoaMessage(0, WindowID(0), "setHasShadow:", #YES)  
CocoaMessage(0, WindowID(0), "setMovableByWindowBackground:", #YES)  
CocoaMessage(0, WindowID(0), "setBackgroundColor:", windowShape)  

Repeat     
  Select WaitWindowEvent()      
    Case #PB_Event_Gadget
      If EventGadget() = 0 
        appQuit = #True
      EndIf        
  EndSelect  
Until appQuit
Thanks for that, I cannot test it as I use Windows, but it is good to have for others if they find the question.

Re: Draw to partially transparent screen?

Posted: Fri Aug 02, 2024 10:12 am
by TI-994A
In that case, just for kicks, here's a slightly more interesting dual-platform version: :wink:

Code: Select all

UsePNGImageDecoder()

Procedure quitClicked()
  ;coordinates of the Superman emblem
  If WindowMouseX(0) > 220 And WindowMouseX(0) < 280 And
     WindowMouseY(0) > 110 And WindowMouseY(0) < 150
    quitHotspot = #True
  EndIf
  ProcedureReturn quitHotspot    
EndProcedure

;downloading a PNG image from my server
imgFile$ = GetTemporaryDirectory() + "superman.png"
If FileSize(imgFile$) < 1  
  ReceiveHTTPFile("syed.sg/tutorials/" + GetFilePart(imgFile$), imgFile$)
EndIf

LoadImage(0, imgFile$)
OpenWindow(0, 0, 0, ImageWidth(0), ImageHeight(0), "", 
           #PB_Window_ScreenCentered | #PB_Window_BorderLess)

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
  
  ImportC "" 
    sel_registerName(str.p-ascii)
    class_addMethod(class, selector, imp, types.p-ascii)
  EndImport   
  
  ProcedureC imageProc(obj, sel, notification)
    Static lastEvent : Shared sharedApp  
    currentEvent = CocoaMessage(0, sharedApp, "currentEvent")    
    If currentEvent <> lastEvent
      lastEvent = currentEvent
      If currentEvent
        Select CocoaMessage(0, currentEvent, "type")
          Case #NSLeftMouseUp
            If quitClicked()
              If MessageRequester("Shaped Window", "Quit now?", 1) = 6
                PostEvent(#PB_Event_CloseWindow)
              EndIf           
            EndIf           
        EndSelect
      EndIf
    EndIf
  EndProcedure
  
  windowShape = CocoaMessage(0, 0, "NSColor colorWithPatternImage:", ImageID(0))
  CocoaMessage(0, WindowID(0), "setOpaque:", #NO)
  CocoaMessage(0, WindowID(0), "setHasShadow:", #YES)  
  CocoaMessage(0, WindowID(0), "setMovableByWindowBackground:", #YES)  
  CocoaMessage(0, WindowID(0), "setBackgroundColor:", windowShape)   
  
  sharedApp = CocoaMessage(0, 0, "NSApplication sharedApplication")
  notiCenter = CocoaMessage(0, 0, "NSNotificationCenter defaultCenter")
  appDelegate = CocoaMessage(0, sharedApp, "delegate")
  delegateClass = CocoaMessage(0, appDelegate, "class")
  eventsHandler = sel_registerName("EventsHandlerCallback:")
  class_addMethod(delegateClass, eventsHandler, @imageProc(), "v@:@")
  CocoaMessage(0, notiCenter, "addObserver:", appDelegate, "selector:", 
               eventsHandler, "name:", #Null, "object:", WindowID(0))    
  
  
CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows
  
  Procedure imageProc(hwnd, msg, wParam, lParam)
    Shared sysProc
    Select msg     
      Case #WM_LBUTTONDOWN   
        If quitClicked()
          If MessageRequester("Shaped Window", "Quit now?", 4) = 6
            PostEvent(#PB_Event_CloseWindow)
          EndIf          
        Else
          SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)      
        EndIf 
    EndSelect 
    ProcedureReturn CallWindowProc_(sysProc, hwnd, msg, wParam, lParam)
  EndProcedure
  
  SetWindowColor(0, #White)
  layeredStyle = GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_LAYERED
  SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, layeredStyle)
  SetLayeredWindowAttributes_(WindowID(0), #White, 0, #LWA_COLORKEY) 
  ImageGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), ImageID(0))
  sysProc = SetWindowLongPtr_(GadgetID(0), #GWL_WNDPROC, @imageProc())
  
CompilerEndIf

While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
[EDIT]: modified the code to support Windows and MacOS. :D

Re: Draw to partially transparent screen?

Posted: Fri Aug 02, 2024 11:48 am
by matalog
That's really good TI-994A, thanks again.