Jump to content

Analog Clock


greenmachine
 Share

Recommended Posts

With v1.0.4: Open clock, open notepad, pass notepad over clock, and watch: the hands redraw but the ticks do not.

As for the multithreading, the though had crossed my mind so that you would have a faster redraw rate than 1 fps. I didn't pursue it because I wasn't sure if you would be interested.. now I'll give it a go :think:

Hmm, yes I see.. it's because I have them redraw only when it is active again, and not when it is inactive (which would be ok if it was minimized or completely hidden, but that isn't always the case). I suppose having it redraw the ticks every second wouldn't be too bad...

One thing I (or we if you're going to work on it too) have to watch out for is redrawing too quickly. It flashes and doesn't catch all the lines all the time.

Edit - How about this: I keep the hands updating every second (to avoid flicker and misdraw), but allow the ticks to be drawn every frame (under conditions). Since the ticks don't move, there isn't as much of a chance of misdraw.

Edited by greenmachine
Link to comment
Share on other sites

  • Replies 58
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

This is really excellent work for such a short period of time, and the code is well laid out, Well done!

Just had an :think: (just to make the code a bit bigger hehe)

Would be cool to have several clocks showing different world times, London, Tokyo, New York etc... :(

Edited by Lakes

2015 - Still no flying cars, instead blankets with sleeves.

Link to comment
Share on other sites

Ok, so I had to modify the current version of Coroutine.au3 to allow two-way communication between the child and parent scripts. It's a beta version, but it should work for your purposes. Here's the multithreaded function "Drawer()":

Func Drawer($GUI)
    $user32_dll = DllOpen("user32.dll")
    $gdi_dll = DllOpen("gdi32.dll")
    $GUIHDC = DllCall ($user32_dll,"int","GetDC","hwnd", $GUI)
    $GUIHDC = $GUIHDC[0]
    Dim $Pens[7]
    $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "0", "hwnd", "0x00FFFFFF"); small background pen
    $Pens[0] = $Pen[0]
    $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "2", "hwnd", "0x00FFFFFF"); medium background pen
    $Pens[1] = $Pen[0]
    $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "3", "hwnd", "0x00FFFFFF"); large background pen
    $Pens[2] = $Pen[0]
    $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "0", "hwnd", "0x000000FF"); small red pen (second hand)
    $Pens[3] = $Pen[0]
    $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "2", "hwnd", "0x00000000"); medium black pen
    $Pens[4] = $Pen[0]
    $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "3", "hwnd", "0x00000000"); large black pen
    $Pens[5] = $Pen[0]
    $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "0", "hwnd", "0x00000000"); small black pen
    $Pens[6] = $Pen[0]
    $lineArr = "start"
    While $lineArr <> "exit"
        If IsArray($lineArr) Then
            For $i = 0 To UBound($lineArr, 1) - 1
                DllCall ($gdi_dll, "hwnd", "SelectObject", "hwnd", $GUIHDC, "hwnd", $Pens[$lineArr[$i][0])
                DllCall ($gdi_dll, "int", "MoveToEx", "hwnd", $GUIHDC, "int", $lineArr[$i][1], "int", $lineArr[$i][2], "ptr", 0)
                DllCall ($gdi_dll, "int", "LineTo", "hwnd", $GUIHDC, "int", $lineArr[$i][3], "int", $lineArr[$i][4])
            Next
            $test = _CoYield(1);Peek to check for new/different lines
            If @extended == 1 Then
                $lineArr = $test
            EndIf
            Sleep(50)
        EndIf
    WEnd
    DllCall ($user32_dll,"int","ReleaseDC","int",$GUIHDC[0],"hwnd",$GUI_Clock)
    DllClose($gdi_dll)
    DllClose($user32_dll)
EndFunc

The way you use it is to pass the $GUI handle when you start the function like this:

$Drawer = _CoCreate('Func Drawer($GUI)| $user32_dll = DllOpen("user32.dll")|    $gdi_dll = DllOpen("gdi32.dll")|    $GUIHDC = DllCall ($user32_dll,"int","GetDC","hwnd", $GUI)| $GUIHDC = $GUIHDC[0]|   Dim $Pens[7]|   $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "0", "hwnd", "0x00FFFFFF"); small background pen| $Pens[0] = $Pen[0]| $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "2", "hwnd", "0x00FFFFFF"); medium background pen|    $Pens[1] = $Pen[0]| $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "3", "hwnd", "0x00FFFFFF"); large background pen| $Pens[2] = $Pen[0]| $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "0", "hwnd", "0x000000FF"); small red pen (second hand)|  $Pens[3] = $Pen[0]| $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "2", "hwnd", "0x00000000"); medium black pen| $Pens[4] = $Pen[0]| $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "3", "hwnd", "0x00000000"); large black pen|  $Pens[5] = $Pen[0]| $Pen = DllCall ($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "0", "hwnd", "0x00000000"); small black pen|  $Pens[6] = $Pen[0]| $lineArr = "start"| While $lineArr <> "exit"|       If IsArray($lineArr) Then|          For $i = 0 To UBound($lineArr, 1) - 1|              DllCall ($gdi_dll, "hwnd", "SelectObject", "hwnd", $GUIHDC, "hwnd", $Pens[$lineArr[$i][0])|             DllCall ($gdi_dll, "int", "MoveToEx", "hwnd", $GUIHDC, "int", $lineArr[$i][1], "int", $lineArr[$i][2], "ptr", 0)|               DllCall ($gdi_dll, "int", "LineTo", "hwnd", $GUIHDC, "int", $lineArr[$i][3], "int", $lineArr[$i][4])|           Next|           $test = _CoYield(1);Peek to check for new/different lines|          If @extended == 1 Then|             $lineArr = $test|           EndIf|          Sleep(50)|      EndIf|  WEnd|   DllCall ($user32_dll,"int","ReleaseDC","int",$GUIHDC[0],"hwnd",$GUI_Clock)| DllClose($gdi_dll)| DllClose($user32_dll)|EndFunc');<== End of _CoCreate() function for Drawer()
$DrawerPID = _CoStart($Drawer, '$GUI');$GUI is passed as a string on purpose

Now that the Drawer function is running as a separate process, create an array of all the lines you want to be drawn according to this scheme:

Dim $lineArr[numLines]
$lineArr[n][0] = Pen number (BackgroundPens(0-2), BlackPens(3-6))
$lineArr[n][1] = x0
$lineArr[n][2] = y0
$lineArr[n][3] = x1
$lineArr[n][4] = y1

Once you have your array of lines, pass them to the function, which is already waiting for the array, with _CoSend()

_CoSend($DrawerPID, $lineArr)

So basically replace anywhere you draw in your main script with a _CoSend() function, sending in the new/refreshed array of lines to draw. An idea for this is to have all the tick marks, and two copies of each of the hands in the array. Keep the old position as one and the new position as another set of hands. Then just change the pen colors. I know this is probably all really confusing, but I have to go to my grandma's for easter, I'll check in on your progress tonight. Attached is the version of Coroutine.au3 that you need.

Edit: Newer version of Coroutine.au3 in later post

Edited by neogia

[u]My UDFs[/u]Coroutine Multithreading UDF LibraryStringRegExp GuideRandom EncryptorArrayToDisplayString"The Brain, expecting disaster, fails to find the obvious solution." -- neogia

Link to comment
Share on other sites

Well, how long will it take you to save the .au3 and compile it?

AutoIt Scripts:Aimbot: Proof of Concept - PixelSearching Aimbot with several search/autoshoot/lock-on techniques.Sliding Toolbar - Add a nice Sliding Toolbar to your next script. Click the link to see an animation of it in action!FontInfo UDF - Get list of system fonts, or search to see if a particular font is installed.Get Extended Property UDF - Retrieve a files extended properties (e.g., video/image dimensions, file version, bitrate of song/video, etc)
Link to comment
Share on other sites

Eureka! It took a little longer than expected, but I've successfully created a multithreaded version of the clock. It's a bit cycle expensive (same for main script, but about 15%CPU for the dedicated drawer), but some tweaking could probably fix that. In any case, this version of Coroutine.au3 is still in beta, but works for this application. All you do is put Coroutine.au3 in the same directory as Clock.au3 and run the clock. The functionality of the clock is untouched except for the redrawing of the tick marks. You can test it out by passing another window in front of the clock, and it redraws everything almost instantly. It certainly took awhile longer, but this script has gotten me alot more excited about the possibilities of multithreading.

Clock.au3

Coroutine.au3

Edited by neogia

[u]My UDFs[/u]Coroutine Multithreading UDF LibraryStringRegExp GuideRandom EncryptorArrayToDisplayString"The Brain, expecting disaster, fails to find the obvious solution." -- neogia

Link to comment
Share on other sites

  • 3 weeks later...

hah! nice one green!

Every time I search the forums for something I come upon something cool like this, it's almost a defining factor of the AutoIt community. Anyways....

Cool Analog Clock, BUT, all that code and it still can't remember where I put the thing! or how big it's supposed to be! (hear me scream on launch no. 2!) With all your fancy dll calling code, a simple ini routine should be a piece of cake! AutoIt's ini handling feautures are a breeze to operate, check them out!

And strangely, the first version (from your post on page 1) runs flawlessly, but the recent download version (above) stutters, redraws itself multiple times if you resize it (overlapping clockfaces), and occasionally, regular square gui edges appear around it. Very strange.

Very cool, though. The first version!

Suggestion: make click and drag just move it! why all that extra click-click to get to a menu to do something as intuitive as a drag? click&drag does nothing at all, wastage! And with a modifier key (say, Ctrl), it could perhaps be resized, the menu being reserved for functions that actually need to be "chosen".

GUISetOnEvent($GUI_EVENT_RESIZED, "SavePrefs")

Another suggestion: if possible, I'd like the clock to hover above my workspace (always on top) with a large tranparency, so it's nearly invisible (so far so good) but, I'd like to be able to click through it. I don't know if such a thing is possible with AutoIt, but for sure, if your cool clock had this, it would become my new desktop clock!

good work, and thanks for the source.

-mu

[edit]correction, above version is from someone else, that explains it! interesting multi-threading though, neogia[/edit]

Edited by mr.underperson
Link to comment
Share on other sites

I love it. Two improvements I would like to see are:

1. The ability to choose color of face / hands

2. Anti aliased hands, the ones on it now have a bad case of the jaggies i.e. instead of smooth hands they are all /\/\/\//\/\/\/\/ on the edges.

All in all sweet clock dood, good job!

~Projects~1. iPod Ejector 1.0 - Tool Used To Eject iPod in Windows - Uses DevEject.exe :P2. SmartFTP Close Popup Tool - Closes reminders from freeware SmartFTP.~Helpful Links For New Users~1. LXP's Learning AutoIT PDF Guide - <<< Go here for a PDF Guide on learning AutoIT from the ground up!<<<2. AutoIt 1-2-3 <<<Want to learn more about AutoIT quickly? Go Here<<<3. How To Install The Beta And Production Versions Of AutoIT / SciteAutoIT

Link to comment
Share on other sites

  • 2 weeks later...

Excellent clock! :) I would suggest you to improve the hands "jump" to make it smoother..like seen on mechanical watches! You know, current quartz-like style is soooo boring :( And another tip, it would be nice if the clock would remember the last setting (size and transparency).

BTW, I tested also the multi-thread version, but I have to say that it doesn't work for me too well. At first, it takes longer to start and with significantly increased CPU eating. The initial version takes from zero to nothing while this multi-threaded version takes around 60-70% of CPU! In addition, when the clock is resized (the multithreaded one) it leaves artifacts from the previous size and also resizing as such is much slower!

Keep up good work! :D

Link to comment
Share on other sites

You're using Beta?

If Not Beta = 1 Then
     Download Beta
ElseIf Beta = 1 Then
     FileRun( analog_clock.au3 with Scite )
     Menuselect (Tools )
     MenuselectItem( Beta Run )
     If @error Then
          FileWriteLine("C:\Autoit\analog_clock.au3", "1st Line", "Dim $Mid")
     EndIf
EndIf
Edited by Daniel W.

--------------------------------------------------------------------------------------------------------------------------------Scripts : _Encrypt UDF_UniquePCCode UDF MS like calculatorInstall programm *UPDATED* --------------------------------------------------------------------------------------------------------------------------------[quote name='Helge' post='213117' date='Jul 26 2006, 10:22 AM']Have you ever tried surfing the internet with a milk-carton ?This is similar to what you're trying to do.[/quote]

Link to comment
Share on other sites

Got another idea - I love the clock and the alarm. Sizing and moving -what about having a set to default, to reset back to your specs? Also there is some weird things that happen if you try to run more than one time. Just ideas - "its hot"

2¢

All by me:

"Sometimes you have to go back to where you started, to get to where you want to go." 

"Everybody catches up with everyone, eventually" 

"As you teach others, you are really teaching yourself."

From my dad

"Do not worry about yesterday, as the only thing that you can control is tomorrow."

 

WindowsError.gif

WIKI | Tabs; | Arrays; | Strings | Wiki Arrays | How to ask a Question | Forum Search | FAQ | Tutorials | Original FAQ | ONLINE HELP | UDF's Wiki | AutoIt PDF

AutoIt Snippets | Multple Guis | Interrupting a running function | Another Send

StringRegExp | StringRegExp Help | RegEXTester | REG TUTOR | Reg TUTOT 2

AutoItSetOption | Macros | AutoIt Snippets | Wrapper | Autoit  Docs

SCITE | SciteJump | BB | MyTopics | Programming | UDFs | AutoIt 123 | UDFs Form | UDF

Learning to script | Tutorials | Documentation | IE.AU3 | Games? | FreeSoftware | Path_Online | Core Language

Programming Tips

Excel Changes

ControlHover.UDF

GDI_Plus

Draw_On_Screen

GDI Basics

GDI_More_Basics

GDI Rotate

GDI Graph

GDI  CheckExistingItems

GDI Trajectory

Replace $ghGDIPDll with $__g_hGDIPDll

DLL 101?

Array via Object

GDI Swimlane

GDI Plus French 101 Site

GDI Examples UEZ

GDI Basic Clock

GDI Detection

Ternary operator

Link to comment
Share on other sites

  • 2 weeks later...

Hmm, lots to catch up on...

@mr.underperson - Click+Drag to move, Ctrl+Click+Drag to resize, maybe Alt+Click+Drag to change transparency? I could do that with Larry's Mouse Hook dll... but if there's a way to do it without relying on third-party scripts I'd really like to know. INI saving is a piece of cake, I agree. I'll get to that too.

@Neoborn - Allowing color changing shouldn't be too tough, but I don't know how to go about making my hands anti-aliased. Do you have any ideas?

@odklizec - Could you clarify on how I would go about making the "jump" smoother? I'm not exactly sure what you mean.

@Daniel W - What?

@nitekram - Default settings and user-defined settings? I can do that.

Link to comment
Share on other sites

someone posted that he got errors when starting it ...

--------------------------------------------------------------------------------------------------------------------------------Scripts : _Encrypt UDF_UniquePCCode UDF MS like calculatorInstall programm *UPDATED* --------------------------------------------------------------------------------------------------------------------------------[quote name='Helge' post='213117' date='Jul 26 2006, 10:22 AM']Have you ever tried surfing the internet with a milk-carton ?This is similar to what you're trying to do.[/quote]

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...