I think WinDelay has no effect here, since no window operations are performed. SetControlDelay was already in the script and I've added SetBatchLines.
I've updated the first post to include RSS specific background colors and also improved the HTML output to include the same coloring scheme (Guest10
, look for the TickerHtmlOutput-setting).
I intended to produce a slow gradual color fade for the ticker but that resulted in crazy flickering, probably similar to what joedf experienced under XP. So now the default is a 300ms fade, starting when the last item of the leading feed exits the screen. This means that when there are many news items visible the coloring isn't foolproof.
Below is a 'backup' of the previous version 1.05.
Code: Select all
;Ticker: An RSS Scroller 1.05 by NextronNL
;A smooth news ticker using RSS feeds of your choice.
;User settings below.
;When including this in your own script, please note:
;Use of globals is minimized. All globals start with Ticker*, to prevent conflicts.
;The label TickerAutorun needs to be run at least once.
;Label TickerGuiStart created the gui.
;Label TickerGuiClose destroys the gui and resets variables.
;Label TickerGuiToggle toggles between the two.
;The script contains three functions written by others that may conflict with the including script, and may need to be removed:
;GetTextSize by Laszlo
;UrlDownloadToVar by Eddy
;UnHTM by SKAN
;Known issues:
;Mouseover pause works by comparing the mouse location with the gui coordinates, not the actual gui window. So the ticker will pause even if it is covered by another window.
;User Settings
TickerAutorun:
#SingleInstance,Force ;Remove this entire line if it you include the Ticker script in your existing script and it poses a conflict.
TickerButton=MButton ;The Gui is clickthrough, except for this button which opens the link to the article.
TickerTopOfScreenInsteadOfBottom=0 ;0: Gui is placed at the bottom of the screen, above the taskbar. 1: Gui is placed at the top of the screen.
TickerTopMostInsteadOfBottom=0 ;0: Gui is placed at the lowest Z-order, below other windows. 1: Gui is always on top.
TickerShowDescription=0 ;0: Scroll just the titles of the articles. 1: Scroll the titles and their descriptions.
TickerTransparancy=180 ;Gui transparancy 0-255 (Fully transparant - Opaque).
TickerBackgroundColor=0077FF ;Gui background color. RGB-hex, ex: 0077FF or name, ex: red.
TickerTextColor=F0F0F0 ;Text color. RGB-hex, ex: F0F0F0 or name, ex: blue.
TickerTextSize=16 ;Text size. Point number, ex: 16.
TickerTextWeight=Bold ;Text weight. Number 1-1000 (400 is normal and 700 is bold). The following words are also supported: bold, italic, strike, underline, and norm.
TickerTextFont= ;Text font. Name, ex: Verdana. Or empty for default.
TickerSeperation=70 ;Distance between individual items. Number in pixels, ex: 70.
TickerScrollSpeed=1.8 ;Scrolling speed. Number of pixels per time interval, ex: 1.4
TickerMessageQueue=7 ;Maximum number of items that can be visible at once. Required number depends on item length, text size, screen width and seperation. A number to low cause items tp blink in view. High number requires more resources.
TickerPauseOnMouseover=1 ;0: Items always scroll. 1: Scrolling is paused when the mouse is hovering over them.
TickerTimer=10 ;Update interval of scrolling in milliseconds, ex: 10
TickerRssRefresh=15 ;Update interval of RSS feed in minutes, ex: 15
TickerRssMaxItemsPerFeed=8 ;Maximum number of items to retrieve from each RSS feed, ex: 8.
TickerRssMaxAgeHours=18 ;Maximum age in hours of each item in RSS feed before it's discarded during RSS update, ex: 18.
TickerRssBlockedWords=Advertisement:|^ADV:|Happy zombies ;RSS titles containing any of these case-insensitive words are discarded, separate words using a pipe symbol (|). Actually this is a single regular expression, so more elaborate filtering is possible, hoever, because of this the characters: \.*?+[{|()^$ must be preceded by a backslash to be seen as literal
TickerRss:=Array() ;Initialize RSS array, leave this.
TickerRss.Insert("http://rss.cnn.com/rss/edition.rss") ;Url of RSS feed to use. Multiple feeds allowed. For each new RSS feed, use a new line, ex: TickerRss.Insert("http://rss.cnn.com/rss/edition.rss") .
TickerRss.Insert("http://feeds.bbci.co.uk/news/rss.xml")
TickerRss.Insert("http://hosted.ap.org/lineups/TOPHEADS.rss?SITE=AP&SECTION=HOME")
TickerRss.Insert("http://feeds.reuters.com/reuters/topNews")
;Initialize
TickerGuiStart:
TickerItem:=Array()
TickerLabelhWnd:=Array()
TickerLabelUrl:=Array()
SetTimer,TickerRss,% TickerRssRefresh*60000
Gosub,TickerRss
Gui,Ticker:Default
Gui,+ToolWindow -SysMenu -Caption +LastFound hwndTickerhWnd
Gui,Margin, 5,5
Gui,Color,%TickerBackgroundColor%
WinSet,ExStyle,+0x20
WinSet,Transparent,%TickerTransparancy%
Gui,Font,c%TickerTextColor% s%TickerTextSize% w%TickerTextWeight%,%TickerTextFont%
SysGet,TickerMon,MonitorWorkArea
Loop, % TickerMessageQueue
{
Gui,Add, Text, x%TickerMonRight% y5 hwndTickerLabelhWndtemp,
TickerLabelhWnd.Insert(TickerLabelhWndtemp)
TickerLabelUpdate()
}
VarSetCapacity(TickerLabelhWndtemp,0)
TickerGuiH:=GetTextSize("Text", "s" TickerTextSize " w" TickerTextWeight, TickerTextFont, 1)
TickerGuiH:=SubStr(TickerGuiH,Instr(TickerGuiH,",")+1)+10
TickerGuiY:=TickerTopOfScreenInsteadOfBottom ? "0" : TickerMonBottom-TickerGuiH
Gui,Show, x0 y%TickerGuiY% w%TickerMonRight% h%TickerGuiH% NoActivate
WinSet,% TickerTopMostInsteadOfBottom ? "Topmost" : "Bottom",,ahk_id %TickerhWnd%
SetTimer,TickerUpdate,%TickerTimer%
Hotkey,If, MouseOver(TickerhWnd)
Hotkey,%TickerButton%,TickerClick,On
Hotkey,If,
Return
TickerUpdate:
TickerUpdate()
Return
TickerRss:
TickerRssUpdate()
Return
TickerGuiClose:
Gui,Ticker:Default
SetTimer,TickerRss,Off
SetTimer,TickerUpdate,Off
Hotkey,If, MouseOver(TickerhWnd)
Hotkey,%TickerButton%,TickerClick,Off
Hotkey,If,
TickerLabelUpdate(1)
TickerUpdate(1)
Gui,Destroy
Return
F12::
TickerGuiToggle:
If Winexist("ahk_id " TickerhWnd)
Gosub,TickerGuiClose
Else
Gosub,TickerGuiStart
Return
TickerClick:
WinSet,ExStyle,-0x20, ahk_id %TickerhWnd%
MouseGetPos,,,,TickerClickControl
WinSet, ExStyle,+0x20, ahk_id %TickerhWnd%
If (SubStr(TickerClickControl,1,6)=="Static"){
StringTrimLeft, TickerClickControl, TickerClickControl, 6
If (SubStr(TickerLabelUrl[TickerClickControl],1,4)=="http")
Run,% TickerLabelUrl[TickerClickControl]
}
Return
#If, MouseOver(TickerhWnd)
#If,
TickerUpdate(Reset=0){
global TickerMonRight, TickerMessageQueue, TickerLabelhWnd, TickerSeperation, TickerScrollSpeed, TickerhWnd, TickerPauseOnMouseover
static TickerSlider, TickerMove, TickerMessageQueueIndex=1, Init=1
If (Reset){
Init:=1,TickerMessageQueueIndex=1
Return
}
If Init
TickerSlider:=TickerMonRight/4,TickerMove:=TickerScrollSpeed,Init=0
SetControlDelay,-1
TickerSlider-=TickerMove
TickerSliderHelper:=TickerSlider
Loop, % TickerMessageQueue
{
ControlGetPos,,,TickerLabelW,,, % "ahk_id " TickerLabelhWnd[TickerMessageQueueIndex]
If (TickerSliderHelper<-TickerLabelW){
TickerSlider+=TickerLabelW+TickerSeperation
TickerSliderHelper:=TickerSlider
TickerMessageQueueIndex:=mod(TickerMessageQueueIndex,TickerMessageQueue)+1
ControlGetPos,,,TickerLabelW,,,% "ahk_id " TickerLabelhWnd[TickerMessageQueueIndex]
TickerLabelUpdate()
}
ControlMove,, % TickerSliderHelper,,,,% "ahk_id " TickerLabelhWnd[TickerMessageQueueIndex]
TickerSliderHelper+=TickerLabelW+TickerSeperation
TickerMessageQueueIndex:=mod(TickerMessageQueueIndex,TickerMessageQueue)+1
}
If (TickerPauseOnMouseover){
If MouseOver(TickerhWnd)
If TickerMove<=0
TickerMove=0
Else
TickerMove-=TickerScrollSpeed/40
Else If (TickerMove<TickerScrollSpeed)
TickerMove+=TickerScrollSpeed/10
}
}
TickerLabelUpdate(Reset=0){
Static TickerLabelIndex=1, TickerItemIndex=1
global TickerItem, TickerShowDescription, TickerTextSize, TickerTextWeight, TickerTextFont, TickerLabelhWnd, TickerLabelUrl, TickerMonRight, TickerMessageQueue
If (Reset){
TickerLabelIndex:=1, TickerItemIndex:=1
Return
}
Gui,Ticker:Default
Text:=TickerItem[TickerItemIndex][1] (TickerShowDescription ? " - " TickerItem[TickerItemIndex][2] : "")
ControlMove,,% TickerMonRight,,% GetTextSize(Text,"s" TickerTextSize " w" TickerTextWeight, TickerTextFont),,% "ahk_id " TickerLabelhWnd[TickerLabelIndex]
ControlSetText,,% Text,% "ahk_id " TickerLabelhWnd[TickerLabelIndex]
TickerLabelUrl[TickerLabelIndex]:=TickerItem[TickerItemIndex][3]
If (TickerItemIndex==TickerItem.MaxIndex())
TickerItemIndex:=TickerItem.MinIndex()
Else
For index in TickerItem
If (index>TickerItemIndex){
TickerItemIndex:=index
Break
}
TickerLabelIndex++
If (TickerLabelIndex>TickerMessageQueue)
TickerLabelIndex=1
}
TickerRssUpdate(){
global TickerItem:=Array(), TickerRss, TickerRssMaxItemsPerFeed, TickerRssBlockedWords, TickerRssMaxAgeHours
For index, value in TickerRss
{
feed:=UrlDownloadToVar(value)
startpos=1
items=1
Loop
{
pos:=RegExMatch(feed,"iUs)<item.*>.*</item>",item,startpos)
If not pos
Break
startpos:=pos+StrLen(item)
item:=RegExReplace(item,"iUs)<!\[CDATA\[(.+)\]\]>","$1")
RegExMatch(item,"iUs)<title.*>(.*)</title>",title)
If RegExMatch(title1, "i)" TickerRssBlockedWords)
Continue
RegExMatch(item,"iUs)<description.*>(.*)</description>",description)
RegExMatch(item,"iUs)<link.*>(.*)</link>",link)
RegExMatch(item,"iUs)<pubdate.*>(.*)</pubdate>",pubdate)
itemage:=A_NowUTC
itemage-=ParseRCF822Date(pubdate1, 1),Hours
If (itemage>=TickerRssMaxAgeHours)
Continue
TickerItem.Insert([UnHTM(title1),UnHTM(description1),link1])
If (items>=TickerRssMaxItemsPerFeed)
Break
items++
}
}
}
MouseOver(hWnd){
CoordMode,Mouse,Screen
MouseGetPos,mx,my
WinGetPos,wx1,wy1,ww,wh,ahk_id %hWnd%
wx2:=wx1+ww, wy2:=wy1+wh
Return mx>=wx1 && mx<=wx2 && my>=wy1 && my<=wy2
}
ParseRCF822Date(datetime, UTC=0, centurythreshold=2010){
;Returns YYYYMMDDHH24MISS from a RFC822 or RSS PubDate date-time.
static Needle:="i)([a-z]{3}),{0,1} (\d{1,2}) ([a-z]{3}) (\d{2,4}) (\d{1,2}):(\d{2}):{0,1}(\d{0,2}) ?([a-z0-9+-]{0,5})"
, months:="Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec"
FormatFloat:=A_FormatFloat, c:=0
If !RegExMatch(datetime,needle,dt)
Return False
If (dt7="")
dt7=0
If (dt8="")
dt8=z
If (UTC){
If RegExMatch(dt8,"^(\+|-)(\d{2})(\d{2})$",dtc)
c:=dtc2*60+dtc3*(dtc1="+" ? 1 : -1)
Else If RegExMatch(dt8,"i)^([a-z]{2,3})$")
c:= (-4*!!RegExMatch(dt8,"i)EDT")-5*!!RegExMatch(dt8,"i)EST|CDT")-6*!!RegExMatch(dt8,"i)CST|MDT")-7*!!RegExMatch(dt8,"i)MST|PDT")-8*!!RegExMatch(dt8,"i)PST"))*60
Else If RegExMatch(dt8,"i)^([a-z]{1})$")
c:=(InStr("MLKIHGFEDCBAZNOPQRSTUVWXY",dt8)-13)*60
}
SetFormat,Float,04.0
YYYY:= (dt4<100 ? dt4<Mod(centurythreshold,100) ? dt4+(centurythreshold//100)*100-100 : dt4+(centurythreshold//100)*100 : dt4)+0.0
SetFormat,Float,02.0
MM:=(InStr(months, dt3)//4)+1.0
DD:=dt2+0.0
HH24:=dt5+0.0
MI:=dt6+0.0
SS:=dt7+0.0
SetFormat,Float,% FormatFloat
Result:=YYYY . MM . DD . HH24 . MI . SS
Result+=-c,Minutes
Return Result
}
GetTextSize(pStr, pSize=8, pFont="", pHeight=false) {
;Laszlo: http://www.autohotkey.com/board/topic/16414-hexview-31-for-stdlib/page-2
Gui TextSize:Font, %pSize%, %pFont%
Gui TextSize:Add, Text, R1, %pStr%
GuiControlGet T, TextSize:Pos, Static1
Gui TextSize:Destroy
Return pHeight ? TW "," TH : TW
}
UrlDownloadToVar(URL) {
;Eddy: http://www.autohotkey.com/board/topic/9529-urldownloadtovar/page-6
ComObjError(false)
WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WebRequest.Open("GET", URL)
WebRequest.Send()
Return WebRequest.ResponseText
}
UnHTM( HTM ) { ; Remove HTML formatting / Convert to ordinary text by SKAN 19-Nov-2009
Static HT ; Forum Topic: http://www.autohotkey.com/board/topic/47356-unhtm-remove-html-formatting-from-a-string-updated/
IfEqual,HT,, SetEnv,HT, % "ááââ´´ææàà&ååãã&au"
. "mlä&bdquo„¦¦&bull•ç縸¢¢&circˆ©©¤¤&dagger†&dagger‡°"
. "°÷÷ééêêèèððëë&euro€&fnofƒ½½¼¼¾¾>>&h"
. "ellip…ííîî¡¡ìì¿¿ïï««&ldquo“&lsaquo‹&lsquo‘<<&m"
. "acr¯&mdash—µµ··  &ndash–¬¬ññóóôô&oeligœòò&or"
. "dfªººøøõõöö¶¶&permil‰±±££"""»»&rdquo”®"
. "®&rsaquo›&rsquo’&sbquo‚&scaronš§§­¹¹²²³³ßßþþ&tilde˜&tim"
. "es×&trade™úúûûùù¨¨üüýý¥¥ÿÿ&apos'"
TXT := RegExReplace( HTM,"<[^>]+>" ) ; Remove all tags between "<" and ">"
Loop, Parse, TXT, &`; ; Create a list of special characters
L := "&" A_LoopField ";", R .= (!(A_Index&1)) ? ( (!InStr(R,L,1)) ? L:"" ) : ""
StringTrimRight, R, R, 1
Loop, Parse, R , `; ; Parse Special Characters
If F := InStr( HT, A_LoopField ) ; Lookup HT Data
StringReplace, TXT,TXT, %A_LoopField%`;, % SubStr( HT,F+StrLen(A_LoopField), 1 ), All
Else If ( SubStr( A_LoopField,2,1)="#" )
StringReplace, TXT, TXT, %A_LoopField%`;, % Chr(SubStr(A_LoopField,3)), All
Return RegExReplace( TXT, "(^\s*|\s*$)") ; Remove leading/trailing white spaces
}