QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: Pete on May 17, 2019, 01:05:09 pm

Title: Is this possible in graphics mode?
Post by: Pete on May 17, 2019, 01:05:09 pm
Hi,

I wonder if anyone here knows I hardly ever program in graphics? :D

Well, in any QB64 screen, is it possible to produce a window with transparency? In other words, if I drag that window across my desktop, I can see the desktop icons showing through the QB64 window?

Pete
Title: Re: Is this possible in graphics mode?
Post by: bplus on May 17, 2019, 01:18:26 pm
Get an image of your desktop and then do graphics over that and you will an appearnce. To fake a QB64 window alos get an image.
Title: Re: Is this possible in graphics mode?
Post by: Pete on May 17, 2019, 01:22:45 pm
I was hoping there was a way to float a QB64 window over the existing desktop. I know I could make a desktop copy, Iv'e done that before for my FireFox app. So it's not possible to make the window transparent?

Pete
Title: Re: Is this possible in graphics mode?
Post by: bplus on May 17, 2019, 01:28:28 pm
I don't know what's possible but you'd have to get the back of the QB64 screen transparent. It would be a cool effect!
Title: Re: Is this possible in graphics mode?
Post by: FellippeHeitor on May 17, 2019, 01:39:55 pm
http://www.qb64.org/wiki/Windows_Libraries#Window_Transparency (http://www.qb64.org/wiki/Windows_Libraries#Window_Transparency)
Title: Re: Is this possible in graphics mode?
Post by: Petr on May 17, 2019, 02:24:57 pm
Fellippe, example you post here return this error message:

In file included from qbx.cpp:2171:
..\\temp\\main.txt: In function 'void QBMAIN(void*)':
..\\temp\\main.txt:9:125: error: cast from 'HWND' {aka 'HWND__*'} to 'int' loses precision [-fpermissive]
 *__LONG_MYHWND=(  int32  )FindWindow(NULL,(char*)(qbs_add(qbs_new_txt_len("Translucent window test",23),func_chr( 0 )))->chr);
                                                                                                                             ^
compilation terminated due to -Wfatal-errors.


under QB 1.3

but works under v 1.1 Revision 20170120/51
Title: Re: Is this possible in graphics mode?
Post by: SMcNeill on May 17, 2019, 02:58:17 pm
Fellippe, example you post here return this error message:

In file included from qbx.cpp:2171:
..\\temp\\main.txt: In function 'void QBMAIN(void*)':
..\\temp\\main.txt:9:125: error: cast from 'HWND' {aka 'HWND__*'} to 'int' loses precision [-fpermissive]
 *__LONG_MYHWND=(  int32  )FindWindow(NULL,(char*)(qbs_add(qbs_new_txt_len("Translucent window test",23),func_chr( 0 )))->chr);
                                                                                                                             ^
compilation terminated due to -Wfatal-errors.


under QB 1.3

but works under v 1.1 Revision 20170120/51

You're using a 64-bit version instead of a 32-bit version, so the OFFSET size required is wrong.  LONG won't hold the return values correctly in a 64-bit system.  You need an INTEGER64 instead.  Try this simple fix:

Code: [Select]
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
DIM Myhwnd AS LONG ' Get hWnd value
_TITLE "Translucent window test"
Myhwnd = _WINDOWHANDLE
' 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)
    DIM Msg AS LONG
    CONST G = -20
    CONST LWA_ALPHA = &H2
    CONST WS_EX_LAYERED = &H80000
    Msg = GetWindowLong(hwnd, G)
    Msg = Msg OR WS_EX_LAYERED
    Crap = SetWindowLong(hwnd, G, Msg)
    Crap = SetLayeredWindowAttributes(hwnd, 0, Level, LWA_ALPHA)
END SUB

Notice the line: Myhwnd = _WINDOWHANDLE

No need to get the library call, since _WINDOWHANDLE has been added as a keyword by default now, to prevent this type of issue for users. 
Title: Re: Is this possible in graphics mode?
Post by: Petr on May 17, 2019, 02:59:37 pm
For a truly transparent window (without using Windows libraries), _SCREENIMAGE can be used, but the program must be minimized to always save the current active screen. I use it here in a screen recorder program.

Maybe something from this thread https://www.qb64.org/forum/index.php?topic=561.msg4127#msg4127 help you with your problem, Pete.
Title: Re: Is this possible in graphics mode?
Post by: Petr on May 17, 2019, 03:03:22 pm
Thank you Steve, your version works perfectly! I didn't think to this option (again).
Title: Re: Is this possible in graphics mode?
Post by: SMcNeill on May 17, 2019, 03:10:27 pm
Thank you Steve, your version works perfectly! I didn't think to this option (again).

If you really *need* to use FindWindow (such as to find the handle of a different window), then the best way to code for it is to use the precompiler to make certain that you get the right size value back for it:

Code: [Select]
' Needed for acquiring the hWnd of the window
$IF 32BIT THEN
    DECLARE LIBRARY
    FUNCTION FindWindow& (BYVAL ClassName AS _OFFSET, WindowName$) ' To get hWnd handle
    END DECLARE
$ELSE
    DECLARE LIBRARY
        FUNCTION FindWindow&& (BYVAL ClassName AS _OFFSET, WindowName$) ' To get hWnd handle
    END DECLARE
$END IF

On a 32-bit system, get a LONG (32-bit) value, else get an INTEGER64 (64-bit) value...

Also a simple change, which makes certain your code works as intended across versions.
Title: Re: Is this possible in graphics mode?
Post by: Pete on May 17, 2019, 03:25:31 pm
I tried the Wiki example, and the -+ does nothing. It doesn't allow the desktop to show through at all. It is just a lot of pastel triangles in a standard window.

I tried Steve's example, and it worked as anticipated. - and + keys change the opacity, which is a true translucency. Nice! Thanks Steve. I'll also try out Petr link when I return.

Pete
Title: Re: Is this possible in graphics mode?
Post by: Petr on May 17, 2019, 03:27:14 pm
Yes!. Thank you Steve. I feel like, I had this problem when trying to transcribe MOD player from another language to QB64. I have to look around for the disk if I can find the source.  Is sure very good to know this.
Title: Re: Is this possible in graphics mode?
Post by: bplus on May 17, 2019, 03:33:58 pm
Yes Thank you Steve for fix, that is nice effect!

Great idea Pete and thanks to Fellippe for getting us a step closer.