Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Taskbar Clock/Calendar with Processor and Memory Load bars


  • Please log in to reply
8 replies to this topic
Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Using three jewels found by Shimanov and antonyb, docking a window to the taskbar, calculating the processor- and memory load became easier. Here is an application of them and the DateTime GUI control: an easily configurable taskbar clock with extras. My taskbar is 180 pixels wide on the left of my high resolution screen. You have to modify the settings in the beginning of the script to get the best looking result. (With this adaptability and the many features the script has about 100 code lines, but hopefully the structure is clear, and you can find the part you want to tinker with.)

At start two slimmed down progress bars are created and docked to the taskbar with the Dock2Taskbar subroutine (only 3 lines long). They will show the processor load (blue bar) and the free/total memory ratio (red bar). Also, a simple GUI is docked between them. It has only a single DateTime control, no border, no caption to save screen space. The window is smaller than its control, to hide margins and the triangle of the DateTime control. (The script was extracted from a large one, this is why the GUI is number seven, not for reminding the reader about the number of days in a week.)

The progress bars are updated by a timer every second, showing the average processor load during this time and the current ratio of the free- and the total physical memory. These give valuable information about the available power of the computer.

The clock is updated 4 times a second, to achieve better response for the mouse functions:

- Hovering the mouse pointer over the clock shows a tooltip with the full date and time information.

- A left click on the active clock pops up the standard calendar. (If the clock is not active, a left click activates it, and the second click pops up the calendar.) In the calendar you can navigate back and forth on the months, select the month from a popup list, increase/decrease the year to see any past or future date. Esc or a click closes the calendar.

- A right click on the clock pops up a menu, which offers to call the date/time adjustment function of Windows; to copy the full date/time information to the clipboard or exit. An example of the clipboard is below:

2005 November 9, 6:02:18 PM
Wednesday. Day: 313, Week: 45

For different format or information edit the function FullDT(), which is at the end of the script.
#NoTrayIcon                ; Save space w/o icon/menu

;----- edit here for best look -----

X0        = 0              ; X coordinate of the left edge
FieldW    = 179            ; width of the clock, progress bars (fit to taskbar)
ProgressH = 8              ; height of the progress bars

ProcLoadY = 1164           ; Y coordinate of the processor load bar
ProcColor = Navy

ClockFont = Arial Narrow
ClockPts  = 13
FontStyle = bold
ClockPatt = M/dd  ddd h:mm:ss
ClockY   := ProcLoadY + ProgressH
ClockH    = 25             ; height of the clock
DtH      := ClockH + 4     ; height of the control, clipped
DtW      := FieldW + 30    ; cut off calendar triangle
DtX       = -2             ; cut off borders
DtY       = -6             ; cut off borders

MemLoadY := ClockY + ClockH - 4
MemColor  = Red

;----- code starts here -----

VarSetCapacity( IdleTicks,    2*4 )
VarSetCapacity( memorystatus, 100 )
hw_tray := DllCall( "FindWindowEx", "uint",0, "uint",0, "str","Shell_TrayWnd", "uint",0 )

Progress 1:b x%X0% y%ProcLoadY% w%FieldW% ZX0 ZY0 ZH%ProgressH% CB%ProcColor%
GoSub Dock2TaskBar

Menu ClockMenu, Add, &Adjust Date/Time, SetDT
Menu ClockMenu, Add, &Copy Date/Time, DTcopy
Menu ClockMenu, Add, &Exit, 7GuiClose

Gui 7:-Caption ToolWindow  ; no title, no taskbar icon
Gui 7:Margin, 0,0
Gui 7:font, S%ClockPts% %FontStyle%, %ClockFont%
Gui 7:Add, DateTime, x%DtX% y%DtY% w%DtW% h%DtH% vDT, %ClockPatt%
Gui 7:Show, x%X0% y%ClockY% h%ClockH% w%FieldW%, Clock
WinActivate Clock
GoSub Dock2TaskBar
WinGet ClockID, ID, A      ; ID of Clock window

Progress 2:b x%X0% y%MemLoadY% w%FieldW% ZX0 ZY0 ZH%ProgressH% CB%MemColor%
GoSub Dock2TaskBar

SetTimer UpdateBars, 1000
SetTimer Clock             ; redraw clock, tooltip
Return

7GuiContextMenu:
   ToolTip
   Menu ClockMenu, Show    ; show context menu
Return

~LButton::                 ; CALENDAR
   MouseGetPos,,,Win,,1    ; is Clock under the mouse pointer?
   If (Win <> ClockID)
      Return
   ToolTip
   Send !{Down}            ; activate calendar
Return

7GuiClose:                 ; Exit
ExitApp                    ; Terminate

