Jump to content

Screensaver UDF


james3mg
 Share

Recommended Posts

I'd talked about it, but it ended up being easier than I expected. Here it is; an easy-to-use screensaver UDF!

You need to #include this file in any script you want to make a UDF, then customize from your main script using the provided functions. To actually make the .scr file, compile your script, then rename the .exe to .scr

The absolute minimum screensaver script is as follows:

#include <_SS_UDF.au3>
_SS_Start()

Yes, that's all. Now, this screensaver isn't too exciting; it's just a black screen, but it's a fully functional screensaver (when compiled and renamed as noted above) that has a working preview, exits when (most) keys are pressed or when the mouse is moved, understands when the screensaver is attempted to be configured and 'saves' any screens configured on your system (read: multi-monitor setups supported).

A only slightly more exciting screensaver would be:

#include <_SS_UDF.au3>
_SS_GUICreate()
GUICtrlCreateLabel("Hello, world!",5,5,100,20)
GUICtrlSetColor(-1,0xFFFFFF)
_SS_Start()

If you want to animate your text, you might use:

#include <_SS_UDF.au3>
$MySSWin=_SS_GUICreate()
$MyLabel=GUICtrlCreateLabel("Hello, World!",5,5,100,20)
GUICtrlSetColor(-1,0xFFFFFF)
_SS_SetMainLoop("MyMainLoop")
Global $Xpos=1
Global $Ypos=1
Global $Xdir=1
Global $Ydir=1

_SS_Start()

Func MyMainLoop()
    Do
        GUICtrlSetPos($MyLabel,$Xpos,$Ypos)
        $Xpos+=$Xdir
        $Ypos+=$Ydir
        If $YPos=0 Or ($YPos=$_SS_WinHeight-20 AND $YDir=1) Then $YDir=$YDir*-1
        If $XPos=0 Or ($XPos=$_SS_WinWidth-100 AND $XDir=1) Then $XDir=$XDir*-1
        Sleep(15)
    Until _SS_ShouldExit()
EndFunc

Note that the user has specified their own custom loop function to actually DO something while the screensaver is running.

The functions:

Required functions to be called:

_SS_Start();the function to call when everything's set up- turns control over to the appropriate loops

Recommended functions to be called:

_SS_GUICreate();the function to create the correct type of GUI for the screensaver, regardless of it's a preview or not...

_SS_SetMainLoop($_ss_funcName="_SS_MainFunc");user calls this to name the function they'd like to use as the main screensaver loop

Optional functions available to be called:

_SS_SetConfigLoop($_ss_funcName="_SS_ConfigFunc");user calls this to name the function they'd like to use if the screensaver is attempted to be configured

