• Print

Author Topic: Translucent windows anyone?  (Read 407 times)

Jobert14

  • Full Member
  • ***
  • Posts: 236
  • BAHHH!!!
    • Email
Translucent windows anyone?
« on: January 19, 2013, 05:28:02 PM »
I was kinda bored so I decided to port a VB4 program that changes the current window's opacity level to QB64 and it worked surprisingly well!

Note: Only works in Windows...Not sure if its possible in Linux.

Quote
DEFINT A-Z

' Declare windows API functions
DECLARE DYNAMIC LIBRARY "user32"
   FUNCTION SetLayeredWindowAttributes& (BYVAL hwnd AS LONG, BYVAL crKey AS LONG, BYVAL bAlpha AS _UNSIGNED _BYTE, BYVAL dwFlags AS LONG)
   FUNCTION GetWindowLong& ALIAS "GetWindowLongA" (BYVAL hwnd AS LONG, BYVAL nIndex AS LONG)
   FUNCTION SetWindowLong& ALIAS "SetWindowLongA" (BYVAL hwnd AS LONG, BYVAL nIndex AS LONG, BYVAL dwNewLong AS LONG)
END DECLARE

' Needed for acquiring the hWnd of the window
DECLARE LIBRARY
   FUNCTION FindWindow& (BYVAL ClassName AS _OFFSET, WindowName$) ' To get hWnd handle
END DECLARE


DIM MyHwnd AS LONG

' Get hWnd value
_TITLE "Translucent window test"
MyHwnd = FindWindow(0, "Translucent window test" + CHR$(0))


' Set screen and draw a simple fractal which looks cooler than a black translucent window
SCREEN _NEWIMAGE(640, 480, 32)

FOR Py = 0 TO 479
   FOR Px = 0 TO 639
      PSET (Px, Py), _RGB32((Px OR Py) MOD 256, (Px + Py) MOD 256, Py MOD 256)
   NEXT Px
NEXT Py


' Main loop
PRINT "Press +/- to change opacity"

Level = 127
SetWindowOpacity MyHwnd, Level
DO
   Press$ = INKEY$
   LOCATE 2, 1: PRINT "Opacity:"; Level

   ' Change window opacity whenever +/- are pressed
   IF Press$ = "+" AND Level < 255 THEN Level = Level + 1: SetWindowOpacity MyHwnd, Level
   IF Press$ = "-" AND Level > 0 THEN Level = Level - 1: SetWindowOpacity MyHwnd, Level

   _LIMIT 60

LOOP UNTIL Press$ = CHR$(27)
SYSTEM


'====================================================================\
SUB SetWindowOpacity (hWnd AS LONG, Level)

CONST G = -20
CONST LWA_ALPHA = &H2
CONST WS_EX_LAYERED = &H80000

DIM Msg AS LONG

Msg = GetWindowLong(hWnd, G)
Msg = Msg OR WS_EX_LAYERED
Crap = SetWindowLong(hWnd, G, Msg)
Crap = SetLayeredWindowAttributes(hWnd, 0, Level, LWA_ALPHA)

END SUB
The C.E.O guy of Meido-Tek Productions (please warn me if this name is already taken).

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4680
  • QB Forever
    • Email
Re: Translucent windows anyone?
« Reply #1 on: January 19, 2013, 06:01:25 PM »
If we can do this on a per pixel basis and make it frameless then it would be very useful because we could make custom shaped windows.
Something old... Something new... Something borrowed... Something blue...

OlDosLover

  • Hero Member
  • *****
  • Posts: 3960
  • OlDosLover
    • Email
Re: Translucent windows anyone?
« Reply #2 on: January 20, 2013, 03:45:44 AM »
Hi all,
    Very nice and unusual effect Jobert14. Thank you for sharing this!
OlDosLover.

LeChuck

  • Hero Member
  • *****
  • Posts: 895
  • 18 * 37
Re: Translucent windows anyone?
« Reply #3 on: January 20, 2013, 06:32:44 AM »
Bookmarked, very cool!
Two or more, use a FOR!

