I hope somebody likes it, input is welcomed.
Code: Select all
;Ticker: An RSS Scroller 1.10 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=0x0077FF ;Gui background color. RGB-hex, ex: 0x0077FF or name, ex: red.
TickerBackgroundColorFadeSteps=10 ;The amount of steps the RSS-specific background color should be faded. Color adjustments are accompanied with blinking, so keep this low.
; A feed's color change triggers when the last item of the previous feeds exits the screen.
; 0: Disable RSS-specific background color fade, html output still in color. 1: Instantanious color change. Ex: 12: Fade in twelve intervals.
TickerTextColor=0xF0F0F0 ;Text color. RGB-hex, ex: 0xF0F0F0 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 to blink into 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.
;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
TickerRssBlockedWords=Advertisement:|^ADV:|Happy zombies
;Html output file for RSS feeds, RSS-specific background colors apply. Only .htm and .html extensions permitted.
;Ex: C:\tickerhtml.html . Leave blank to disable.
;WARNING: This file gets overwritten during each RSS update, so be careful of the file specified.
TickerHtmlOutput=
TickerRss:=Array() ;Initialize RSS array, leave this.
;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") .
; Feeds may also specify optional custom feed specific settings using an array form, ex:
; TickerRss.Insert(["http://feeds.bbci.co.uk/news/rss.xml", "red", 3])
; Index 1: Feed URL
; Index 2: Background color
; Index 3: Max items per feed
TickerRss.Insert("http://rss.cnn.com/rss/edition.rss")
TickerRss.Insert(["http://feeds.bbci.co.uk/news/rss.xml","red", 2])
TickerRss.Insert(["http://hosted.ap.org/lineups/TOPHEADS.rss?SITE=AP&SECTION=HOME","0x007700"])
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 -DPIscale
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, TickerBackgroundColor, TickerNewBackgroundColor
static TickerSlider, TickerMove, TickerMessageQueueIndex=1, Init=1
If (Reset){
Init:=1,TickerMessageQueueIndex=1
Return
}
If Init
TickerSlider:=TickerMonRight/4, TickerMove:=TickerScrollSpeed, Init:=0, TickerNewBackgroundColor:=TickerBackgroundColor
SetBatchLines, -1
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
}
TickerSetBackgroundColor(TickerNewBackgroundColor)
}
TickerLabelUpdate(Reset=0){
Static TickerLabelIndex=1, TickerItemIndex=1
global TickerItem, TickerShowDescription, TickerTextSize, TickerTextWeight, TickerTextFont, TickerLabelhWnd, TickerLabelUrl, TickerMonRight, TickerMessageQueue, TickerNewBackgroundColor, TickerBackgroundColor
If (Reset){
TickerLabelIndex:=1, TickerItemIndex:=1
Return
}
Gui,Ticker:Default
Text:=TickerItem[TickerItemIndex][1] (TickerShowDescription ? " - " TickerItem[TickerItemIndex][2] : "")
Text:=RegExReplace(Text,"iUs)&","&&")
ControlMove,,% TickerMonRight,,% GetTextSize(Text,"s" TickerTextSize " w" TickerTextWeight, TickerTextFont),,% "ahk_id " TickerLabelhWnd[TickerLabelIndex]
ControlSetText,,% Text,% "ahk_id " TickerLabelhWnd[TickerLabelIndex]
TickerLabelUrl[TickerLabelIndex]:=TickerItem[TickerItemIndex][3]
TickerItemIndexColorOffsetted:=Mod(TickerItemIndex-TickerMessageQueue+TickerItem.MaxIndex()+1, TickerItem.MaxIndex())+1
TickerNewBackgroundColor:=ColorFader(TickerItem[TickerItemIndexColorOffsetted][4] ? TickerItem[TickerItemIndexColorOffsetted][4] : TickerBackgroundColor,0,1)
If (TickerItemIndex==TickerItem.MaxIndex())
TickerItemIndex:=TickerItem.MinIndex()
Else
For index in TickerItem
If (index>TickerItemIndex){
TickerItemIndex:=index
Break
}
TickerLabelIndex++
If (TickerLabelIndex>TickerMessageQueue)
TickerLabelIndex=1
}
TickerSetBackgroundColor(InputColor){
Static TickerNewBackgroundColor, TickerOldBackgroundColor, TickerCurrentBackgroundColor, TickerFadeStep:=1, Init:=1
Global TickerBackgroundColorFadeSteps, TickerhWnd, TickerBackgroundColor
If (InputColor=TickerCurrentBackgroundColor) || !TickerBackgroundColorFadeSteps
Return
If Init
Init:=0, TickerOldBackgroundColor:=TickerBackgroundColor
If (TickerFadeStep=1)
TickerNewBackgroundColor:=InputColor
If (InputColor!=TickerNewBackgroundColor){
TickerNewBackgroundColor:=InputColor
TickerFadeStep=1
TickerOldBackgroundColor:=TickerCurrentBackgroundColor
}
TickerSetBackgroundColor:=ColorFader(TickerNewBackgroundColor, TickerOldBackgroundColor, TickerFadeStep/TickerBackgroundColorFadeSteps)
Gui,Ticker:Default
If TickerSetBackgroundColor!=TickerCurrentBackgroundColor
Gui, Color,%TickerCurrentBackgroundColor%
TickerCurrentBackgroundColor:=TickerSetBackgroundColor
If (TickerFadeStep=TickerBackgroundColorFadeSteps)
TickerOldBackgroundColor:=TickerCurrentBackgroundColor
TickerFadeStep:=Mod(TickerFadeStep, TickerBackgroundColorFadeSteps)+1
}
ColorFader(ToColor, FromColor, FadeProgress){
Static HtmlColor:={Black: 0x000000, Green: 0x008000, Silver: 0xC0C0C0, Lime: 0x00FF00, Gray: 0x808080, Olive: 0x808000, White: 0xFFFFFF, Yellow: 0xFFFF00
, Maroon: 0x800000, Navy: 0x000080, Red: 0xFF0000, Blue: 0x0000FF, Purple: 0x800080, Teal: 0x008080, Fuchsia: 0xFF00FF, Aqua: 0x00FFFF}
FormatInteger:=A_FormatInteger
SetFormat, Integer, H
NewColor:=HtmlColor[ToColor]
If !NewColor
If !Instr(ToColor,"0x")
NewColor:="0x" ToColor
Else NewColor:=ToColor
OldColor:=HtmlColor[FromColor]
If !OldColor
If !Instr(FromColor,"0x")
OldColor:="0x" FromColor
Else OldColor:=FromColor
Rn:=(NewColor&0xFF0000)>>16
Gn:=(NewColor&0x00FF00)>>8
Bn:=(NewColor&0x0000FF)>>0
Ro:=(OldColor&0xFF0000)>>16
Go:=(OldColor&0x00FF00)>>8
Bo:=(OldColor&0x0000FF)>>0
Rf:=Round((Rn-Ro)*FadeProgress)+Ro
Gf:=Round((Gn-Go)*FadeProgress)+Go
Bf:=Round((Bn-Bo)*FadeProgress)+Bo
Out:= Rf<<16 | Gf<<8 | Bf
SetFormat, Integer, % FormatInteger
Return % Out
}
TickerRssUpdate(){
global TickerItem:=Array(), TickerRss, TickerRssMaxItemsPerFeed, TickerRssBlockedWords, TickerRssMaxAgeHours
For index, value in TickerRss
{
color1:=""
TickerRssMaxItemsPerFeedSpecific:=TickerRssMaxItemsPerFeed
If IsObject(value){
If value[2]
color1:=value[2]
If value[3]
TickerRssMaxItemsPerFeedSpecific:=value[3]
value:=value[1]
}
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,color1])
TickerExportHtml(title1,description1,link1,color1,continuefile)
continuefile=1
If (items>=TickerRssMaxItemsPerFeedSpecific)
Break
items++
}
}
}
TickerExportHtml(title1,description1,link1,color1,continuefile){
Global TickerBackgroundColor, TickerTextColor, TickerTextSize, TickerTextFont, TickerHtmlOutput
If !RegExMatch(TickerHtmlOutput,"i)\.(htm|html)$")
Return
StringReplace,textcolor,TickerTextColor,0x,#
If !color1
color1:=TickerBackgroundColor
StringReplace,backgroundcolor,color1,0x,#
If !(continuefile){
FileDelete, % TickerHtmlOutput
FileAppend, % "<!DOCTYPE html><html><head><title>Ticker RSS Feed</title><style>div{font-family:""" TickerTextFont """,Verdana,sans-serif;left:0;right:0;margin:1px;border:1px dotted black;}a{display:block;width:100%;height:100%;padding:5px;text-decoration:none;color:" textcolor ";}</style></head>", % TickerHtmlOutput
}
FileAppend, % "<div style=""background-color:" backgroundcolor """><a href=""" link1 """>" title1 "</a></div>`n", % TickerHtmlOutput
}
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:-DPIscale
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
}