AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

UNCLE DAVID'S SNIPPETS #1 Graphics - Demo Analog Clock

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Dippy46



Joined: 06 Jul 2004
Posts: 171
Location: Manchester, England.

PostPosted: Sun Mar 26, 2006 6:59 pm    Post subject: UNCLE DAVID'S SNIPPETS #1 Graphics - Demo Analog Clock Reply with quote

Hi,all
Someone asked me recently, as to the limitations of AHK. I said that as far as I know it does'nt do three dimensional molecular transformations, BUT! we're working on it. Smile
Seriously though,the point at which Chris introduced DllCall, there ceased to be ANY limitations other than the users Imagination/Ability. I currently use a graphics library that I wrote last year. However for political reasons I can't release the Library at this time. However I have extracted some of the more salient functions and written them out as subroutines.
The code attached is intentionally verbose, and with lots of bits to tweak making it easier for newbies to grapple with.

CAVEAT: Any use of SelectObject into a DC must be matched immediately with a DeleteOject as soon as the operation it was used for, is completed. FAILURE TO DO SO WILL RESULT IN POSSIBLY FATAL MEMORY LEAKS.. YOU HAVE BEEN WARNED!.
The code attached shows basically how to set up a buffer/canvas on which to draw (avoids flicker) and then blits the result to the AhkWindow. Just a few simple draw functions such as drawing ellipses,rectangles & lines + a quick look at font handling! Feedback on this will be greatly appreciated,and questions are welcome (if I can answer them even better).
More demos will be downloadable in the near future showing simple Animations and hopefully some spriteing! So,finally as Eintein said,
"make it as simple as possible,but no simpler". Have Fun.


Code:

;;###################################################
;;##         Compiler Version 1.0.43.00            ##
;;##                                               ##
;;## SUBJECT:   GRAPHICS                           ##
;;## AUTHOR :   Dave Perrée  March 2006            ##
;;## PROGRAM:   DEMO ANALOG CLOCK Ver 1.00         ##
;;##                                               ##
;;###################################################

SetTimer,working,500
2pi := 2*3.1415926
Gui,Show, W193 H168, AhkClock_01 
;; Get handle to window we've created
hwndA := DllCall("GetActiveWindow")
;;#############################################################################
;; Some trickery! As we've made no provision to handle WM_Paint messages, the     
;; resulting display would be rather messy unless of course we never moved     
;; another window over it. The first line below is the minimum required and
;; does not affect the appearance of the window.
;; It is this line OR the one below it that fools AHK into being responsible
;; for handling the paint messages. Note also the position of the gui,-caption
;; Try remming out the winset line to see how it would appear :)
;; Not a pretty sight eh!
;;#############################################################################
;Winset,Transparent,255,AhkClock_01
Winset,Transcolor,012345 125,AhkClock_01
Gui, -CAPTION
Gosub ONCEONLY
Gosub working  ; kick straight in
Return

guiclose:
gosub ReleaseGraphics
exitapp

ONCEONLY:
;; will last for duration of program
_xx := 0   ; x cord of canvas area
_yy := 0   ; y cord   ""
_ww := 200   ; width    ""
_hh := 200   ; height   ""
gosub CreateStruc
gosub CreateBckBuffer
RETURN

Working:
;; NB: all colors in API are BGR tuples
;; popup if computer is idle > 10 minutes
IfGreater, A_TimeIdle, 600000
 winactivate,AhkClock

;; Use a rectangle to clear the canvas (invisible colour!)
hBrush  := DllCall("CreateSolidBrush", UInt,0x452301)
DllCall("SelectObject" ,UINT,memDC,uint,hBrush)
DllCall("FillRect", UInt, MemDC, Str, Rect, UInt, hBrush)
DllCall("DeleteObject", UInt, hBrush)
;-----
;; Draw 2 filled circles
;; 17 million to choose from and we always use white ? :)
hBrush  := DllCall("CreateSolidBrush", UInt,bgr(255,255,255))
DllCall("SelectObject" ,UINT,memDC,uint,hBrush)
hCurrPen := DllCall("CreatePen" ,uint,0,uint,2,uint,bgr(0,0,0))
DllCall("SelectObject" ,UINT,memDC,uint,hCurrPen)
DllCall("Ellipse",uint,memdc,uint,3,uint,3,uint,197,uint,197)
DllCall("Ellipse",uint,memdc,uint,16,uint,16,uint,184,uint,184)
DllCall("DeleteObject", UInt, hBrush) 
DllCall("DeleteObject", UInt, hCurrPen)