_SS_ShouldExit($_SS_Sensitivity=10);a generic "check if no longer idle" function...checks for mouse movement with a built-in sensitivity (pixels the mouse must move suddenly to return a 1)
(Note that _SS_ShouldExit() also handles closing the small preview in Windows' "Configure Screensaver" GUI, but it's not working perfectly yet (it works 'well enough' though). If you do your own exit checking (from within your main screensaver loop identified in your _SS_SetMainLoop() call), make sure you handle exiting the screensaver preview as well.

Variables available to the user (usually for use within their Main Loop function):

$_SS_WinWidth;available to the user to get the width of the available screensaver window, regardless of it's a preview or full screensaver

$_SS_WinHeight;available to the user to get the height of the available screensaver window, regardless of it's a preview or full screensaver

$_SS_IsPreview;available to the user so they can do different things depending on if it's a preview (1) or the full screensaver (0)

If you want to have configurations for your screensaver, you need to write the GUI loop in a function and point to it with _SS_SetConfigLoop()...you'll have to do all the saving/restoring of values yourself (usually with an .ini file or in the registry), as well as lookup of the configured values within your Main Loop function.

I hope this makes sense and is helpful to people...let me know if something doesn't quite work or what you think of this!

I do have to say, much credit goes to lokster for teaching me how to get the screensaver preview to work in Windows' Configure Screensaver dialog.

Latest version of the UDF (29 Apr 2008) - New method for determining idle status in _SS_ShouldExit now obeys sensitivity parameter again.

v1.3.1.0 _SS_UDF.au3

Previous Downloads:

v1.3.0.0: 3 (New method for determining idle status in _SS_ShouldExit, but sensitivity parameter is ignored)

v1.2.0.0: 46 (Correct support for multiple monitors)

v1.1.0.1: 14 (_SS_ShouldExit verifies that $_SS_KeyGrab is declared before checking it.)

v1.1.0.0: 9 (a few typos and bugs I'd missed in the original version, and better (not perfect) handling of exiting the preview)

v1.0.0.0: 45

Edited by james3mg
"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

  • Replies 50
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images

From my original post:

The absolute minimum screensaver script is as follows:

...

Yes, that's all. Now, this screensaver isn't too exciting; it's just a black screen, but it's a fully functional screensaver (when compiled and renamed as noted above) that has a working preview, exits when (most) keys are pressed or when the mouse is moved, understands when the screensaver is attempted to be configured and 'saves' any screens configured on your system (read: multi-monitor setups supported)

(emphasis added)

Yes, the preview works. Just try it out- all you have to do is copy five lines of code into a new script in the same directory as the UDF (copy the one with Hello, world) to see that the preview works. This UDF allows you to create one loop for your screensaver that works both in full screensaver mode and in preview mode.

Hope this is what you're looking for.

"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

Can you tell me how the preview (small window when selecting any screensaver) works exactly without using your UDF? :D

...

$VirtualDesktopWidth=152

$VirtualDesktopHeight=112

Global $_SS_GUI=GUICreate("ColorBoxes Screensaver",$_SS_WinWidth,$_SS_WinHeight,0,0,0x80000000)

GUISetBkColor(0x000000)

$USER32 = DllOpen("user32.dll")

DllCall($USER32,"int","SetParent","hwnd",$_SS_GUI,"hwnd",HWnd($CmdLine[2]))

DllClose($USER32)

...

I think, this is the part if the preview! E.g. What should I do to draw a line when selecting a test.scr screensaver and want to see a simple line in the preview window???

Thanks.

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Ok, I found it out how to draw a line in the little preview window.

When I compile your test screensaver :

#include <_SS_UDF.au3>

$MySSWin=_SS_GUICreate()

$MyLabel=GUICtrlCreateLabel("Hello, World!",5,5,100,20)

GUICtrlSetColor(-1,0xFFFFFF)

_SS_SetMainLoop("MyMainLoop")

Global $pos=1

_SS_Start()

Func MyMainLoop()

Do

GUICtrlSetPos($MyLabel,$pos,$pos)

$pos+=1

Sleep(15)

Until _SS_ShouldExit()

EndFunc

And open the window where you can select the screenesaver then I can see following in taskmanager:

If I look into the taskmanager then rundll32.exe is starting the screensaver, the screensaver is a child process of rundll32.exe,

and you can see the preview in the little window. If I press OK or Cancel then only rundll32.exe is terminating. The child process (screensaver)

becomes to root process and it is still running.

When I check buildin screensaver from MS the processes will be terminated after pressing OK or Cancel properly - not left screensaver task.

I assume that the closing process of the preview is different but how? :D

Can somebody confirm?

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Ok, I found it out how to draw a line in the little preview window.

...

If I look into the taskmanager then rundll32.exe is starting the screensaver, the screensaver is a child process of rundll32.exe,

and you can see the preview in the little window. If I press OK or Cancel then only rundll32.exe is terminating. The child process (screensaver)

becomes to root process and it is still running.

When I check buildin screensaver from MS the processes will be terminated after pressing OK or Cancel properly - not left screensaver task.

I assume that the closing process of the preview is different but how? :D

Can somebody confirm?

Sorry I wasn't around longer this weekend to see your question. Did you find the answer to your preview question, then? When the screensaver preview is requested, the screensaver is launched with two parameters: /p and a hwnd id of the preview parent window. So you just need to create a titlebar-less window that's 152x112, then call

$USER32 = DllOpen("user32.dll")
DllCall($USER32,"int","SetParent","hwnd",$_SS_GUI,"hwnd",HWnd($CmdLine[2]))
DllClose($USER32)

where $_SS_GUI is the hwnd of your 152x112 GUI, and $CmdLine[2] is the hwnd of the screensaver preview parent window.

You're right, I haven't figured out the absolute correct way to sense when the preview screensaver should close- the UDF simply has the preview close when its parent window no longer exists, or if the screensaver is called again (config, test, etc). So it won't keep running after you close Windows' "select screensaver" GUI, but it DOES run longer than it should. One way of proving this that I found this weekend is to select a screensaver built with this UDF, make sure the preview is showing, then select another screensaver- you'll see them overlap each other, as your AutoIt screensaver won't close (its parent not having closed).

So I guess this UDF is still one step away from truly running correct- if I/we can figure out how to determine when Windows wants the screensaver to close, I'll build it into the UDF and update the first post.

Thanks for trying this out! :D

Edit: Your post pointed out to me a few bugs I'd left in the code- please download the newest version of the UDF (in the first post). It should now reliably exit the screensaver when you close the "Configure Screensaver" window with OK or Cancel, but it still won't exit when you just change the screensaver selection in the dialog...I'm still trying to find out what message is sent to the preview to tell it to exit (you'd think it was just a close message, but it's not).

Edited by james3mg
"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

I checked out also lokster' ss code but didn't find a clear solution. :D

Maybe lokster can explain... :)

Continue searching... :D

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Actually, thanks for posting that link- he's the one I got most of my SS knowledge from, and I'd meant to include that link earlier.

Look down near the bottom of his code (just above the beginning of all the function definitions, at the section beginning $Mode == 2) and you'll see he uses the same method as I do for knowing when to exit the preview.

I need to look at full C++ screensaver-type resources and find out what message is passed to the preview (or whatever is done) when it should exit...I haven't seen a better method within AutoIt yet, so I think the search will have to extend beyond these forums. I'll let you know when I find something.

In the meantime, just make sure you're using the latest version of the UDF, as it correctly exits when you close the Select Screensaver dialog in Windows...at least that's most of the problem solved.

Edited by james3mg
"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

I tested it with your latest UDF (I've to insert Global $_SS_GUI, $_SS_KeyGrab in your UDF because

of em: possibly used before declaration) and with this code you posted:

#include <_SS_UDF.au3>
$MySSWin=_SS_GUICreate()
$MyLabel=GUICtrlCreateLabel("Hello, World!",5,5,100,20)
GUICtrlSetColor(-1,0xFFFFFF)
_SS_SetMainLoop("MyMainLoop")
Global $Xpos=1
Global $Ypos=1
Global $Xdir=1
Global $Ydir=1

_SS_Start()

Func MyMainLoop()
    Do
        GUICtrlSetPos($MyLabel,$Xpos,$Ypos)
        $Xpos+=$Xdir
        $Ypos+=$Ydir
        If $YPos=0 Or ($YPos=$_SS_WinHeight-20 AND $YDir=1) Then $YDir=$YDir*-1
        If $XPos=0 Or ($XPos=$_SS_WinWidth-100 AND $XDir=1) Then $XDir=$XDir*-1
        Sleep(30)
    Until _SS_ShouldExit()
EndFunc

Now the preview terminates correctly! :D I assume I have to recode my SS from scratch :D

with the new knowledge I got from your UDF and other postings...

But it is not working on multi monitor - only my primary display shows the SS, the second isn't effected.

Primary is running at 1680x1050 and secondary at 1280x1024.

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Now the preview terminates correctly! :D I assume I have to recode my SS from scratch with the new knowledge I got from your UDF and other postings...

If you originally programmed it using my UDF, you should just be able to recompile it with the new one #included and it'll work the same. If, however, you used the principles you found in the UDF and wrote all your own code then...probably.

But it is not working on multi monitor - only my primary display shows the SS, the second isn't effected.

Primary is running at 1680x1050 and secondary at 1280x1024.

Interesting- I hadn't tried different resolutions/alignments...I'd assumed that the Windows API-provided (I think) $VirtualDesktopHeight and $VirtualDesktopWidth with x and y at 0 would make a GUI that covered from desktop top-left to bottom-right extents of the desktop, though corners might be lost where they go off the monitor (i.e. the pixels with x greater than 1680 and y greater than 1024 in your setup). If it doesn't work that way, we may have to look for a new method for finding the virtual desktop...this is the first I'd heard of this problem, however.

By "isn't affected", do you mean that you still see your desktop on the second display, or that it's black and the bouncing 'hello world' doesn't go onto your secondary monitor?

Edit: I just tried it on my computer, setting my primary to 1600x1200, secondary at 1280x1024, and it worked just like I described it should. I think you'd better check your own code, as the UDF seems to be working properly. Why don't you post your code and I'll see if I can't help you through the changes you need to make (new preview exiting, etc)? Or are you really determined not to use my UDF? :D:) It's not that big, after all...and it doesn't even call any other includes...you only end up with about 10 unused lines if you define all your own functions...

And BTW, the warnings you see in SciTE are just warnings- those global variables won't be called before declaration, because if you haven't called _SS_GUICreate() before you call _SS_Start(), _SS_Start() will call _SS_GUICreate() itself, thus declaring those variables. And if you try to use _SS_ShouldExit before you call _SS_GUICreate(), it will return that the screensaver should exit, since the GUI does not exist. So declaring them at the top of the UDF is unnecessary, though there's nothing WRONG with it...I was just trying to keep the number of unnecessary lines to a minimum to keep the size down. However, note that I've uploaded another new version of the script to the first post...the only change is that _SS_ShouldExit() checks to make sure that $_SS_KeyGrab is declared before trying to read it. That way, even if you create your own GUI (instead of using _SS_GUICreate() ) and still use _SS_ShouldExit(), it won't try to call an undeclared variable.

Edited by james3mg
"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

