The actual bitmap, one byte of color information for each pixel, is at the end of the file. We keep the beginning of the image file, read the first 31 rows of the image and the last row, and write into the same file swapped. Setting this as the new tray icon has the effect of the picture scrolled up cyclically by one pixel. Scrolling down is similar.
The hotkey Win-1 scrolls up, Win-2 scrolls down and Win-0 stops the icon. You can use your favorite one, or use the 3rd script to decode the Ascii85 encoded example.
file0= %A_ScriptDir%\l0.bmp ; <-- your bmp file file = %A_ScriptDir%\l.bmp ; working copy GoTo #0 #1:: SetTimer ScrollUp, 50 SetTimer ScrollDown,Off Return #2:: SetTimer ScrollUp, Off SetTimer ScrollDown,50 Return #0:: SetTimer ScrollUp, Off SetTimer ScrollDown,Off FileCopy %file0%, %file%, 1 Menu Tray, Icon, %file% Return ScrollUp: Menu Tray, Icon, %file% BinRead( file, D1, 992,-1024) BinRead( file, D2, 32, -32) BinWrite(file, D2, 32,-1024) BinWrite(file, D1, 992, -992) Return ScrollDown: Menu Tray, Icon, %file% BinRead( file, D1, 32,-1024) BinRead( file, D2, 992, -992) BinWrite(file, D2, 992,-1024) BinWrite(file, D1, 32, -32) Return BinWrite(file, ByRef data, n=0, offset=0) { ; n = #bytes/all; neg offset from end, "A" = Append h := DllCall("CreateFile",Str,file, UInt,0x40000000, UInt,0, UInt,0, UInt,4, UInt,0, UInt,0) m := 2*(offset+0 < 0) ; offset >= 0 : m = 0; offset < 0, non-numeric: m = 2 offset += 0 ; non-numeric -> 0 DllCall("SetFilePointerEx",UInt,h, Int64,offset, UIntP,p, Int,m) m := VarSetCapacity(data) If n not between 1 and %m% n = %m% DllCall("WriteFile",UInt,h, Str,data, UInt,n, UIntP,U, UInt,0) DllCall("CloseHandle", UInt,h) } BinRead(file, ByRef data, n=0, offset=0) { ; n = #bytes/all; neg offset from end h := DllCall("CreateFile",Str,file, UInt,0x80000000, UInt,3, UInt,0, UInt,3, UInt,0, UInt,0) m := 2*(offset < 0) ; offset >= 0 : m = 0; offset < 0: m = 2 DllCall("SetFilePointerEx",UInt,h, Int64,offset, UIntP,U, Int,m) m := DllCall("GetFileSize",UInt,h, Int64P,r) If n not between 1 and %m% n = %m% VarSetCapacity(data, n) DllCall("ReadFile",UInt,h, Str,data, UInt,n, UIntP,r, UInt,0) DllCall("CloseHandle", UInt,h) Return r }You can encode your favorite bmp file (for copying from the MsgBox to the script) with the following script:
nD := BinRead(file, D) ; include file and BinRead from above Ascii85Encode(C, D, nD) StringReplace C, C, ``, ````, All StringReplace C, C, `%, ```%, All StringReplace C, C, `), ```), All Loop % (StrLen(C)+79)//80 { StringMid x, C, A_Index*80-79, 80 B = %B%%x%`n } MsgBox %B% Ascii85Encode(ByRef code, ByRef data, n=0) { If n not between 1 and % VarSetCapacity(data) n := StrLen(data) ; If no \0 in data, can omit n x = 0 code = <~ Loop %n% { x += *(&data+A_Index-1) << (24-8*((A_Index-1)&3)) If !(A_Index & 3) { ; Mod(i,4) = 0 IfEqual x,0, SetEnv code,%code%z Else Loop 5 code := code Chr(33+Mod(x//85**(5-A_Index),85)) x = 0 } } If (n & 3) ; Mod(n,4) > 0 Loop % (n&3)+1 code := code Chr(33+Mod(x//85**(5-A_Index),85)) code = %code%~> }Pressing Ctrl-C when the message box is active, copies the content to the clipboard, which you can paste to the script in an editor. This is how the encoded file is used (as Veovis suggested).
C = ( <~6;9?Dz!!"n[!!"DI!!",A!!",A!!!$"#QOi`)!!!!`%zz!!!!"z!!!-'"9=[LPQ1gf]DscHoDg^+49 3URe,TUQqu?]s!!(mWDueSlD#i&c(BAXZ!!!!=GQ7a-D#aPK(B=F8!!'kmGQ7u("99:g!!!"C!!!$^;u cn`)jo>B#&c_n3!!!"N49,?]#ljr*`)ZTj<z49,?]k5YJ^&c_n3z(]XO9mJm4eO8o7\HiR\QDuf.a"TT 1dOT5B*HiW1.rrD<arrA,\rr@EH!!!i:!!`)6``!!!W3z!!!i9zzz!!$,SP5q*9`)$#.!OT5@]HiSb?! !!#G!!!#K,6.^f!!!#PGQ7```%!<<,L('">Yz2uisJ$ig;+!!!"K!!#fJ!!`)-E!!(R_('&OY!!`%+E- iiLfjT#qC&c_oU!!'Jr(BCr.S,eZae,XjrG6$/CBE5Mtkl?jq&cd<'!!`%6D(]\CQmJn`%'O8o7\HiO^ ?O8o7e[K*?IOT5@]HiW(`)rr=_Qrr@iTrr@EHrrA]+L&cK![K`%*DOT5@]HiO-IQiI*dZ2ak`)OT5@]H iO-Hzz('"=7!!$s<#lnfB!rs,;&-`)\1!!!!1lMpnb"ooD=OT5@]HiOc[!!&Vk!!!$"z!!`%6D&--PI! !!f8WrN,"!!!!"huE``W0E;jgL]@DTHiSZs!!`)6``!!!W3zzZiC(+kl:\``&c_n3!!!!Y9``P1WSH'E <e,TIKG6!R`%Duf,&!WWi5g&M*QG6"\b!WY1CIfPTD!!`%BH!!(&PL]B@:k5^Xr&cd<'!!!9Y<r``G\# QPXiirB('!!!T1,6.``D"9>M&!!!$!!!!!K?iU1_SH&Z>e,TJmG5qWY!!!#+!!!#K!!!"C!!((?!<D?a !!!W3z!!`)sn!!!#\!!`%T$!!`%Cj!!!0b!!!$+!!`%Qh!!`%BH!!&[D!!`%9E!!!f8z!!`%TNDu]k<! W[cOg&QL#G5qUC!WW3#IfKHKz!!!RH!!!"g!!''Le,TIKG5qrm49,Jj#ljtT`)ZTk^!!!&:49,?d#ljr B`)ZTj<!!&B':]TbE?iUfP1]RLU!!`)cociEe?k5Z+p&c_n3!!`)co,67H<2?4?mf`)PdN=oe-o491cL #loSX`)ZY6c!!!;+!<</a!!`%Q_!!`%BH!!*`%<!!*$W!!*`%g!!*$3!!!2t!!!&o!!`%Q_!!`%BH!!( M]49,Bb#lm<D`)ZTk^!!'7M:B9dhjT$(Gec5\oG5s;r.00AI:&ohEf`)U3u=oa/t49,Ag#loP+`)ZY80 !!$-7!W^g*!!(Nu!!`%4e!!`%pZ:B2`)ujT*k]ec9moG5qXEzzzzzzz!!!$#zzzzzzz!!!0+"U,&5"U, &5"98E`)"U,&5"98E`)"U,&5"U,&5!!!0+"U,&5"U,&5z"U,&5z"U,&5"U,&5!!!0+"U,&5"U+u4"p+c `)"U+u4"p+c`)"U,&5"U,&5!!!0+"U,&5"U,`)7"pP&-"U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5"98W1 "pP&-!!!3-"pP&-z!!EH/!!!0+"U,&5!!!3-"pP&-!!!3-"pP&-z!!!0+!!!0+"U+u4"pP89"pP89"pP 89"pP89"pP85!!!0+!!!0+"U,`)7"pP89"pP89"pP89"pP89"pP89!!EH/!!!0+"U,`)7"pP89"pP89" pP89"pP89"pP89"U,&5!!!0+"U+u4"pP89"pP89"pP89"pP89"pP86"U,&5!!!0+"U,&5"U,`)7"pP&- "U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5"U,`)7"pP&1"U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5"U,`)7" pP57"U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5"U+u4"p5#4"U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5"U,& 5"U,&5"U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5"U,&5"U,&5"U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5"U ,&5"U,&5"U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5"U,&5"U,&5"U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5 "U,&5"U,&5"U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5"U,&5"U,&5"U,`)7"pP&-"U,&5"U,&5!!!0+"U, &5"U,&5"U,&5"U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5"U,&5"U,&5"U,`)7"pP&-"U,&5"U,&5!!!0+" U,&5"U,&5"U,&5"U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5"U,&5"U,&5"U,`)7"pP&-"U,&5"U,&5!!!0 +"U,&5"U,&5"U,&5"U,`)7"pP&-"U,&5"U,&5!!!0+"U,&5"U,&5"U,&5"U,`)7"pP&1"U,&5"U,&5!! !0+"U,&5"U,&5"U,&5"U,`)7"pP57"U,&5"U,&5!!!0+"U,&5"U,&5"U,&5"U+u4"p5#4"U,&5"U,&5! !!0+"U,&5"U,&5"U,&5"U,&5"U,&5"U,&5"U,&5!<E?-"U,&5"U,&5"U,&5"U,&5"U,&5"U,&5"U,&5!<E~> ) Ascii85Decode(B,C,nB) BinWrite(file0, B, nB) ; use file0 and BinWrite from the 1st script Ascii85Decode(ByRef data, code, ByRef len) { StringReplace, code, code, <~ StringReplace, code, code, ~> StringReplace, code, code, `n,, All StringReplace, code, code, `r,, All StringReplace, code, code, %A_Space%,,All StringCaseSense On ; needed for z -> !!!!! StringReplace, code, code, z, !!!!!, All m := Mod(StrLen(code),5) - (Mod(StrLen(code),5)>0) ; 12345 -> ?1230 len := (StrLen(code)//5)*4 + m VarSetCapacity(data,len,0) p := &data x = 0 Loop Parse, code If Mod(A_Index,5) = 0 { x := x*85 + Asc(A_LoopField)-33 Loop 4 { DllCall("RtlFillMemory",UInt,p, UInt,1, UChar,x>>(32-8*A_Index)) p++ } x = 0 } Else x := x*85 + Asc(A_LoopField)-33 x := (x+1) * 85**(4-m) ; omitted code chars -> 85+33, carry stops at trailing 0's of x Loop %m% { DllCall("RtlFillMemory",UInt,p, UInt,1, UChar,x>>(32-8*A_Index)) p++ } }