;; Draw some dots for the hour markers
dotpos = 0
loop 12
{
dotpos+=2pi/12
POSX := _ww/2 + 90*COS(dotpos)    
POSY := _hh/2 + 90*SIN(dotpos)
hCurrPen := DllCall("CreatePen" ,uint,0,uint,8,uint,bgr(0,0,0))
DllCall("SelectObject" ,UINT,memDC,uint,hCurrPen)
DllCall("MoveToEx" ,UINT,memDC, UINT,POSX,UINT,POSY,UINT,0)
DllCall("LineTo" ,UINT,memDC,UINT,POSX,UINT,POSY)
DllCall("DeleteObject", UInt, hCurrPen)
}
;; Draw some minute markers
dotpos = 0
loop 60
{
dotpos+=2pi/60
POSX := _ww/2 + 88*COS(dotpos)    
POSY := _hh/2 + 88*SIN(dotpos)
hCurrPen := DllCall("CreatePen" ,uint,0,uint,3,uint,bgr(0,0,0))
DllCall("SelectObject" ,UINT,memDC,uint,hCurrPen)
DllCall("MoveToEx" ,UINT,memDC, UINT,POSX,UINT,POSY,UINT,0)
DllCall("LineTo" ,UINT,memDC,UINT,POSX,UINT,POSY)
DllCall("DeleteObject", UInt, hCurrPen)
}

;;
;; HOUR HAND
HANDpos := 2pi*(((A_hour+A_min/60)*5)/60) ; creeps by minutes
hlen = 45
wide = 8
hcol := Bgr(255,150,0)
GOSUB DRAW_HAND
;;
;; MINUTE HAND
HANDpos := 2pi*((A_min/60)+(A_sec/3600)) ; creeps by seconds
HLEN = 65
WIDE = 6
HCOL := Bgr(0,255,0)
GOSUB DRAW_HAND
;; SECOND HAND
HANDpos := 2pi*(A_sec/60)
HLEN = 90
WIDE = 2
HCOL := Bgr(0,0,255)
GOSUB DRAW_HAND
;;
FormatTime, Mdate ,A_now,ddd dd MMM yy
DllCall("SetTextColor",UINT,MEMdc,UINT,0X0)
DllCall("SetBkMode",UINT,MEMdc,UINT,1) ; transparent
;; minimal font handling, I jest not - You'd better believe it !
hFont := DllCall("CreateFont",uint,14,uint,0,uint,0,uint,0 ,uint,700 ,uint,0
         ,uint,0 ,uint,0 ,uint,0 ,uint,0 , uint,0,uint,0 ,uint,0
         , verdana)
DllCall("SelectObject" ,UINT,memDC,uint,hFont)
DllCall("TextOutA",UINT,MEMDC,UINT,70,UINT,130,STR,Mdate,UINT,13)
DllCall("TextOutA",UINT,MEMDC,UINT,70,UINT,50,STR,"AutoHotkey",UINT,10)
DllCall("DeleteObject", UInt, Hfont)

;; What! no clockface numbers !! Well, go on then, Experiment :)

gosub UpdateScreen
Return


;;#############################################################################
;;             +++++++++++ END OF PROGRAM SECTION ++++++++++++++
;;#############################################################################

Bgr(_blu,_grn,_red)
{
return (_blu << 16 | _grn << 8 | _red) 
}

DRAW_HAND:
POSX := _ww/2 + hlen*COS(HANDpos-2pi/4)
POSY := _hh/2 + hlen*SIN(HANDpos-2pi/4)
hCurrPen := DllCall("CreatePen" ,uint,0,uint,wide,uint,hcol)
DllCall("SelectObject" ,UINT,memDC,uint,hCurrPen)
DllCall("MoveToEx" ,UINT,memDC, UINT,_ww/2,UINT,_hh/2,UINT,0)
DllCall("LineTo" ,UINT,memDC,UINT,POSX,UINT,POSY)
DllCall("DeleteObject", UInt, hCurrPen)
RETURN