...

By "isn't affected", do you mean that you still see your desktop on the second display, or that it's black and the bouncing 'hello world' doesn't go onto your secondary monitor?

Yes, I can see my desktop on my second display. Only 1st on 1st display the ss is active. Btw, I'm using Vista Enterpise.

...

Why don't you post your code and I'll see if I can't help you through the changes you need to make (new preview exiting, etc)? ...

Here the code:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=D:\Coding\Scripts\AU3\Au3GlPlugin\Star.ico
#AutoIt3Wrapper_outfile=Magic Lines Screensaver.scr
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_Description=Very simple screensaver coded in AutoIT
#AutoIt3Wrapper_Res_Fileversion=1.0.0.0
#AutoIt3Wrapper_Res_Language=1033
://////=__=
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=n
;~ #AutoIt3Wrapper_Run_Tidy=y
;~ #Tidy_Parameters=/rel
;~ #AutoIt3Wrapper_Tidy_Stop_onerror=n


#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>


Opt('MustDeclareVars', 1)
Opt("ColorMode", 1)
Opt("GUIOnEventMode", 1)
Opt("TrayIconHide", 1)

If WinExists("ScrnSav:" & @ScriptFullPath) Then WinKill("ScrnSav:" & @ScriptFullPath)
AutoItWinSetTitle("ScrnSav:" & @ScriptFullPath)

Global $CommandLine

Const $appname = "Magic Lines Screensaver"
Const $ver = "0.50"
Const $build = "2008-04-14"

Global $hGUI, $hWnd, $hGraphic, $hPen, $x, $y, $x1, $x2, $y1, $y2, $i, $position, $radius, $radians, $stRegion 
Global $GUI_Name, $info, $info_pos, $rand, $rand_pos, $details, $wait, $diameter, $speed, $func, $name
Dim $Array_of_Details[10]
Global Const $Pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062

If Not IsDeclared("SM_VIRTUALWIDTH") Then Global Const $SM_VIRTUALWIDTH = 78
If Not IsDeclared("SM_VIRTUALHEIGHT") Then Global Const $SM_VIRTUALHEIGHT = 79
Global $VirtualDesktopWidth = DLLCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_VIRTUALWIDTH)
$VirtualDesktopWidth = $VirtualDesktopWidth[0]
Global $VirtualDesktopHeight = DLLCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_VIRTUALHEIGHT)
$VirtualDesktopHeight = $VirtualDesktopHeight[0]

Global $_SS_WinWidth = $VirtualDesktopWidth
Global $_SS_WinHeight = $VirtualDesktopHeight


If $CmdLine[0] > 0 Then
    $CommandLine = StringLeft($CmdLine[1], 2)
Else
    $CommandLine = "/s"
EndIf

;$CommandLine = "/p"

If $CommandLine = "/s" Then

    $x = @DesktopWidth ;$_SS_WinWidth
    $y = @DesktopHeight ;$_SS_WinHeight

    $GUI_Name = $appname & " v" & $build & " by UEZ"
    ; Create GUI
    $hGUI = GUICreate($GUI_Name, $x, $y, 0, 0, $WS_POPUP, BitOr($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
    $hWnd = WinGetHandle($GUI_Name)
    
    GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "Quit") ; exit program on mouse move
    HotKeySet("{ESC}", "Quit") ; or when ESC is pressed
    GUISetCursor(16, 1) ; hide mouse cursor 
    GUISetBkColor (0x000000) ; set screen backround
    ;GUISetBkColor (0xF0F0F0)

    _GDIPlus_Startup () ; initialize GDI+
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd)
    $hPen = _GDIPlus_PenCreate (0x2FFFFFFF) ; define draw color using alpha blending
    ;$hPen = _GDIPlus_PenCreate (0x2F111111)
    
    $Array_of_Details[0] = 0.50 ; array of detail levels
    $Array_of_Details[1] = 1.00
    $Array_of_Details[2] = 1.50
    $Array_of_Details[3] = 2.00
    $Array_of_Details[4] = 2.50
    $Array_of_Details[5] = 3.00
    $Array_of_Details[6] = 3.50
    $Array_of_Details[7] = 4.00
    $Array_of_Details[8] = 4.50
    $Array_of_Details[9] = 5.00
    
    $speed = 1
    $wait = 5000 ; wait 5 sec.
    $details = $Array_of_Details[Random(0, 8, 1)] ; select randomly detail level from array
    $i = 0
    $position = Random(2, 360, 1) ; set position for x2 and y2
    $radius = Random($y / 8, $y / 2, 1) ; set radius of the circle
    $diameter = $radius * 2
    $radians = 180 * $details ;Random(90, 360, 1) ; set value convert from degrees to radians
    
    $func = Random(1, 5, 1)
    Select
        Case $func = 1
            $name = "Shell"
        Case $func = 2
            $name = "Space"
        Case $func = 3
            $name = "Star"
        Case $func = 4
            $name = "Circle"
        Case $func = 5
            $name = "Nest"
    EndSelect


    $info_pos = Random(0, $y - 55, 1) ; set random position on left side
    $info = GUICtrlCreateLabel($GUI_Name, 4, $info_pos, 90, 50) ; display info label on left side
    GUICtrlSetColor($info, 0x0000FF) ; set font color
    GUICtrlSetFont($info, 8) ; set font size
    
    $rand_pos = Random(0, $y - 20, 1)
    $rand = GUICtrlCreateLabel($name & " | " & $diameter & " | " & $details, $x - 85, $rand_pos, 100, 16) ; display random numbers label on right side
    GUICtrlSetColor($rand, 0x00FFFF) ; set font color
    GUICtrlSetFont($rand, 8) ; set font size
    
    GUISetState() ; initialize GDI+ screen
    
    Do
        Select
            Case $func = 1
                Shell()
                $name = "Shell"
            Case $func = 2
                Space()
                $name = "Space"
            Case $func = 3
                Star()
                $name = "Star"
            Case $func = 4
                Circle()
                $name = "Circle"
            Case $func = 5
                Nest()
                $name = "Nest"
        EndSelect

        _GDIPlus_GraphicsDrawLine ($hGraphic, $x1, $y1, $x2, $y2, $hPen) ;draw line within the circle
        $i += 1
        Sleep($speed)
        If $i = 360 * $details Then ; if drawing is nearly 360 degrees then reset screen with new settings
            $func = Random(1, 5, 1)
            Select
                Case $func = 1
                    $name = "Shell"
                Case $func = 2
                    $name = "Space"
                Case $func = 3
                    $name = "Star"
                Case $func = 4
                    $name = "Circle"
                Case $func = 5
                    $name = "Nest"
            EndSelect           
            $i = 0
            $details = $Array_of_Details[Random(0, 8, 1)]
            $position = Random(2, 360, 1)
            $radius = Random($y / 8, $y / 2, 1)
            $diameter = $radius * 2
            $radians = 180 * $details ;Random(90, 360, 1)
            Sleep ($wait)
            
            $rand = GUICtrlCreateLabel("", $x - 85, $rand_pos, 100, 30) ; delete font on right side
            $info = GUICtrlCreateLabel("", 4, $info_pos, 90, 50) ; delete font left side
            
            $rand_pos = Random(0, $y - 20, 1) ; set new position for information right
            $rand = GUICtrlCreateLabel($name & " | " & $diameter & " | " & $details, $x - 85, $rand_pos, 100, 16) ; print information
            GUICtrlSetColor($rand, 0x00FFFF) ; set font color
            $info_pos = Random(0, $y - 55, 1) ; set new position for information left
            $info = GUICtrlCreateLabel($GUI_Name, 4, $info_pos, 90, 50) ; print information
            GUICtrlSetColor($info, 0x0000FF) ; set font color
            
            $stRegion = DllStructCreate($tagRECT) ; delete whole screen
            DllStructSetData($stRegion, 1, 0)
            DllStructSetData($stRegion, 2, 0)
            DllStructSetData($stRegion, 3, $x)
            DllStructSetData($stRegion, 4, $y)
            _WinAPI_InvalidateRect($hGUI, $stRegion, True)
        EndIf
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    Quit()
    