Clippy

  • Hero Member
  • *****
  • Posts: 16446
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: Translucent windows anyone?
« Reply #4 on: January 20, 2013, 01:06:33 PM »
Cool! Press minus long enough and it completely disappears.
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

mcalkins

  • Hero Member
  • *****
  • Posts: 1279
    • qbasicmichael.com
    • Email
Re: Translucent windows anyone?
« Reply #5 on: January 20, 2013, 04:07:37 PM »
Nice.

I tried it on QB64 0.954 with Windows XP. (Windows XP doesn't use a compositing window manager, so I wondered what effect that would have.)

I decided to watch the CPU usage.  I was curious if the transparency would mean increased usage. The first time I ran it, the process spent a lot of time in kernel mode, and was sluggish, until I went to opacity 255. However, the next time I ran the program, CPU usage was lower, and the opacity didn't seem to matter. The third time I ran it, CPU usage was back up (mostly kernel mode), and the program was sluggish. Multiple subsequent runs all have the lower CPU usage.

There seems to be some randomness (perhaps a race condition or lock contention inside QB64's code??) that results in increased CPU usage with some runs, but not others...

Regards,
Michael
The QBASIC Forum Community: http://www.network54.com/index/10167 Includes off-topic subforums.
QB64 Off-topic subforum: http://qb64offtopic.freeforums.org/

Gothon

  • Newbie
  • *
  • Posts: 8
Re: Translucent windows anyone?
« Reply #6 on: January 22, 2013, 04:26:04 PM »
Quote from: Galleon on January 19, 2013, 06:01:25 PM
If we can do this on a per pixel basis and make it frameless then it would be very useful because we could make custom shaped windows.

Actually the windows API has had the ability make custom shaped windows a long time.  Though Microsoft does this by combining regions represented using vector primitives (eg, polygons/ellipses) rather than giving each pixel an individual alpha transparency.

http://msdn.microsoft.com/en-us/library/windows/desktop/dd162913(v=vs.85).aspx


Here I have modified the program to produce a transparent window with an elliptical doughnut hole in the middle.
Code: [Select]
DEFINT A-Z

TYPE RECT
    Left AS LONG
    Top AS LONG
    Right AS LONG
    Bottom AS LONG
END TYPE

' Declare windows API functions
DECLARE DYNAMIC LIBRARY "user32"
    FUNCTION SetLayeredWindowAttributes& (BYVAL hwnd AS LONG, BYVAL crKey AS LONG, BYVAL bAlpha AS _UNSIGNED _BYTE, BYVAL dwFlags AS LONG)
    FUNCTION GetWindowLong& ALIAS "GetWindowLongA" (BYVAL hwnd AS LONG, BYVAL nIndex AS LONG)
    FUNCTION SetWindowLong& ALIAS "SetWindowLongA" (BYVAL hwnd AS LONG, BYVAL nIndex AS LONG, BYVAL dwNewLong AS LONG)
    FUNCTION SetWindowRgn& (BYVAL hWnd AS LONG, BYVAL hRgn AS LONG, BYVAL bRedraw AS INTEGER)
END DECLARE

DECLARE DYNAMIC LIBRARY "gdi32"
    FUNCTION CreateEllipticRgn& (BYVAL X1 AS LONG, BYVAL Y1 AS LONG, BYVAL X2 AS LONG, BYVAL Y2 AS LONG)
    FUNCTION CreateRectRgnIndirect& (lprc AS RECT)
    FUNCTION CombineRgn& (BYVAL hRgnDest AS LONG, BYVAL hRgnSrc1 AS LONG, BYVAL hRgnSrc2 AS LONG, BYVAL fnCombineMode AS LONG)
END DECLARE

' Needed for acquiring the hWnd of the window
DECLARE LIBRARY
    FUNCTION FindWindow& (BYVAL ClassName AS _OFFSET, WindowName$) ' To get hWnd handle
END DECLARE

'/* CombineRgn() Styles */
CONST RGN_AND = 1
CONST RGN_OR = 2
CONST RGN_XOR = 3
CONST RGN_DIFF = 4
CONST RGN_COPY = 5


DIM MyHwnd AS LONG
DIM Region AS LONG
DIM Result AS LONG
DIM R AS RECT

' Get hWnd value
_TITLE "Translucent window test"
MyHwnd = FindWindow(0, "Translucent window test" + CHR$(0))

'Build a window region with an elliptical hole
R.Right = 640: R.Bottom = 480
Region = CreateEllipticRgn(20, 40, 600, 400)
Result = CombineRgn(Region, Region, CreateRectRgnIndirect(R), RGN_XOR)
Result = SetWindowRgn(MyHwnd, Region, 0)

' Set screen and draw a simple fractal which looks cooler than a black translucent window
SCREEN _NEWIMAGE(640, 480, 32)

FOR Py = 0 TO 479
    FOR Px = 0 TO 639
        PSET (Px, Py), _RGB32((Px OR Py) MOD 256, (Px + Py) MOD 256, Py MOD 256)
    NEXT Px
NEXT Py


' Main loop
PRINT "Press +/- to change opacity"

Level = 196
SetWindowOpacity MyHwnd, Level
DO
    Press$ = INKEY$
    LOCATE 2, 1: PRINT "Opacity:"; Level

    ' Change window opacity whenever +/- are pressed
    IF Press$ = "+" AND Level < 255 THEN Level = Level + 1: SetWindowOpacity MyHwnd, Level
    IF Press$ = "-" AND Level > 0 THEN Level = Level - 1: SetWindowOpacity MyHwnd, Level

    _LIMIT 60

LOOP UNTIL Press$ = CHR$(27)
SYSTEM


'====================================================================\
SUB SetWindowOpacity (hWnd AS LONG, Level)

CONST G = -20
CONST LWA_ALPHA = &H2
CONST WS_EX_LAYERED = &H80000

DIM Msg AS LONG

Msg = GetWindowLong(hWnd, G)
Msg = Msg OR WS_EX_LAYERED
Crap = SetWindowLong(hWnd, G, Msg)
Crap = SetLayeredWindowAttributes(hWnd, 0, Level, LWA_ALPHA)

END SUB
« Last Edit: January 22, 2013, 04:34:23 PM by Gothon »

Clippy

  • Hero Member
  • *****
  • Posts: 16446
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: Translucent windows anyone?
« Reply #7 on: January 22, 2013, 09:36:28 PM »
AHHHHHH! My program's been shot by a tank!   ;D 

Cool! Make a program shaped like a slice of pizza for Pete...  ;)
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

mcalkins

  • Hero Member
  • *****
  • Posts: 1279
    • qbasicmichael.com
    • Email
Re: Translucent windows anyone?
« Reply #8 on: January 23, 2013, 12:05:18 AM »
 :)

Regards,
Michael
The QBASIC Forum Community: http://www.network54.com/index/10167 Includes off-topic subforums.
QB64 Off-topic subforum: http://qb64offtopic.freeforums.org/

OlDosLover

  • Hero Member
  • *****
  • Posts: 3960
  • OlDosLover
    • Email
Re: Translucent windows anyone?
« Reply #9 on: January 23, 2013, 04:51:05 AM »
Hi all,
    Very impressive Gothon. Thanks for sharing.
OlDosLover.

iamdenteddisk

  • Hero Member
  • *****
  • Posts: 2737
    • Email
Re: Translucent windows anyone?
« Reply #10 on: January 23, 2013, 02:49:25 PM »
I'm not a library's guy but I have to say that is pretty neat stuff there.  could it be used to do in-depth overlays like in Disney animations?
I know Disney used 10 animation layers but most of the modern animation company's call that overkill and they only use 6 layers..

could be used to implement 3d distance with such a thing to especially if you can move the layer independently showing flex of the surface you are standing on. could probably get away with only using 3 layers in some cases..
 

  • Print