CreateStruc:
VarSetCapacity(Rect, 16, 0)
InsertInteger(0,rect,0)   ; always zero
InsertInteger(0,rect,4)   ; always zero
InsertInteger(_ww,rect,8)
InsertInteger(_hh,rect,12)
Return

CreateBckBuffer:
ScreenDC := DllCall("GetDC", uint,hwndA)
MemDC    := DllCall("CreateCompatibleDC",uint,ScreenDC)
MemBM    := DllCall("CreateCompatibleBitmap",uint,ScreenDC ,uint,_ww,uint,_hh)
DllCall("SelectObject",uint,MemDC,uint,MemBM)
Return

ReleaseGraphics:
DllCall("ReleaseDC", UInt, 0, UInt, ScreenDC)
DllCall("DeleteObject", UInt,MemDC)
DllCall("DeleteObject", UInt,MemBM)
Return

UpdateScreen:
DllCall("BitBlt"
  ,Uint,ScreenDC,uint,_xx,uint,_yy,uint,_ww,uint,_hh
  ,Uint,MemDC,uint,0,uint,0,Uint
  ,0x00CC0020) ;; Srccopy As Is
Return

InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
; The caller must ensure that pDest has sufficient capacity.
; To preserve any existing contents in pDest,
; only pSize number of bytes starting at pOffset are altered in it.
{
   Loop %pSize% 
   DllCall("RtlFillMemory", UInt, &pDest + pOffset + A_Index-1
   , UInt, 1, UChar, pInteger >> 8*(A_Index-1) & 0xFF)
}


_________________
Simple ideas lie within reach, only of complex minds


Last edited by Dippy46 on Sun Mar 26, 2006 9:11 pm; edited 1 time in total
Back to top
View user's profile Send private message
corrupt



Joined: 29 Dec 2004
Posts: 2436

PostPosted: Sun Mar 26, 2006 7:29 pm    Post subject: Reply with quote

Nice. Thanks Smile
Back to top
View user's profile Send private message Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Sun Mar 26, 2006 11:32 pm    Post subject: Reply with quote

Cool! The seconds hand moves a little irregularly, though. How hard is it to add numbers at the hour positions?
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10480

PostPosted: Mon Mar 27, 2006 2:24 am    Post subject: Reply with quote

Thanks for sharing this. I've moved it to the Scripts forum because it might get more attention there.
Back to top
View user's profile Send private message Send e-mail
Grendel



Joined: 18 Nov 2005
Posts: 25
Location: Germany

PostPosted: Mon Mar 27, 2006 9:03 am    Post subject: Reply with quote

this is a very good example how flexible and genius AHK-Scripts can be !

great stuff...thanks for giving several ideas Very Happy
_________________
greets Grendel
Back to top
View user's profile Send private message
not-logged-in-daonlyfreez
Guest





PostPosted: Mon Mar 27, 2006 6:22 pm    Post subject: Reply with quote

Great stuff!

Thru peeking at MSDN on GDI, I quickly was able to add an Arc

Code:
hCurrPen := DllCall("CreatePen" ,uint,0,uint,1,uint,bgr(0,0,0))
DllCall("SelectObject" ,UINT,memDC,uint,hCurrPen)
DllCall("Arc",uint,memdc,uint,0,uint,0,uint,50,uint,50,uint,7,uint,12,uint,38,uint,48)
DllCall("DeleteObject", UInt, hCurrPen)


I hope this could be the start of a built-in AHK GUI Canvas Control Cool
Back to top
Dippy46



Joined: 06 Jul 2004
Posts: 171
Location: Manchester, England.

PostPosted: Mon Mar 27, 2006 7:46 pm    Post subject: Reply with quote