ElseIf $CommandLine = "/c" Then
    MsgBox(64,  "Information", "Nothing to configure yet, maybe later ;-)" & @CRLF & @CRLF & _
                "UEZ  (c)  " & $build, 15)
    Exit
ElseIf $CommandLine = "/p" Then ;display little preview
    Global $VirtualDesktopHeight, $VirtualDesktopWidth, $USER32, $_SS_WinHeight, $_SS_WinWidth, $PID
    $VirtualDesktopWidth = 152
    $VirtualDesktopHeight = 112
    Global $hGUI = GUICreate($appname, $VirtualDesktopWidth, $VirtualDesktopHeight, 0, 0, 0x80000000)
    $hWnd = WinGetHandle($GUI_Name)
    $USER32 = DllOpen("user32.dll") 
    DllCall($USER32, "int", "SetParent", "hwnd", $hGUI, "hwnd", HWnd($CmdLine[2])) ;set preview window
    DllClose($USER32)
    $hWnd = WinGetHandle($hGUI)
    GUISetState()
    GUISetBkColor(0x000000)
    _GDIPlus_Startup () ; initialize GDI+
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd)
    $hPen = _GDIPlus_PenCreate (0x7FFFFFFF) ; define draw color using alpha blending
    _GDIPlus_GraphicsDrawLine ($hGraphic, 0, 0, $VirtualDesktopWidth, $VirtualDesktopHeight, $hPen)
    Do
        Sleep(100)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    _GDIPlus_PenDispose ($hPen)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_Shutdown ()
    Exit
EndIf


Func Test()
        Local $a, $b
        $a = ATan(($i / $Pi / 45))
        $b = $i /  $pi / 270
        $x1 = Cos ($radius * $i / 360) + ($x / 2)
        $y1 = Tan ($radius * $i / 180) + ($x / 2)
        $x2 = $i / 4
        $y2 = $i / 6
EndFunc

Func Nest()
        Local $a
        $a = ATan((Sqrt($i * $Pi / 180)))
        $x1 = $radius * Cos($i / Sqrt($Pi * $radians)) / $a + $x / 2 ; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i / Sqrt($Pi * $radians)) / $a + $y / 2 ; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Sin($position / $i * Sqrt($Pi * $radians)) / $a + $x / 2 ; create x2 position on space starting from the middle of the screen
        $y2 = $radius * Cos($position / $i * Sqrt($Pi * $radians)) / $a + $y / 2 ; create y2 position on Space starting from the middle of the screen
EndFunc
    
Func Shell()
        Local $a
        $a = Sin($i / 180 / $Pi) / Cos($i * 180 * $Pi)
        $x1 = $radius * Cos($i * Sin($Pi / $radians)) * $a + $x / 2 ; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i * Sin($Pi / $radians)) * $a + $y / 2 ; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Cos($position * $i * Cos($Pi / $radians)) * $a + $x / 2 ; create x2 position on space starting from the middle of the screen
        $y2 = $radius * Sin($position * $i * Cos($Pi / $radians)) * $a + $y / 2 ; create y2 position on Space starting from the middle of the screen
EndFunc
    
Func Space()
        Local $a
        $a = Cos($i) * Sin($i) / ATan($i) * $Pi
        $x1 = $radius * Cos($i * ($Pi / $radians)) / $a + $x / 2 ; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i * ($Pi / $radians)) / $a + $y / 2 ; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Cos($position * $i * ($Pi / $radians)) / $a + $x / 2 ; create x2 position on space starting from the middle of the screen
        $y2 = $radius * Sin($position * $i * ($Pi / $radians)) / $a + $y / 2 ; create y2 position on Space starting from the middle of the screen
EndFunc
    
Func Star()
        $x1 = $radius * Cos($i * ($Pi / $radians)) * ATan($i) + $x / 2 ; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i * ($Pi / $radians)) / Tan($i) + $y / 2 ; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Cos($position * $i * ($Pi / $radians)) * Tan($i) + $x / 2 ; create x2 position on star starting from the middle of the screen
        $y2 = $radius * Sin($position * $i * ($Pi / $radians)) / Tan($i) + $y / 2 ; create y2 position on star starting from the middle of the screen
EndFunc
    
Func Circle()
        $x1 = $radius * Cos($i * ($Pi / $radians)) + $x / 2 ; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i * ($Pi / $radians)) + $y / 2 ; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Cos($position * $i * ($Pi / $radians)) + $x / 2 ; create x2 position on circle starting from the middle of the screen
        $y2 = $radius * Sin($position * $i * ($Pi / $radians)) + $y / 2 ; create y2 position on circle starting from the middle of the screen
EndFunc 

Func Quit() ; exit program
    _GDIPlus_PenDispose ($hPen)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_Shutdown ()
    Exit
EndFunc

It's not finished yet. Configuration Menu needs to be implemented and the properly terminating code is missing :D

Thanks,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

If $CommandLine = "/s" Then

$x = @DesktopWidth ;$_SS_WinWidth

$y = @DesktopHeight ;$_SS_WinHeight

$GUI_Name = $appname & " v" & $build & " by UEZ"

; Create GUI

$hGUI = GUICreate($GUI_Name, $x, $y, 0, 0, $WS_POPUP, BitOr($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))

$hWnd = WinGetHandle($GUI_Name)

Well, you're not using my UDF to create your screensaver GUI, which is why you don't see both screens covered, and I do.

If you want to keep not using the UDF, don't use @DesktopWidth or @DesktopHeight to set your $x and $y...use $_SS_WinWidth and $_SS_WinHeight (the vars you've commented out for some reason). @DesktopWidth and @DesktopHeight only return the size of the PRIMARY monitor, as documented.

Or when you create the GUI, use

GUICreate($GUI_Name, $_SS_WinWidth, $_SS_WinHeight, 0, 0, $WS_POPUP, BitOr($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))

or