SetDT:                     ; Adjust date and time
   Run timedate.cpl
Return

DTcopy:
   Clipboard := FullDT()
Return

Clock:
   GuiControl 7:, DT, %A_Now% ; update in preset format
   MouseGetPos,,,Win,,1    ; is Clock under the mouse pointer?
   If (Win = ClockID)
   {                       ; ~traytip = full date/time info
      ClockTip = 1
      ToolTip % FullDT()
   }
   Else If ClockTip
   {
      ClockTip =           ; ClockTip removed
      ToolTip
   }
Return

UpdateBars:
   IdleTime0 = %IdleTime%
   Tick0 = %Tick%
   DllCall("kernel32.dll\GetSystemTimes", "uint",&IdleTicks, "uint",0, "uint",0)
   IdleTime := *(&IdleTicks)
   Loop 7
      IdleTime += *( &IdleTicks + A_Index ) << ( 8 * A_Index )
   Tick := A_TickCount
   load := 100 - 0.01*(IdleTime - IdleTime0)/(Tick - Tick0)
   Progress 1:%load%

   DllCall("kernel32.dll\GlobalMemoryStatus", "uint",&memorystatus)
   mem := *( &memorystatus + 4 )    ; 0..100
   Progress 2:%mem%
Return

Dock2TaskBar:              ; Active window is put to the taskbar
   Process Exist           ; PID -> ErrorLevel
   WinGet hw_gui, ID, ahk_pid %ErrorLevel%
   DllCall( "SetParent", "uint", hw_gui, "uint", hw_tray )
Return

FullDT()
{
   FormatTime wday,,dddd
   FormatTime day,,yDay
   FormatTime week,,yWeek
   StringTrimLeft week, week, 4
;----- edit here for best look -----
   FormatTime DT,,yyyy MMMM d, h:mm:ss tt
   DT = %DT%`n%wday%. Day: %day%`, Week: %week%
;----- edit here for best look -----
   Return DT
}

Here is a slightly improved, but longer version, using Shimanov's custom control idea. The changes:
Can be set:
- Color of Clock background, Clock font, Calendar boarder, Calendar font
- Position and boarder-width of calendar
- Font of calendar (independent of clock)
Changed:
- Calendar is closed with ESC or click on the clock again
- New right click menu item: Cancel, to do nothing
- Calendar is now a separate GUI
- Clock is shown as text, not as datetime control (more flexibility)
- Mouse hover is handled by Windows messages for smoother action (no Timer, MouseGetPos)
- Muse click is handled by messages (not by hotkey action, less interference with other scripts)
- Timer rate is reduced to 1 sec (less processor load)

Version 1.2:
- Smoother ToolTip (no erase-redraw)
- Double-click on the Clock pastes the current time to the last window (format specified in the header)
- Double-click on a date pastes it to the last window (format specified in the header)
- Date window (MonthCal control) stays on top for further date selections, until closed

Still needed:
- Auto placement, or placement helper to avoid the need for playing with numbers
; ---- Taskbar Clock v1.2 ---- ;
#NoTrayIcon                ; Save space w/o icon/menu
Process Priority,,High
SetWinDelay 0
SetKeyDelay -1
BlockInput Send

;----- edit here for best look -----

ClockX    = 0              ; Left edge of the clock
FieldW    = 179            ; Width of the clock and progress bars (fit to taskbar)
ProgressH = 8              ; Height of the progress bars

ProcLoadY = 1164           ; Y coordinate of the processor load bar
ProcColor = Black

ClockColor= White          ; Background
ClockFColr= Black          ; Font
ClockFont = Arial Narrow
ClockPts  = 13
ClockStyle= bold

ClockPatt = M/dd  ddd  hh:mm:ss
ClockPaste= h:mm:ss tt     ; Time format pasted
ClockY   := ProcLoadY + ProgressH
ClockH    = 23             ; Height of the clock
DtX       = 2              ; DateTime margin from left
DtY       = -2             ; ... from top

MonthColor= FF0000         ; Boarder
MonthFColr= Black          ; Font
MonthFont = Arial
MonthPts  = 12
MonthStyle=
MonthBordr= 4
MonthX    = 180            ; Left edge of the calendar
MonthY    = 890            ; Top ...
MonthPaste= MMMM d, yyyy

MemLoadY := ClockY + ClockH - 1
MemColor  = Red

;----- code starts here -----

VarSetCapacity( IdleTicks,    2*4 )
VarSetCapacity( memorystatus, 100 )
hw_tray := DllCall( "FindWindowEx", "uint",0, "uint",0, "str","Shell_TrayWnd", "uint",0 )