Hi all,
Thanx for the responses.
@Laszlo, yes re: irregularity,my fault for choosing a slow timer rate but that was done to show up the lazy graphics. Just reduce it to a more normal 100msecs or less and it should be ok!
As far as Numbers go there are several solutions ranging from the elegant thru to totally gross.
I should have some methods up on the board within the next 24hours or so Rolling Eyes
@N-L-I daonlyfreez
I have mixed feelings about adding more complexity to AHK's internal abilities, and I think in some ways it would spoil it for those users who enjoy the simplistic and friendly interface. I think it would probably be more prudent to build an official include file or rather a set of approved
includes for those users who require additional functionality. I may be wrong but there have been many posts on the subject QED.
_________________
Simple ideas lie within reach, only of complex minds
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Tue Apr 04, 2006 4:29 pm    Post subject: Reply with quote

I like this pure AHK analog clock, but it is too slow or the hands movement is irregular, so I made a little mod. The clock is updated now 4 times a second, but if the value of seconds did not change, we do nothing. This is a factor of 2 speedup, with smoother hands movement.

The original script redrew the whole clock constantly, which was slow. Instead, the outer circle and the markers are now kept unchanged, only the hands are erased and redrawn. This gives more than ten fold speedup. There are a number of simplifications for further speedup and making the script shorter. The end result is less than 1% processor load in my laptop, down from 20%, and the length of the script is reduced more than twofold.

I have my taskbar on the left edge of the screen, and the clock is docked there. Since it is transparent, I still can see or click on everything underneath. Of course the clock can be made to appear in a corner of the screen, always on top, or let it come to the top regularly, and then get back to the bottom.
Code:
OnExit GuiClose   ; Close open graphic tools
o2  = 100         ; half width/height of canvas
wh := o2*2
w16:= wh-16

Gui Show, % "X-12 Y867 W" wh "H" wh-44, AhkClock        ; <-- EDIT location
WinGet hwndA, ID, A
Winset Transcolor,012345,AhkClock
Gui -CAPTION

WinGet Tray_ID, ID, ahk_class Shell_TrayWnd             ; Dock to the TASKBAR
WinGet ClockID, ID, ahk_id %hwndA%
DllCall("SetParent", UInt, ClockID, UInt, Tray_ID)

VarSetCapacity(Rect, 16, 0)
DllCall("ntoskrnl.exe\RtlFillMemoryUlong", UInt,&rect+ 8, UInt,4, UInt,wh)
DllCall("ntoskrnl.exe\RtlFillMemoryUlong", UInt,&rect+12, UInt,4, UInt,wh)

ScreenDC:= DllCall("GetDC", UInt,hwndA)
MemDC   := DllCall("CreateCompatibleDC", UInt,ScreenDC)
MemBM   := DllCall("CreateCompatibleBitmap", UInt,ScreenDC , UInt,wh, UInt,wh)
DllCall("SelectObject", UInt,MemDC, UInt,MemBM)

hBrush  := DllCall("CreateSolidBrush", UInt,0x452301)   ; KEEP IT OPEN for inner circle
DllCall("SelectObject", UInt,memDC, UInt,hBrush)
DllCall("FillRect", UInt,MemDC, Str,Rect, UInt,hBrush)  ; Canvas of invisible color

hCurrPen:= DllCall("CreatePen", UInt,0, UInt,2, UInt,0) ; KEEP IT OPEN for inner circle
DllCall("SelectObject", UInt,memDC, UInt,hCurrPen)
DllCall("Ellipse", UInt,memdc, UInt,1, UInt,1, UInt,wh-1, UInt,wh-1) ; OUTER CIRCLE

loop 12                             ; Hour markers
   DrawHand(o2-3,.523599*A_Index, 5, 0)
loop 60                             ; Minute markers
   DrawHand( o2, .104720*A_Index, 1, 0)

SetTimer Working
RETURN

GuiClose:
   DllCall("DeleteObject", UInt,hBrush)
   DllCall("DeleteObject", UInt,hCurrPen)
   DllCall("ReleaseDC", UInt,0, UInt,ScreenDC)
   DllCall("DeleteObject", UInt,MemDC)
   DllCall("DeleteObject", UInt,MemBM)
ExitApp