GUICreate($GUI_Name, $VirtualDesktopWidth, $VirtualDesktopHeight, 0, 0, $WS_POPUP, BitOr($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))

, both of which are equal, since you're not using _SS_Start() or using $_SS_WinWidth and $_SS_WinHeight for your preview window. BTW, in your code, $hGUI and $hWnd are equal, since the return value from GUICreate() IS the window handle.

As far as the new exit routine I put in my UDF, you can get the same thing by replacing

Do
        Sleep(100)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

with

While 1
        Sleep(100)
        If GUIGetMsg() = GUI_EVENT_CLOSE OR NOT WinExists($GUI_Name) Then ExitLoop
    WEnd

in your

ElseIf $CommandLine = "/p" Then;display little preview
case.

Not that I'm offended, naturally, but do you mind me asking why you're not just using the UDF as I described? It's not really common practice in a UDF thread to post questions about scripts that don't use that UDF...

Edited by james3mg
"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

I modified your screensaver to use my UDF (no offense), and it seems to work great:

#Region;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=D:\Coding\Scripts\AU3\Au3GlPlugin\Star.ico
#AutoIt3Wrapper_outfile=Magic Lines Screensaver.scr
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_Description=Very simple screensaver coded in AutoIT
#AutoIt3Wrapper_Res_Fileversion=1.0.0.0
#AutoIt3Wrapper_Res_Language=1033
#AutoIt3Wrapper_Res_Field=Coded by|UEZ
#EndRegion;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=n
;~ #AutoIt3Wrapper_Run_Tidy=y
;~ #Tidy_Parameters=/rel
;~ #AutoIt3Wrapper_Tidy_Stop_onerror=n


#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>
#include <_SS_UDF.au3>


;Opt('MustDeclareVars', 1)
Opt("ColorMode", 1)
Opt("GUIOnEventMode", 1)
Opt("TrayIconHide", 1)

Const $appname = "Magic Lines Screensaver"
Const $ver = "0.50"
Const $build = "2008-04-14"

Global $hGUI, $hWnd, $hGraphic, $hPen, $x, $y, $x1, $x2, $y1, $y2, $i, $position, $radius, $radians, $stRegion 
Global $GUI_Name, $info, $info_pos, $rand, $rand_pos, $details, $wait, $diameter, $speed, $func, $name
Dim $Array_of_Details[10]
Global Const $Pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062

_SS_SetMainLoop("UEZMainLoop")
_SS_SetConfigLoop("UEZConfig")
_SS_Start()

Func UEZMainLoop()

    $x = $_SS_WinWidth
    $y = $_SS_WinHeight

    $hGUI = _SS_GUICreate()
    $hWnd = $hGUI
    
    _GDIPlus_Startup (); initialize GDI+
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd)
    $hPen = _GDIPlus_PenCreate (0x2FFFFFFF); define draw color using alpha blending
;$hPen = _GDIPlus_PenCreate (0x2F111111)
    
    $Array_of_Details[0] = 0.50; array of detail levels
    $Array_of_Details[1] = 1.00
    $Array_of_Details[2] = 1.50
    $Array_of_Details[3] = 2.00
    $Array_of_Details[4] = 2.50
    $Array_of_Details[5] = 3.00
    $Array_of_Details[6] = 3.50
    $Array_of_Details[7] = 4.00
    $Array_of_Details[8] = 4.50
    $Array_of_Details[9] = 5.00
    
    $speed = 1
    $wait = 5000; wait 5 sec.
    $details = $Array_of_Details[Random(0, 8, 1)]; select randomly detail level from array
    $i = 0
    $position = Random(2, 360, 1); set position for x2 and y2
    $radius = Random($y / 8, $y / 2, 1); set radius of the circle
    $diameter = $radius * 2
    $radians = 180 * $details;Random(90, 360, 1); set value convert from degrees to radians
    
    $func = Random(1, 5, 1)
    Select
        Case $func = 1
            $name = "Shell"
        Case $func = 2
            $name = "Space"
        Case $func = 3
            $name = "Star"
        Case $func = 4
            $name = "Circle"
        Case $func = 5
            $name = "Nest"
    EndSelect


    $info_pos = Random(0, $y - 55, 1); set random position on left side
    $info = GUICtrlCreateLabel($GUI_Name, 4, $info_pos, 90, 50); display info label on left side
    GUICtrlSetColor($info, 0x0000FF); set font color
    GUICtrlSetFont($info, 8); set font size
    
    $rand_pos = Random(0, $y - 20, 1)
    $rand = GUICtrlCreateLabel($name & " | " & $diameter & " | " & $details, $x - 85, $rand_pos, 100, 16); display random numbers label on right side
    GUICtrlSetColor($rand, 0x00FFFF); set font color
    GUICtrlSetFont($rand, 8); set font size
    
    GUISetState(); initialize GDI+ screen
    
    Do
        Select
            Case $func = 1
                Shell()
                $name = "Shell"
            Case $func = 2
                Space()
                $name = "Space"
            Case $func = 3
                Star()
                $name = "Star"
            Case $func = 4
                Circle()
                $name = "Circle"
            Case $func = 5
                Nest()
                $name = "Nest"
        EndSelect

        _GDIPlus_GraphicsDrawLine ($hGraphic, $x1, $y1, $x2, $y2, $hPen);draw line within the circle
        $i += 1
        Sleep($speed)
        If $i = 360 * $details Then; if drawing is nearly 360 degrees then reset screen with new settings
            $func = Random(1, 5, 1)
            Select
                Case $func = 1
                    $name = "Shell"
                Case $func = 2
                    $name = "Space"
                Case $func = 3
                    $name = "Star"
                Case $func = 4
                    $name = "Circle"
                Case $func = 5
                    $name = "Nest"
            EndSelect        
            $i = 0
            $details = $Array_of_Details[Random(0, 8, 1)]
            $position = Random(2, 360, 1)
            $radius = Random($y / 8, $y / 2, 1)
            $diameter = $radius * 2
            $radians = 180 * $details;Random(90, 360, 1)
            Sleep ($wait)
            
            $rand = GUICtrlCreateLabel("", $x - 85, $rand_pos, 100, 30); delete font on right side
            $info = GUICtrlCreateLabel("", 4, $info_pos, 90, 50); delete font left side
            
            $rand_pos = Random(0, $y - 20, 1); set new position for information right
            $rand = GUICtrlCreateLabel($name & " | " & $diameter & " | " & $details, $x - 85, $rand_pos, 100, 16); print information
            GUICtrlSetColor($rand, 0x00FFFF); set font color
            $info_pos = Random(0, $y - 55, 1); set new position for information left
            $info = GUICtrlCreateLabel($GUI_Name, 4, $info_pos, 90, 50); print information
            GUICtrlSetColor($info, 0x0000FF); set font color
            
            $stRegion = DllStructCreate($tagRECT); delete whole screen
            DllStructSetData($stRegion, 1, 0)
            DllStructSetData($stRegion, 2, 0)
            DllStructSetData($stRegion, 3, $x)
            DllStructSetData($stRegion, 4, $y)
            _WinAPI_InvalidateRect($hGUI, $stRegion, True)
        EndIf
    Until _SS_ShouldExit()

    Quit()