Menu ClockMenu, Add, &Adjust Date/Time, DTSet
Menu ClockMenu, Add, &Copy Date/Time, DTcopy
Menu ClockMenu, Add, E&xit,  7GuiClose
Menu ClockMenu, Add, Canc&el,DTCancel

Progress 1:b x%X0% y%ProcLoadY% w%FieldW% ZX-2 ZY0 ZH%ProgressH% CB%ProcColor%
GoSub Dock2TaskBar
Progress 2:b x%X0% y%MemLoadY% w%FieldW% ZX-2 ZY0 ZH%ProgressH% CB%MemColor%
GoSub Dock2TaskBar

Gui 7:-Caption ToolWindow ; no title, no taskbar icon
Gui 7:Color, %ClockColor%
Gui 7:font, S%ClockPts% %ClockStyle% c%ClockFColr%, %ClockFont%
Gui 7:Add, Text, x%DtX% y%DtY% vDT, __________________
Gui 7:Show, x%ClockX% y%ClockY% h%ClockH% w%FieldW%, Clock
WinActivate Clock
GoSub Dock2TaskBar
WinGet ClockID, ID, A      ; ID of Clock window

Gui 8:-Caption +AlwaysOnTop ToolWindow +Owner7
Gui 8:Margin, %MonthBordr%, %MonthBordr%
Gui 8:Color, %MonthColor%
Gui 8:Font, S%MonthPts% %MonthStyle% c%MonthFColr%, %MonthFont%
Gui 8:Add, MonthCal, AltSubmit g8Month vMonth

SetTimer ClockUpdate, 1000 ; Update bars, redraw clock, tooltip
OnMessage(0x200,"Hover7")  ; 0x200 = WM_MOUSEMOVE instead of WM_MOUSEHOVER -> MAIN AHK
OnMessage(0x201,"LClick7") ; 0x201 = WM_LBUTTONDOWN -> MAIN AHK

DTCancel:                  ; Do nothing in popup menu
Return

7GuiContextMenu:           ; Right click popup menu
   ToolTip                 ; Erase
   Menu ClockMenu, Show    ; Show context menu
Return

7GuiClose:                 ; Exit
ExitApp                    ; Terminate

8Month:                    ; Click on a date
   If (MonthTick > A_TickCount - 300)
   {                       ; Click again shortly after last click
      FormatTime date, %Month%, %MonthPaste%
      Send !{TAB}%date%    ; Paste date to last window
      Gui 8:Show
   }
   Else                    ; Remember time of last click
      MonthTick = %A_TickCount%
   Sleep 50                ; Prevent problems with double gLabel activations
Return

8GuiEscape:                ; ESC hides calendar
   Gui 8:Hide
Return

LClick7()                  ; CALENDAR
{
   Global MonthX, MonthY, ClockTick, ClockPaste
   IfNotEqual A_Gui,7, Return
   If (ClockTick > A_TickCount - 300)
   {                       ; Click again shortly after last click
      FormatTime t,,%ClockPaste%
      Send !{TAB}%t%       ; Paste time to last window
      Gui 8:Hide           ; Remove calendar
      Return
   }
   ClockTick=%A_TickCount% ; Remember time of last click
   GuiControlGet VisibleMonth, 8:Visible, Month
   if (A_GuiControl <> "Month")
      if VisibleMonth      ; Toggle visibility
         Gui 8:Hide
      else
         Gui 8:Show, x%MonthX% y%MonthY%
}

DTSet:                     ; Adjust date and time
   Run timedate.cpl
Return

DTcopy:                    ; Copy Date/Time to the ClipBoard
   Clipboard := FullDT()
Return

Hover7()                   ; When the mouse hovers DT
{                          ; Smoother move than MouseGetPos
   Global ClockTip
   IfNotEqual A_Gui,7, Return
   ClockTip = 1
   ToolTip % FullDT()      ; Show full date/time info
}

ClockUpdate:
   FormatTime time,,%ClockPatt%
   GuiControl 7:,DT,%time% ; Update date/time in preset format
   MouseGetPos,,,WinID
   If WinID = %ClockID%    ; Mouse in Clock
   {
      ClockTip = 1
      ToolTip % FullDT()   ; Show full date/time info
   }
   Else If ClockTip        ; Only clear ours
   {
      ClockTip =           ; ClockTip: tip removed
      ToolTip
   }
   IdleTime0 = %IdleTime%  ; Save previous values
   Tick0 = %Tick%
   DllCall("kernel32.dll\GetSystemTimes", "uint",&IdleTicks, "uint",0, "uint",0)
   IdleTime := *(&IdleTicks)
   Loop 7                  ; Ticks when Windows was idle
      IdleTime += *( &IdleTicks + A_Index ) << ( 8 * A_Index )
   Tick := A_TickCount     ; #Ticks all together
   load := 100 - 0.01*(IdleTime - IdleTime0)/(Tick - Tick0)
   Progress 1:%load%       ; Update progress bar

   DllCall("kernel32.dll\GlobalMemoryStatus", "uint",&memorystatus)
   mem:=*(&memorystatus+4) ; LS byte is enough, mem = 0..100
   Progress 2:%mem%        ; Update progress bar