Working:
   IfEqual Sec0,%A_Sec%, Return     ; No change - no draw
   Sec0 = %A_Sec%

   DllCall("SelectObject", UInt,memDC, UInt,hCurrPen)
   DllCall("Ellipse", UInt,memdc, UInt,16, UInt,16, UInt,w16, UInt,w16) ; ERASE HANDS

   DrawHand(55,.523599*A_hour+.008727*A_min-1.570796,11,0x000088) ; HOUR HAND
   DrawHand(75,.104720*A_min +.001745*A_sec-1.570796, 7,0x00FFFF) ; MINUTE HAND
   DrawHand(82,.104720*A_sec               -1.570796, 3,0xFFFFFF) ; SECOND HAND
   DrawHand(16,.104720*A_sec               +1.570796, 5,0xFFFFFF) ; "" extension

   DllCall("BitBlt", UInt,ScreenDC, UInt,0, UInt,0, UInt,wh, UInt,wh
           ,UInt,MemDC, UInt,0, UInt,0, UInt,0x00CC0020) ; SrcCopy As Is
Return

DrawHand(r,angle,width,color)
{
   Global memDC, o2
   hCurrPen := DllCall("CreatePen", UInt,0, UInt,width, UInt,color)
   DllCall("SelectObject", UInt,memDC, UInt,hCurrPen)
   DllCall("MoveToEx", UInt,memDC, UInt,o2, UInt,o2, UInt,0)
   DllCall("LineTo", UInt,memDC, UInt,Round(o2+r*cos(angle)), UInt,Round(o2+r*sin(angle)))
   DllCall("DeleteObject", UInt,hCurrPen)
}
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Tue Apr 04, 2006 7:39 pm    Post subject: Reply with quote

I updated my version with
- OnExit, to clean up when the script exits abnormally (like a new version is started)
- Round the coordinates in the DrawHand function (instead of truncating), to improve accuracy
- Colored the hands for demo

Don't forget to edit the location. On lower screen resolutions the clock could be outside.
Back to top
View user's profile Send private message
Dippy46



Joined: 06 Jul 2004
Posts: 171
Location: Manchester, England.

PostPosted: Fri Apr 07, 2006 6:40 pm    Post subject: Reply with quote

@Laszlo, Nice one!
The main reason I popped this code up was to generate a little bit of interest. Thanx for taking up the challenge. I wonder if you've sussed the best way to produce the clockface numbers Rolling Eyes

Back Soon
Regards
Dave.
_________________
Simple ideas lie within reach, only of complex minds
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Fri Apr 07, 2006 7:24 pm    Post subject: Reply with quote

As you see, no numbers in my version, either. I've been too lazy, and waited for you to do the numbers.

Another question: the lines, circles would look much nicer, with some dithering or anti-aliasing, or how is it called, when the edges of straight lines made blurry, to avoid sharp steps at pixel boundaries. Does anyone know a simple way to do it?
Back to top
View user's profile Send private message
Jaytech



Joined: 11 Dec 2006
Posts: 244
Location: Orlando, FL

PostPosted: Wed Jul 09, 2008 10:35 pm    Post subject: Reply with quote

Ok, this string has ben dead for quite some time, but I was in need of an analog clock. Finding this was a good send considering that I know almost nothing about how it works. That being said, I did make a couple small changes. I increased the size and added numbers. Woot!

So for anyone who wants it, here my additions:

Code:
;;###################################################
;;##         Compiler Version 1.0.43.00            ##
;;##                                               ##
;;## SUBJECT:   GRAPHICS                           ##
;;## AUTHOR :   Dave Perrée  March 2006            ##
;;## PROGRAM:   DEMO ANALOG CLOCK Ver 1.00         ##
;;##                                               ##
;;###################################################

SetTimer,working,500
2pi := 2*3.1415926

Gui,Show, W493 H468, AhkClock_01
;; Get handle to window we've created
hwndA := DllCall("GetActiveWindow")
;;#############################################################################
;; Some trickery! As we've made no provision to handle WM_Paint messages, the     
;; resulting display would be rather messy unless of course we never moved     
;; another window over it. The first line below is the minimum required and
;; does not affect the appearance of the window.
;; It is this line OR the one below it that fools AHK into being responsible
;; for handling the paint messages. Note also the position of the gui,-caption
;; Try remming out the winset line to see how it would appear :)
;; Not a pretty sight eh!
;;#############################################################################
;Winset,Transparent,255,AhkClock_01
Gui, -CAPTION
Winset,Transcolor,012345 125,AhkClock_01