EndFunc

Func UEZConfig()

    MsgBox(64,  "Information", "Nothing to configure yet, maybe later;-)" & @CRLF & @CRLF & _
                "UEZ  ©  " & $build, 15)
EndFunc


Func Test()
        Local $a, $b
        $a = ATan(($i / $Pi / 45))
        $b = $i /  $pi / 270
        $x1 = Cos ($radius * $i / 360) + ($x / 2)
        $y1 = Tan ($radius * $i / 180) + ($x / 2)
        $x2 = $i / 4
        $y2 = $i / 6
EndFunc

Func Nest()
        Local $a
        $a = ATan((Sqrt($i * $Pi / 180)))
        $x1 = $radius * Cos($i / Sqrt($Pi * $radians)) / $a + $x / 2; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i / Sqrt($Pi * $radians)) / $a + $y / 2; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Sin($position / $i * Sqrt($Pi * $radians)) / $a + $x / 2; create x2 position on space starting from the middle of the screen
        $y2 = $radius * Cos($position / $i * Sqrt($Pi * $radians)) / $a + $y / 2; create y2 position on Space starting from the middle of the screen
EndFunc
    
Func Shell()
        Local $a
        $a = Sin($i / 180 / $Pi) / Cos($i * 180 * $Pi)
        $x1 = $radius * Cos($i * Sin($Pi / $radians)) * $a + $x / 2; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i * Sin($Pi / $radians)) * $a + $y / 2; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Cos($position * $i * Cos($Pi / $radians)) * $a + $x / 2; create x2 position on space starting from the middle of the screen
        $y2 = $radius * Sin($position * $i * Cos($Pi / $radians)) * $a + $y / 2; create y2 position on Space starting from the middle of the screen
EndFunc
    
Func Space()
        Local $a
        $a = Cos($i) * Sin($i) / ATan($i) * $Pi
        $x1 = $radius * Cos($i * ($Pi / $radians)) / $a + $x / 2; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i * ($Pi / $radians)) / $a + $y / 2; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Cos($position * $i * ($Pi / $radians)) / $a + $x / 2; create x2 position on space starting from the middle of the screen
        $y2 = $radius * Sin($position * $i * ($Pi / $radians)) / $a + $y / 2; create y2 position on Space starting from the middle of the screen
EndFunc
    
Func Star()
        $x1 = $radius * Cos($i * ($Pi / $radians)) * ATan($i) + $x / 2; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i * ($Pi / $radians)) / Tan($i) + $y / 2; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Cos($position * $i * ($Pi / $radians)) * Tan($i) + $x / 2; create x2 position on star starting from the middle of the screen
        $y2 = $radius * Sin($position * $i * ($Pi / $radians)) / Tan($i) + $y / 2; create y2 position on star starting from the middle of the screen
EndFunc
    
Func Circle()
        $x1 = $radius * Cos($i * ($Pi / $radians)) + $x / 2; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i * ($Pi / $radians)) + $y / 2; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Cos($position * $i * ($Pi / $radians)) + $x / 2; create x2 position on circle starting from the middle of the screen
        $y2 = $radius * Sin($position * $i * ($Pi / $radians)) + $y / 2; create y2 position on circle starting from the middle of the screen
EndFunc 

Func Quit(); exit program
    _GDIPlus_PenDispose ($hPen)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_Shutdown ()
    Exit
EndFunc

See how you don't have to worry about the commandline or showing something different for the preview window? And now if/when I make changes to the UDF, you just need to update _SS_UDF.au3 with the new version and recompile...none of your codes need change.

I didn't spend the time to go through and eliminate all the lines/vars you don't need, so this would still need cleanup if you wanted to proceed along these lines...but can you see that this is cleaner? There's just a single function that runs the main loop of the screensaver, called only when appropriate by the UDF...you don't have to touch it. The lines that make it work are

_SS_SetMainLoop("UEZMainLoop")
_SS_SetConfigLoop("UEZConfig")
_SS_Start()
just before the beginning of the function definitions. You don't even need to set the config loop to anything right now, since there's nothing to configure- the default of the UDF if you don't set this is just to pop up a message that there's nothing to configure. The _SS_Start() is the function that does all the interpreting of what mode the SS should run in, and calls the appropriate functions.

As another benefit, your screensaver will exit when most keys are pressed, rather than just escape or moving the mouse. Anything that would type will exit the screensaver (space, enter, numbers, letters, etc). This is because it's now using the _SS_GUICreate() function along with _SS_ShouldExit(), provided by the UDF.

Does that make sense?

Edited by james3mg
"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

Thank you very much but I have still a question in my mind: what is wrong (preview part) with my orginal code? Why does the process not terminate properly?

Anyway, I can use my ss with your UDF :D

It is ok to exit the ss when pressing any key instead of ESC only.

I will test the multi monitor behaviour tomorrow in my office... :D

Now it's time to go to bed :)

UEZ

PS: on the left side the info label gone away - I will fix it.

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Thank you very much but I have still a question in my mind: what is wrong (preview part) with my orginal code? Why does the process not terminate properly?

You needed to check and see if the GUI you created still exists at the same time you check if $GUI_EVENT_CLOSE was sent. (see the post just above my previous one where I rewrote your script). If either of these conditions exist, the script should exit. What happens is that since the preview GUI is a child of the Screensaver Configuration dialog, it closes your preview window (not the script, just the window) when the dialog is closed. So if the window no longer exists, the whole script should exit.

I still think there should be a better way to find out if Windows wants the preview to close, but I haven't found it yet. If I find it, I'll update the UDF. And since you're using the UDF now, it'll be seamless for you...just update the UDF file and recompile.

I can use my ss with your UDF :D

I'm glad. I think you'll find it cleaner this way. Just go through your script and clean it up a bit from the mess I left it- you probably don't need $x AND $_SS_WinWidth, or $hGUI AND $hWnd, for instance.

Keep in mind that when the fullscreen screensaver is running, $VirtualDesktopWidth is equal to $_SS_WinWidth, but when it's only the preview window running, $_SS_WinWidth is only the width of the preview window. (same principles apply for the height vars). I did that on purpose, so you can always find the full size of the desktop (across all monitors) using $VirtualDesktopWidth, if you need it for something. So be sure to call the correct one at all times (it will almost always be $_SS_WinWidth you want to work with).

By the way, I as reviewing the code I provided you, and realized that there was a lot of code in UEZMainLoop() that should be called before _SS_Start(). Everything from the top of the UEZMainLoop() function down to the line with GUISetState() should be moved out of the function and put in the main body of the script above _SS_SetMainLoop(), _SS_SetConfigLoop() and _SS_Start(). Also, you don't need to GUISetState() the screensaver window at all- that's handled by _SS_Start(). So the only thing left in UEZMainLoop() should be your do...until loop and the call to Quit() afterward. It probably won't make a big performance difference, but that's the way it's designed to run- set up the window before you call _SS_Start(), and let your loop just be whatever changes over time in the window.

