Alternative to window regions

Share your advanced PureBasic knowledge/code with the community.
GreenGiant
Enthusiast
Enthusiast
Posts: 252
Joined: Fri Feb 20, 2004 5:43 pm

Alternative to window regions

Post 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.
TeddyLM
Enthusiast
Enthusiast
Posts: 133
Joined: Wed Apr 30, 2003 2:04 pm
Location: Germany (French expat)

Post by TeddyLM »

interesting !
thank you
PolyVector
Enthusiast
Enthusiast
Posts: 499
Joined: Wed Sep 17, 2003 9:17 pm
Location: Southern California
Contact:

Post by PolyVector »

very interesting, It's sad that this requires win2k... :/
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

Neat.
@}--`--,-- A rose by any other name ..
GreenGiant
Enthusiast
Enthusiast
Posts: 252
Joined: Fri Feb 20, 2004 5:43 pm

Post 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
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Post by NoahPhense »

nice work GreenGiant ..
Nico
Enthusiast
Enthusiast
Posts: 274
Joined: Sun Jan 11, 2004 11:34 am
Location: France

Post 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! :)
Post Reply