AutoHotkey Community

It is currently May 27th, 2012, 7:15 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: March 26th, 2006, 7:59 pm 
Offline

Joined: July 6th, 2004, 10:07 am
Posts: 171
Location: Manchester, England.
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. :)
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 March 26th, 2006, 10:11 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 26th, 2006, 8:29 pm 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2545
Nice. Thanks :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 27th, 2006, 12:32 am 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Cool! The seconds hand moves a little irregularly, though. How hard is it to add numbers at the hour positions?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 27th, 2006, 3:24 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
Thanks for sharing this. I've moved it to the Scripts forum because it might get more attention there.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 27th, 2006, 10:03 am 
Offline

Joined: November 18th, 2005, 11:18 pm
Posts: 25
Location: Germany
this is a very good example how flexible and genius AHK-Scripts can be !

great stuff...thanks for giving several ideas :D

_________________
greets Grendel


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 27th, 2006, 7:22 pm 
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 8)


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 27th, 2006, 8:46 pm 
Offline

Joined: July 6th, 2004, 10:07 am
Posts: 171
Location: Manchester, England.
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 :roll:
@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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2006, 5:29 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
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)
}


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2006, 8:39 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 7th, 2006, 7:40 pm 
Offline

Joined: July 6th, 2004, 10:07 am
Posts: 171
Location: Manchester, England.
@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 :roll:

Back Soon
Regards
Dave.

_________________
Simple ideas lie within reach, only of complex minds


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 7th, 2006, 8:24 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
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?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 9th, 2008, 11:35 pm 
Offline

Joined: December 11th, 2006, 4:11 pm
Posts: 242
Location: Orlando, FL
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)
}


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 22 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group