Gosub ONCEONLY
Gosub working  ; kick straight in
Return

guiclose:
gosub ReleaseGraphics
exitapp

ONCEONLY:
;; will last for duration of program
_xx := 0   ; x cord of canvas area
_yy := 0   ; y cord   ""
_ww := 500   ; width    ""
_hh := 500   ; height   ""
gosub CreateStruc
gosub CreateBckBuffer
RETURN

Working:
;; NB: all colors in API are BGR tuples
;; popup if computer is idle > 10 minutes
IfGreater, A_TimeIdle, 600000
 winactivate,AhkClock

;; Use a rectangle to clear the canvas (invisible colour!)
hBrush  := DllCall("CreateSolidBrush", UInt,0x452301)
DllCall("SelectObject" ,UINT,memDC,uint,hBrush)
DllCall("FillRect", UInt, MemDC, Str, Rect, UInt, hBrush)
DllCall("DeleteObject", UInt, hBrush)
;-----
;; Draw 2 filled circles
;; 17 million to choose from and we always use white ? :)
hBrush  := DllCall("CreateSolidBrush", UInt,bgr(255,255,255))
DllCall("SelectObject" ,UINT,memDC,uint,hBrush)
hCurrPen := DllCall("CreatePen" ,uint,0,uint,2,uint,bgr(0,0,0))
DllCall("SelectObject" ,UINT,memDC,uint,hCurrPen)
DllCall("Ellipse",uint,memdc,uint,3,uint,3,uint,497,uint,497)
DllCall("Ellipse",uint,memdc,uint,16,uint,16,uint,484,uint,484)
DllCall("DeleteObject", UInt, hBrush)
DllCall("DeleteObject", UInt, hCurrPen)


;; Draw some numbers                        ;New
loop 12                              ;New
{                              ;New
dotpos+=2pi/12                           ;New
POSX := _ww/2 + 220*COS(dotpos)-5                  ;New
POSY := _hh/2 + 220*SIN(dotpos)-12                  ;New
IfEqual, A_Index, 1                        ;New
   Index=3                           ;New
Index+=1                           ;New
IfGreater, Index, 12                        ;New
Index-=12                           ;New
Len:=StrLen(Index)                        ;New
ifEqual, Len, 2                           ;New
   POSX-=5                           ;New
DllCall("SetTextColor",UINT,MEMdc,UINT,0X0)               ;New
DllCall("SetBkMode",UINT,MEMdc,UINT,1) ; transparent            ;New
hFont := DllCall("CreateFont",uint,24,uint,0,uint,0,uint,0 ,uint,700 ,uint,0   ;New
         ,uint,0 ,uint,0 ,uint,0 ,uint,0 , uint,0,uint,0 ,uint,0      ;New
         , verdana)                        ;New
DllCall("SelectObject" ,UINT,memDC,uint,hFont)               ;New
DllCall("TextOutA",UINT,MEMDC,UINT,POSX,UINT,POSY,STR,Index,UINT,Len)      ;New
}




;; Draw some minute markers
dotpos = 0
loop 60
{
dotpos+=2pi/60
Dot_Test:=Mod(A_Index,5)                     ;New
IfEqual, Dot_Test, 0                        ;New
   CONTINUE                        ;New
POSX := _ww/2 + 218*COS(dotpos)   
POSY := _hh/2 + 218*SIN(dotpos)
hCurrPen := DllCall("CreatePen" ,uint,0,uint,4,uint,bgr(0,0,0))
DllCall("SelectObject" ,UINT,memDC,uint,hCurrPen)
DllCall("MoveToEx" ,UINT,memDC, UINT,POSX,UINT,POSY,UINT,0)
DllCall("LineTo" ,UINT,memDC,UINT,POSX,UINT,POSY)
DllCall("DeleteObject", UInt, hCurrPen)
}