(The worst side effect of running the code I provided last time is that two windows are created, one always being invisible...probably not a big deal, but this keeps your code compartmentalized better).

Be sure to let us see your screensaver when it's all done- it looks great so far! :D

"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

...

Be sure to let us see your screensaver when it's all done- it looks great so far! :D

My favorite is the CIRCLE routine :D

Here the status of multi monitor experience:

The 2nd monitor is set to be on top of the 1st (primary) monitor. When the screen saver starts the 2nd monitors stays as it is (not blanked) and the high of 1st monitor gets double.

That means the draws are on the buttom of the 1st monitor not in the middle.

Now when I set up the 2nd monitor to be e.g. on the right side of 1st monitor than also the 2nd monitor is a part of the ss (virtual size).

When I select the build-in ss from MS and press on preview and 2nd monitor is again on the top of 1st monitor, then also 2nd monitor is a part of the ss (working correctly).

Conclusion: the virtual desktop routine is not working properly.

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Conclusion: the virtual desktop routine is not working properly.

Sounds that way, indeed. So what I'm hearing is that the screensaver window is (probably) the correct height and width, but is located at the wrong place. It sounds to me like Windows must always put the 0,0 coordinates of the desktop at the top-left of the PRIMARY monitor, rather than at the top-left of the virtual desktop extents. My guess is the same thing would happen if the secondary monitor was to the left of your primary monitor, except the center of your routines would occur on the right side of the primary monitor.

There's probably a way to call DLLCall("user32.dll", "int", "GetSystemMetrics", "int", IntHERE) to have it return some data that would be helpful to us- maybe the top-left coord of the virtual desktop (which is where our screensaver window should be, rather than at 0,0). If you'll stick around (or come back) in 2 to 3 hours, I'll try to find out what data it is we need to pull, and I'll give you a script to run and post back the results for me to analyze and use to update the UDF.

Stick with me...we'll get this solved! :D

"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

Multi monitor test (number = monitor position and typ):

2

1 -> ss is running only on monitor 1 and y screen resolution on monitor 1 is probably 1+2

12 -> ss is working properly (on both)

21 -> only working on 1 and x screen resolution on monitor 1 is probably 1+2

1

2 -> ss is working properly (on both)

1 is running on 1680x1050 (laptop)

2 is running on 1280x1024

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Got it working.

I found from http://msdn2.microsoft.com/en-us/library/m...385(VS.85).aspx that values 76 and 77 return the X and Y coordinate of the top-left of the virtual desktop (values 78 and 79 are the values I'd already used to find the width and height of the virtual desktop). So I've incorporated those into the _SS_GUICreate() function.

Just update the UDF file with the new one in my first post (1.2.0.0) and try your script again. It should have the multi-monitor support you expect.

Let me know :D

"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

Thanks again, it's working but I don't like it when the lines are spread over 2 screens because of the borders of both monitors.

The primary will be used and there the lines will be centred.

Finally I solved the process terminating problem and also implemented preview.

I got now 2 versions: 1st is with your include and 2nd with my original code (I made some changes).

Here with my code:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=D:\Coding\Scripts\AU3\Au3GlPlugin\Star.ico
#AutoIt3Wrapper_outfile=Magic Lines Screensaver.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_Description=Very simple screensaver coded in AutoIT
#AutoIt3Wrapper_Res_Fileversion=1.0.0.0
#AutoIt3Wrapper_Res_Language=1033
://////=__=
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=n


#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>


Opt('MustDeclareVars', 1)
Opt("ColorMode", 1)
Opt("GUIOnEventMode", 1)
Opt("TrayIconHide", 1)

If WinExists("ScrnSav:" & @ScriptFullPath) Then WinKill("ScrnSav:" & @ScriptFullPath)
AutoItWinSetTitle("ScrnSav:" & @ScriptFullPath)

Global $CommandLine

Const $appname = "Magic Lines Screensaver"
Const $ver = "0.75"
Const $build = "2008-04-17"

Global $hGUI, $hWnd, $hGraphic, $hPen, $x, $y, $x1, $x2, $y1, $y2, $i, $position, $radius, $radians, $stRegion 
Global $GUI_Name, $info, $info_pos, $rand, $rand_pos, $details, $wait, $diameter, $speed, $func, $func_detail, $name
Global $VirtualDesktopHeight, $VirtualDesktopWidth, $VirtualDesktopX, $VirtualDesktopY
Dim $Array_of_Details[10]
Global Const $Pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062

$VirtualDesktopWidth = DLLCall("user32.dll", "int", "GetSystemMetrics", "int", 78);sm_virtualwidth
$VirtualDesktopWidth = $VirtualDesktopWidth[0]
$VirtualDesktopHeight = DLLCall("user32.dll", "int", "GetSystemMetrics", "int", 79);sm_virtualheight
$VirtualDesktopHeight = $VirtualDesktopHeight[0]
$VirtualDesktopX = DLLCall("user32.dll", "int", "GetSystemMetrics", "int", 76);sm_xvirtualscreen
$VirtualDesktopX = $VirtualDesktopX[0]
$VirtualDesktopY = DLLCall("user32.dll", "int", "GetSystemMetrics", "int", 77);sm_yvirtualscreen
$VirtualDesktopY = $VirtualDesktopY[0]


If $CmdLine[0] > 0 Then
    $CommandLine = StringLeft($CmdLine[1], 2)
Else
    $CommandLine = "/s"
EndIf

If $CommandLine = "/s" Then

    $x = @DesktopWidth
    $y = @DesktopHeight

    $GUI_Name = $appname & " v" & $build & " by UEZ"
    $hGUI = GUICreate($GUI_Name, $x, $VirtualDesktopHeight, 0, $VirtualDesktopY, $WS_POPUP, BitOr($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
    $hWnd = WinGetHandle($GUI_Name)
    
    GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "Quit") ; exit program on mouse move
    HotKeySet("{ESC}", "Quit") ; or when ESC is pressed
    GUISetCursor(16, 1) ; hide mouse cursor 
    GUISetBkColor (0x000000) ; set screen backround

    _GDIPlus_Startup () ; initialize GDI+
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd)
    $hPen = _GDIPlus_PenCreate (0x2FFFFFFF) ; define draw color using alpha blending

    Ini()
    
    GUISetState() ; initialize GDI+ screen
    Do
        Draw() ; draw lines
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    
ElseIf $CommandLine = "/c" Then
    MsgBox(64,  "Information", "Nothing to configure yet, maybe later ;-)" & @CRLF & @CRLF & _
                "UEZ  (c)  " & $build, 15)
    Exit
