i'm writing simple app using c#, .net 4.5 , gtk# captures portion of screen , loads onto image in window. after few seconds image disappears , following error :
glib-critical **: source id xxxx not found when attempting remove it.
relevant code:
program.cs:
using system.windows.forms; namespace dota2trainer { class mainclass { public static void main(string[] args) { gtk.application.init(); minimapoverlay mywin = new minimapoverlay(); mywin.keepabove = true; //mywin.decorated = false; mywin.resize(200, 200); mywin.showall(); screencapturer screencap = new screencapturer(30, screen.primaryscreen.bounds.width, screen.primaryscreen.bounds.height, mywin); screencap.start(); gtk.application.run(); } } }
minimapoverlay.cs:
using system; using system.drawing; using system.io; using system.timers; using gtk; namespace dota2trainer { public partial class minimapoverlay : gtk.window { gtk.image image = null; public minimapoverlay() : base(gtk.windowtype.toplevel) { image = new gtk.image(); var buffer = system.io.file.readallbytes(".\\image0.jpeg"); var pixbuf = new gdk.pixbuf(buffer); image.pixbuf = pixbuf; this.add(image); this.build(); } public void refreshimage(byte[] buffer) { try { var pixbuf = new gdk.pixbuf(buffer); image.pixbuf = pixbuf; } catch (exception exception) { console.writeline(exception.message); } } } }
screencapturer.cs:
using system; using system.drawing; using system.drawing.imaging; using system.io; using system.timers; namespace dota2trainer { public delegate void onsavedimage(byte[] screencap); public class screencapturer { public system.timers.timer atimer; int interval= 30000; readonly int screenwidth; readonly int screenheight; rectangle bounds; const double minimapwidthpercentage = 0.15; const double minimapheightpercentage = 0.25; bitmap bitmap; bool busy = false; imageconverter converter = new imageconverter(); public onsavedimage onsaveimage; public screencapturer(int interval, int screenwidth, int screenheight, minimapoverlay imageholder) { this.screenheight = screenheight; this.screenwidth = screenwidth; this.interval = interval; atimer = new system.timers.timer(); atimer.elapsed += new elapsedeventhandler(ontimedevent); atimer.interval = this.interval; int minimapwidth = (int)(screenwidth * minimapwidthpercentage); int minimapheight = (int)(screenheight * minimapheightpercentage); int minimapstartwidth = (screenwidth - minimapwidth); int minimapstartheight = (screenheight - minimapheight); bounds = new rectangle(minimapstartwidth, minimapstartheight, minimapwidth, minimapheight); bitmap = new bitmap(bounds.width, bounds.height); onsaveimage += imageholder.refreshimage; } public void start() { atimer.enabled = true; } public void ontimedevent(object sender, elapsedeventargs e) { try { if (busy) return; busy = true; using (graphics g = graphics.fromimage(bitmap)) { g.copyfromscreen(new point(bounds.left, bounds.top), point.empty, bounds.size); onsaveimage((byte[])converter.convertto(bitmap, typeof(byte[]))); } busy = false; } catch (exception exception) { console.writeline(exception.message); } } } }
full source code can found here:
https://github.com/oldtimerza/dota2trainer
how works creates timer , after amount of time runs ontimedevent() method of screencapturer class, has delegate run minimapoverlay refreshimage() method. code shocking @ moment, wanted rough , ready version , running before refactor it.
i've been searching ages why happens, suggestions?
you should use glib.timeout
instead of system.timers
. there can threading issues system.timers
, timer event occurs on different thread gtk application. glib.timeout
queues event in main gtk application loop @ interval, , runs in same thread. however, not suitable time sensitive functions because application loop handling other events such mouse clicks. i've seen delays of around half second second, on older computer while debugging. doesn't seem issue application; future reference. also, glib.timeout
keep calling update event until return false.
uint timerid; public void start(uint interval) { timerid = glib.timeout.add (interval, onupdatetimer); } protected bool onupdatetimer () { try { if (busy) return; busy = true; using (graphics g = graphics.fromimage(bitmap)) { g.copyfromscreen(new point(bounds.left, bounds.top), point.empty, bounds.size); onsaveimage((byte[])converter.convertto(bitmap, typeof(byte[]))); } busy = false; } catch (exception exception) { console.writeline(exception.message); } return true; }
Comments
Post a Comment