Jump to content

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

MakeICOBars - Create icon bar graphs for tray & pic


  • Please log in to reply
54 replies to this topic
tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
This script will create compatible icons to be used as tray icons or as pictures, showing bars in specified sizes, to be used as an updatable bar graph. Values may be added or shifted. Thanks to Laszlo for machine code binary write.

<!-- m -->https://ahknet.autoh...COBars-1.10.zip<!-- m -->

Usage is:

MakeICOBars(Numbers, Colours, FileName, BGColour, BGOpacity)

Example scripts are included in the zip. The function may be used as follows:

MakeICOBars("25|75", "000000", "BlackBars.ico", "000000", 100)		; Create 2 bars. Both will be black. The background will also be black, but at opacity 100 out of 255 and will be saved to BlackBars.ico
MakeICOBars("25|50|75", "ff0000|00ff00|0000ff", "3Bars.ico", "ffffff", 25) 	; Create 3 bars in the colours red, green, blue respectively and have a partially visible white background saved into 3Bars.ico
MakeICOBars("<25", "ff0000", "Shift.ico") ; Shift previous call by 1 bar to the left, and add a new bar at 25 height on the right
MakeICOBars(">25|50", "ff0000|00ff00", "Shift.ico") ; Shift previous call by 2 bars to the right, and add 2 new bar at 25 and 50 height on the left
MakeICOBars("-25", "ff0000", "AddLeft.ico") ; Add new bar at 25 height to the left hand side
MakeICOBars("+50|75", "0000ff", "AddRight.ico") ; Add new bars at 50 and 75 height to the right hand side, both blue


tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
Ive found a bug with setting the background transparency below 15 (0x0f) but that will be very easy to fix. Ill do it when Im back later. In a rush out... :)

Edit: Had time to fix it and upload. Byee

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
This really rocks!!!

Thanks

What about histogram ?
Posted Image

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
I only looked at what a picture of a histogram looks like. whats the difference between it and a bar graph (sorry...cant be bothered to read ;))

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Histogram is a special bar graph. I think Majkinetor meant line graphs, like function curves.

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007

Histogram is a special bar graph. I think Majkinetor meant line graphs, like function curves.


Heh. That will be more tricky (and slower) as antialising will be needed for lines or curves, so will be a bit annoying. i could definitely do it, but is it really needed? :D

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006

I think Majkinetor meant line graphs, like function curves.

Yup. Sorry if I mistaked the therm. Its on the picture.


BTW, maybe you can see to optimise function later a bit. This code takes 15% CPU

loop, 50 {
	Sleep 500
	TrayHistogram(A_Index*2 "|" A_Index*4, "00ff00|0000ff", "ff0000", 0)
}

2 seconds sleep takes is 3.65% and 1s = 8% measuring on Intel 2.8Ghz

Common scenario for using this function will probably fall in 1s - 2s.

Other then that, I played with it for some time, and it really looks great, especialy with full opacity.
Posted Image

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
@tic: They will definitely look cool, as in maj’s screenshot in your other thread. A running CPU load curve, or Internet speed variations always visible in the lower right corner, but even stock prices are useful. If they are “really needed”? No. We can live long and prosper w/o them, but you could give us some fun toys…

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
On my amd64 4000 @ 3.1GHz it never uses more than 10% with 500ms sleep.

I can optimise it speed wise a lot more but it will take up much more space. Is that a good trade off for you guys? In my example I genereally tended for lower size over faster speed. If you want speed and dont care so much about ram or the size of the script, i could make it much faster!

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Need for speed: when the functions get to their final form, we might be able to replace the loops with machine code functions. If you could keep those loops simple and separated from the more complex actions, the result could be fast and not too large. (Anything more than 1 or 2% CPU load is already too slow.)

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
Ive just spent the last 40 minutes cutting the time down, and found it wasnt making much of a difference. Using strategic A_TickCounts I found the answer. You may not like it....

My code doesnt really need to be optimised. The entirity of my code actually only takes 5-22% of the time of the whole function. All the loops perform very quickly. On average 85% of the time is passed in the binwrite section at the end, and I only used the necessary parts. If you can speed that up, then the whole function will also speed up.

Time1 := A_TickCount
	h := DllCall("CreateFile", "Str", "TrayHist.ico", "Uint", 0x40000000, "Uint", 0, "UInt", 0, "UInt", 4, "Uint", 0, "UInt", 0)
	r := DllCall("SetFilePointerEx","Uint",h,"Int64",offset,"UInt *",p,"Int",0)
	
	TotalWritten = 0
	m := Ceil(StrLen(Icon)/2)
	n := m
	Loop %n%
	{
		StringLeft c, Icon, 2         ; extract next byte
		StringTrimLeft Icon, Icon, 2  ; remove  used byte
		c = 0x%c%                     ; make it number
		Result := DllCall("WriteFile","UInt",h,"UChar *",c,"UInt",1,"UInt *",Written,"UInt",0)
		TotalWritten += Written       ; count written
		If (!result or Written < 1 or ErrorLevel)
		Break
	}
	h := DllCall("CloseHandle", "Uint", h)
	
	MsgBox, % A_TickCount - Time1
	Menu, Tray, Icon, TrayHist.ico
	FileDelete, TrayHist.ico

Edit:

I managed to cut the time down from around 10000ms for 100 cycles (standard settings and 0ms extra sleep) down to 9000, and believe I can cut it down another 500-1000, but as Ive just said, all the remaining time is spent in the binwrite. Perhaps the hIcon would be faster, with Shell_NotifyIcon, if anyone wants to write some tester code for me to add:

<!-- m -->http://msdn2.microso...y/aa922175.aspx<!-- m -->

and gets the pointer structure for me:

<!-- m -->http://msdn2.microso...y/aa930660.aspx<!-- m -->

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
Ive significantly sped up the binwrite function (obviously without the extra stuff thats not needed for this task)

	h := DllCall("CreateFile", "Str", "TrayHist.ico", "Uint", 0x40000000, "Uint", 0, "UInt", 0, "UInt", 4, "Uint", 0, "UInt", 0)
	
	Start := 1
	Loop % Ceil(StrLen(Icon)/2)
	{
		Result := DllCall("WriteFile", "UInt", h, "UChar *", "0x" . SubStr(Icon, Start, 2), "UInt", 1, "UInt *", Written, "UInt", 0)
		Start += 2
		If !Result
		Break
	}
	h := DllCall("CloseHandle", "Uint", h)

At the moment for 100 cycles it is down from 10300ms average to 7719ms. (Code not posted yet). Ill continue to try cutting the time of the fcuntion.

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
Ok the code is updated so that the user can choose the priority it will run at, thus the cpu usage

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
The above code writes each byte separately to the icon file, after converting it from hex form to binary. This is very slow. One solution was to work on binary buffers with NumPut/NumGet (or even with *address, or with RtlFillMemory dll calls), and then you don’t need hex-to-binary conversions, but write the whole buffer to the icon file with one dll call.

Another possibility is to keep working on hex data, but use a machine code function to convert the resulting hex stream to binary buffer. (The other direction is already done in Bit Wizardry: convert binary data to hex stream.) This should speed up the above loop hundred fold, and again, you only need one dll call to WriteFile.

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
Well if you or someone else could write me the machine code for hex to binary it would be much appreciated.

Also, what exactly do you want me to make a new function to do? curves, lines etc? And how would you want the input for how the curve is drawn (Im not gonna say this is gonna be easy, especially with all the antialising it will need)