ElseIf $CommandLine = "/p" Then ;display little preview
    Global $USER32
    $x = 152
    $y = 112
    Global $hGUI = GUICreate($appname, $x, $y, 0, 0, 0x80000000)
    $hWnd = WinGetHandle($hGUI)
    $USER32 = DllOpen("user32.dll") 
    DllCall($USER32, "int", "SetParent", "hwnd", $hGUI, "hwnd", HWnd($CmdLine[2])) ;set preview window
    DllClose($USER32)
    GUISetState()
    GUISetBkColor(0x000000)
    _GDIPlus_Startup () ; initialize GDI+
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd)
    $hPen = _GDIPlus_PenCreate (0x7FFFFFFF) ; define draw color using alpha blending
    $VirtualDesktopY = 0
    Ini()
    While 1
        If NOT WinExists(HWnd($CmdLine[2])) Then Exit
        Draw()
    WEnd
    Quit()
EndIf

Exit

Func Ini()
    $Array_of_Details[0] = 0.50 ; array of detail levels
    $Array_of_Details[1] = 1.00
    $Array_of_Details[2] = 1.50
    $Array_of_Details[3] = 2.00
    $Array_of_Details[4] = 2.50
    $Array_of_Details[5] = 3.00
    $Array_of_Details[6] = 3.50
    $Array_of_Details[7] = 4.00
    $Array_of_Details[8] = 4.50
    $Array_of_Details[9] = 5.00
    
    $speed = 1
    $wait = 5000 ; wait 5 sec.
    $details = $Array_of_Details[Random(0, 8, 1)] ; select randomly detail level from array
    $i = 0
    $position = Random(2, 360, 1) ; set position for x2 and y2
    $radius = Random($y / 12, $y / 2, 1) ; set radius of the circle
    $diameter = $radius * 2
    $radians = 180 * $details ;Random(90, 360, 1) ; set value convert from degrees to radians
    
    $func = Random(1, 5, 1) ; set random function call
    Select
        Case $func = 1
            $name = "Shell"
        Case $func = 2
            $name = "Space"
        Case $func = 3
            $name = "Star"
        Case $func = 4
            $name = "Circle"
        Case $func = 5
            $name = "Nest"
    EndSelect
EndFunc

Func Draw()
        Select
            Case $func = 1
                Shell()
                $name = "Shell"
            Case $func = 2
                Space()
                $name = "Space"
            Case $func = 3
                Star()
                $name = "Star"
            Case $func = 4
                Circle()
                $name = "Circle"
            Case $func = 5
                Nest()
                $name = "Nest"
        EndSelect

        _GDIPlus_GraphicsDrawLine ($hGraphic, $x1, Abs($VirtualDesktopY) + $y1, $x2, Abs($VirtualDesktopY) + $y2, $hPen) ;draw line within the circle
        $i += 1
        Sleep($speed)
        If $i = 360 * $details * $func_detail Then ; if drawing is nearly 360 degrees then reset screen with new settings
            $func = Random(1, 5, 1)
            Select
                Case $func = 1
                    $name = "Shell"
                Case $func = 2
                    $name = "Space"
                Case $func = 3
                    $name = "Star"
                Case $func = 4
                    $name = "Circle"
                Case $func = 5
                    $name = "Nest"
            EndSelect           
            $i = 0
            $details = $Array_of_Details[Random(0, 8, 1)]
            $position = Random(2, 360, 1)
            $radius = Random($y / 12, $y / 2, 1)
            $diameter = $radius * 2
            $radians = 180 * $details ;Random(90, 360, 1)
            Sleep ($wait)
            
                 $stRegion = DllStructCreate($tagRECT) ; delete whole screen
            DllStructSetData($stRegion, 1, 0)
            DllStructSetData($stRegion, 2, 0)
            DllStructSetData($stRegion, 3, $x + Abs($VirtualDesktopY))
            DllStructSetData($stRegion, 4, $y + Abs($VirtualDesktopY))
            _WinAPI_InvalidateRect($hGUI, $stRegion, True)
        EndIf
EndFunc

Func Nest()
        Local $a
        $a = ATan((Sqrt($i * $Pi / 180)))
        $x1 = $radius * Cos($i / Sqrt($Pi * $radians)) / $a + $x / 2 ; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i / Sqrt($Pi * $radians)) / $a + $y / 2 ; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Sin($position / $i * Sqrt($Pi * $radians)) / $a + $x / 2 ; create x2 position on space starting from the middle of the screen
        $y2 = $radius * Cos($position / $i * Sqrt($Pi * $radians)) / $a + $y / 2 ; create y2 position on Space starting from the middle of the screen
        $func_detail = 1.50
EndFunc
    
Func Shell()
        Local $a
        $a = Sin($i / 180 / $Pi) / Cos($i * 180 * $Pi)
        $x1 = $radius * Cos($i * Sin($Pi / $radians)) * $a + $x / 2 ; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i * Sin($Pi / $radians)) * $a + $y / 2 ; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Cos($position * $i * Cos($Pi / $radians)) * $a + $x / 2 ; create x2 position on space starting from the middle of the screen
        $y2 = $radius * Sin($position * $i * Cos($Pi / $radians)) * $a + $y / 2 ; create y2 position on Space starting from the middle of the screen
        $func_detail = 1.0
EndFunc
    
Func Space()
        Local $a
        $a = Cos($i) * Sin($i) / ATan($i) * $Pi
        $x1 = $radius * Cos($i * ($Pi / $radians)) / $a + $x / 2 ; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i * ($Pi / $radians)) / $a + $y / 2 ; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Cos($position * $i * ($Pi / $radians)) / $a + $x / 2 ; create x2 position on space starting from the middle of the screen
        $y2 = $radius * Sin($position * $i * ($Pi / $radians)) / $a + $y / 2 ; create y2 position on Space starting from the middle of the screen
        $func_detail = 1.50
EndFunc
    
Func Star()
        $x1 = $radius * Cos($i * ($Pi / $radians)) * ATan($i) + $x / 2 ; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i * ($Pi / $radians)) / Tan($i) + $y / 2 ; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Cos($position * $i * ($Pi / $radians)) * Tan($i) + $x / 2 ; create x2 position on star starting from the middle of the screen
        $y2 = $radius * Sin($position * $i * ($Pi / $radians)) / Tan($i) + $y / 2 ; create y2 position on star starting from the middle of the screen
        $func_detail = 1.0
EndFunc
    
Func Circle()
        $x1 = $radius * Cos($i * ($Pi / $radians)) + $x / 2 ; create x1 position on circle starting from the middle of the screen
        $y1 = $radius * Sin($i * ($Pi / $radians)) + $y / 2 ; create y1 position on circle starting from the middle of the screen
        $x2 = $radius * Cos($position * $i * ($Pi / $radians)) + $x / 2 ; create x2 position on circle starting from the middle of the screen
        $y2 = $radius * Sin($position * $i * ($Pi / $radians)) + $y / 2 ; create y2 position on circle starting from the middle of the screen
        $func_detail = 1.0
EndFunc 

Func Quit() ; exit program
    _GDIPlus_PenDispose ($hPen)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_Shutdown ()
    Exit
EndFunc

Still to do: Config Window

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...