;;
;; HOUR HAND
HANDpos := 2pi*(((A_hour+A_min/60)*5)/60) ; creeps by minutes
hlen = 175
wide = 8
hcol := Bgr(255,150,0)
GOSUB DRAW_HAND
;;
;; MINUTE HAND
HANDpos := 2pi*((A_min/60)+(A_sec/3600)) ; creeps by seconds
HLEN = 195
WIDE = 6
HCOL := Bgr(0,255,0)
GOSUB DRAW_HAND
;; SECOND HAND
HANDpos := 2pi*(A_sec/60)
HLEN = 220
WIDE = 2
HCOL := Bgr(0,0,255)
GOSUB DRAW_HAND
;;
FormatTime, Mdate ,A_now,ddd dd MMM yy
DllCall("SetTextColor",UINT,MEMdc,UINT,0X0)
DllCall("SetBkMode",UINT,MEMdc,UINT,1) ; transparent
;; minimal font handling, I jest not - You'd better believe it !
hFont := DllCall("CreateFont",uint,24,uint,0,uint,0,uint,0 ,uint,700 ,uint,0
         ,uint,0 ,uint,0 ,uint,0 ,uint,0 , uint,0,uint,0 ,uint,0
         , verdana)
DllCall("SelectObject" ,UINT,memDC,uint,hFont)
DllCall("TextOutA",UINT,MEMDC,UINT,190,UINT,340,STR,Mdate,UINT,13)
DllCall("TextOutA",UINT,MEMDC,UINT,215,UINT,140,STR,"Jaytech",UINT,7)      ;Vanity Plate :)
DllCall("DeleteObject", UInt, Hfont)

;; What! no clockface numbers !! Well, go on then, Experiment :)
gosub UpdateScreen
Return


;;#############################################################################
;;             +++++++++++ END OF PROGRAM SECTION ++++++++++++++
;;#############################################################################

Bgr(_blu,_grn,_red)
{
return (_blu << 16 | _grn << 8 | _red)
}

DRAW_HAND:
POSX := _ww/2 + hlen*COS(HANDpos-2pi/4)
POSY := _hh/2 + hlen*SIN(HANDpos-2pi/4)
hCurrPen := DllCall("CreatePen" ,uint,0,uint,wide,uint,hcol)
DllCall("SelectObject" ,UINT,memDC,uint,hCurrPen)
DllCall("MoveToEx" ,UINT,memDC, UINT,_ww/2,UINT,_hh/2,UINT,0)
DllCall("LineTo" ,UINT,memDC,UINT,POSX,UINT,POSY)
DllCall("DeleteObject", UInt, hCurrPen)
RETURN

CreateStruc:
VarSetCapacity(Rect, 16, 0)
InsertInteger(0,rect,0)   ; always zero
InsertInteger(0,rect,4)   ; always zero
InsertInteger(_ww,rect,8)
InsertInteger(_hh,rect,12)
Return

CreateBckBuffer:
ScreenDC := DllCall("GetDC", uint,hwndA)
MemDC    := DllCall("CreateCompatibleDC",uint,ScreenDC)
MemBM    := DllCall("CreateCompatibleBitmap",uint,ScreenDC ,uint,_ww,uint,_hh)
DllCall("SelectObject",uint,MemDC,uint,MemBM)
Return

ReleaseGraphics:
DllCall("ReleaseDC", UInt, 0, UInt, ScreenDC)
DllCall("DeleteObject", UInt,MemDC)
DllCall("DeleteObject", UInt,MemBM)
Return

UpdateScreen:
DllCall("BitBlt"
  ,Uint,ScreenDC,uint,_xx,uint,_yy,uint,_ww,uint,_hh
  ,Uint,MemDC,uint,0,uint,0,Uint
  ,0x00CC0020) ;; Srccopy As Is
Return

InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
; The caller must ensure that pDest has sufficient capacity.
; To preserve any existing contents in pDest,
; only pSize number of bytes starting at pOffset are altered in it.
{
   Loop %pSize%
   DllCall("RtlFillMemory", UInt, &pDest + pOffset + A_Index-1
   , UInt, 1, UChar, pInteger >> 8*(A_Index-1) & 0xFF)
}
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group