Return

Dock2TaskBar:              ; Active window to be docked to the taskbar, NEEDS hw_tray value
   Process Exist           ; PID -> ErrorLevel
   WinGet hw_gui, ID, ahk_pid %ErrorLevel%
   DllCall( "SetParent", "uint", hw_gui, "uint", hw_tray )
Return

FullDT()                   ; Returns current date/time info
{                          ; Called very frequently if mouse hovers Clock
   Now = %A_Now%           ; Only one access to time: faster, no synchron problems
   FormatTime wday,Now,dddd
   FormatTime day, Now,yDay
   FormatTime week,Now,yWeek
   StringTrimLeft week, week, 4
;----- edit here for best look -----
   FormatTime DT,Now,yyyy MMMM d, h:mm:ss tt
   Return DT "`n" wday ". Day: " day ", Week: " week
;----- edit here for best look -----
}

Edit: 2005.11.10 added credit to antonyb
Edit: 2005.11.13 version 1.1 added
Edit: 2005.11.14 moved Clock in front of the progress bars: look does not change at a click on the clock
Edit: 2005.11.21 V1.2 with smoother tooltip and paste of date/time

shimanov
  • Members
  • 610 posts
  • Last active: Jul 18 2006 08:35 PM
  • Joined: 25 Sep 2005

Using three jewels found by Shimanov


.. and friend.

It has only a single DateTime control


Now I understand your Wish List post.

Gui 7


I sense there is something greater in the works. No?

Nice demonstration of a practical use for some rather esoteric components.

evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
Nice script! I easily customised it to cover up my start button and still fit in a clock and both bars in just 55 pixels (wide).

evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
I noticed a problem with the code and haven't found a way around it yet myself: When you click on the time, the red memory bar gets slightly covered up by the time control (it goes from 4 pixels high to only 2), however, when the layout is more tightly packed, as I use it, the entire bar gets lost (covered up I think). I suspect it has to do with the gui dis-obeying its size settings due to the deliberate "clipping" of its borders, but that's a guess.

I've been playing around with trying to re-show the memory bar or prevent it getting covered up, but with no luck. Any ideas?

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
I added a slightly improved, but longer version to the original post, using Shimanov's custom control idea. It should not have the cover-up. Changes:
Can be set:
- Color of Clock background, Clock font, Calendar boarder, Calendar font
- Position and boarder-width of calendar
- Font of calendar (independent of clock)
Changed:
- Calendar is closed with ESC or click on the clock again
- New right click menu item: Cancel, to do nothing
- Calendar is now a separate GUI
- Clock is shown as text, not as datetime control (more flexibility)
- Mouse hover is handled by Windows messages for smoother action (no Timer, MouseGetPos)
- Muse click is handled by messages (not by hotkey action, less interference with other scripts)
- Timer rate is reduced to 1 sec (less processor load)
Still needed:
- Auto placement, or placement helper to avoid the need for playing with numbers

evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
Laszlo, still getting the cover-up problem of the memory bar by the time, unfortunately. All I changed in the new script was ProcLoadY = 600 so it would fit on my screen easily.

The problem: When the clock is clicked on for the first time, the white box containing the time extends downwards a few more pixels (to cover the top row of pixels on the memory bar) - the display then stays like that. If you don't click on it at all then it is fine.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
1. Reduce ClockH by 2
2. Increase the offset in MemLoadY by 2 (change -3 to -1), to keep the progress bar in the same place
3. Move the progress bar creations before the Clock GUI lines, so that they are always in the background, not only when you click on the clock. This way there will be no change of the look at a click.

I updated the script in the first post accordingly.

evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
Thanks, that worked - although I ended up altering it by 3 pixels instead of 2, but I didn't have to change the order the bars are created in at all.

peejay
  • Members
  • 39 posts
  • Last active: Jul 09 2009 11:30 AM
  • Joined: 04 Mar 2005
Nice script! Never thought a progress bar could be used for this.

Still needed:
- Auto placement, or placement helper to avoid the need for playing with numbers

Maybe you can make it a child window of the taskbar, like the QuickRun toolbar, the Start button, and the TrayNotificationArea (or is this not possible with AHK?).
The Gods smile upon you. Beware - it is probably because they know what is going to happen to you next, and find it amusing. To them, anyway. --- Discworld Horrorscope: http://www.weirdnes.....uk/stars3.html