Page 1 of 1

Alternative to window regions

Posted: Sun Aug 01, 2004 5:56 pm
by GreenGiant
Well, not sure if this is worthy of being in the tricks and tips section, but some people might find it useful. I found out how to have transparency in windows without using regions. The transparency is automatic, basically involving a mask colour. So this means you can use it in realtime. Anyway, here's a little example I wrote:

Code: Select all

Global offset.l

Procedure draw()
  StartDrawing(WindowOutput())
    Box(0,0,100,100,$00FF00)
    
    For temp=1 To 9
      Line(temp*10,0,0,100,$000000)
      Line(0,temp*10,100,0,$000000)
    Next 
    
    y=20+10*Sin(offset*0.09)
    For temp=2 To 99
      oldy=y
      y=20+10*Sin((temp+offset)*0.09)
      Line(temp-1,oldy,0,61,RGB(255-temp*2,temp*2,-(temp*(temp-100))/10))
      Line(temp-1,oldy,1,oldy-y,$000000)
      Line(temp-1,oldy+31,1,oldy-y,$000000)
      Line(temp-1,oldy+61,1,oldy-y,$000000)
      If (temp+offset)%30=0
        Line(temp,y,0,61,$FFFFFF)
      EndIf
    Next 

    Line(0,0,100,0,$000000)
    Line(0,0,0,100,$000000)
    Line(99,0,0,100,$000000)
    Line(0,99,100,0,$000000)
    
  StopDrawing()
  offset=offset+1
EndProcedure

OpenWindow(0,400,400,100,100,#PB_Window_BorderLess,"alpha")
SetWindowLong_(WindowID(0),#GWL_EXSTYLE,GetWindowLong_(WindowID(0),#GWL_EXSTYLE)|$00080000)
SetLayeredWindowAttributes_(WindowID(0),$00FF00,0,1)

SetTimer_(WindowID(0),2,20,@draw())

Repeat
ev=WaitWindowEvent()
  
  If ev=#WM_LBUTTONDOWN
    ReleaseCapture_()
    SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
  EndIf
  
Until ev=#WM_RBUTTONDOWN
The drawing's just an example, the bit thats doing the transparency work is

Code: Select all

SetWindowLong_(WindowID(0),#GWL_EXSTYLE,GetWindowLong_(WindowID(0),#GWL_EXSTYLE)|$00080000)
SetLayeredWindowAttributes_(WindowID(0),$00FF00,0,1)
Basically masking out any part of the window of the colour $00FF00. Unfortunately this requires Windows2000 or higher.

Posted: Sun Aug 01, 2004 10:07 pm
by TeddyLM
interesting !
thank you

Posted: Sun Aug 01, 2004 10:55 pm
by PolyVector
very interesting, It's sad that this requires win2k... :/

Posted: Sun Aug 01, 2004 11:23 pm
by Dare2
Neat.

Posted: Sun Aug 01, 2004 11:49 pm
by GreenGiant
@PolyVector If you want to do something similar on 95/98, I think it would be possible using regions, but maybe not work as well. Here's a very simple little sample I made that generated regions in real-time. The problem is that all the region commands seem so cumbersome, the other way's so much easier. Anyway,

Code: Select all

Global region
Global ticker

Procedure update()
  region=CreateEllipticRgn_(ticker,99-ticker,99-ticker,ticker)
  SetWindowRgn_(WindowID(0),region,#True)
  ticker=ticker+1 
  If ticker>99
    ticker=ticker-100
  EndIf
EndProcedure

Procedure draw()
  StartDrawing(WindowOutput())
    Box(0,0,100,100,$00FF00)   
  StopDrawing()
EndProcedure

OpenWindow(0,400,400,100,100,#PB_Window_BorderLess,"test")

SetTimer_(WindowID(0),2,20,@update()) 

Repeat 
ev=WaitWindowEvent() 
  
  If ev=#WM_LBUTTONDOWN 
    ReleaseCapture_() 
    SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0) 
  EndIf 
  
  If ev=#PB_Event_Repaint
    draw()
  EndIf
  
Until ev=#WM_RBUTTONDOWN

Posted: Sun Aug 01, 2004 11:52 pm
by NoahPhense
nice work GreenGiant ..

Posted: Mon Aug 02, 2004 1:23 pm
by Nico
It's better with a callback because the colour disappears when one click and move:

Code: Select all

Procedure WindowCallback(WindowID,message,wParam,lParam) 
  res=#PB_ProcessPureBasicEvents 
  Select message  
    Case #WM_PAINT 
          draw() 
  EndSelect 
  ProcedureReturn res 
EndProcedure 

.........
SetWindowCallback(@WindowCallback())
Nice code! :)