[Mono-dev] Emedding mono: System.Windows.Form trouble
guy at guysherman.com
Thu Mar 3 05:09:54 EST 2011
I'm working on a sandbox game engine, with mono as the scripting language.
Tonight I got it to attach a DirectX rendering context to a Windows Forms
window created by some .NET code running in mono.
I have injected two methods into the runtime:
and have wrapped them appropriately in a C# class with externs, and they
Now, I naively thought that I could spin up a window, and have a timer
calling Invalidate(), with an overridden paint which calls RendererDraw
above. The problem is that my timer does not seem to fire. Paint is working
because it calls draw once, and also sometimes when I resize the window (so
when it is invalidated it calls my overridden paint which calls my c++
I then tried setting up a thread in the Form's Load method, which
continuously calls RendererDraw, but again, it does not seem to work. The
partial class for my form is below.
public partial class MainForm : Form
private Thread t;
//timer1.Enabled = true;
private void timer1_Tick(object sender, EventArgs e)
private void MainForm_Paint(object sender, PaintEventArgs e)
private void drawRepeatedly()
private void MainForm_Load(object sender, EventArgs e)
t = new Thread(new ThreadStart(drawRepeatedly));
private void button1_Click(object sender, EventArgs e)
private void MainForm_DoubleClick(object sender, EventArgs e)
private void MainForm_Click(object sender, EventArgs e)
You can probably see that I also tried hooking up the on-click event, and a
button. The button didn't show up (probably because I gave the window handle
to DirectX), but the click event didn't seem to be getting raised (although
I wonder if this is because I gave the handle to DirectX. I also tried (but
haven't copied the source) giving DirectX the handle of a panel instead of
the window itself, but still no dice.
I'm not expecting a whole lot of help on the DirectX side, but I'm just
wondering if there is something special to do with the UI thread etc when
running a Windows Forms window via the mono embedding api.
Oh yeah, the window is created by another piece of .net code.
public class PluginHost
private MainForm mainForm;
public void Start()
mainForm = new MainForm();
which is itself called via the embedding api as follows (not the actual code
but you get the idea).
// some stuff
domain = mono_jit_init (file);
assembly = mono_domain_assembly_open(domain, file);
image = mono_assembly_get_image(assembly);
// Then I register my internal calls as above
//I use a generated wrapper class to construct the PluginHost and call Start
but it boils down to
result = mono_object_new( this->domain, this->me /* the MonoImage* */ );
mono_runtime_object_init( result );
mono_runtime_invoke( this->StartMonoMethod, target, args, NULL );
// more stuff
The program then continues on to process the main event loop of the C++ side
Do I need to call the mono_runtime_invoke above in its own thread, and in my
PluginHost class do an Application.Run(mainForm)?
Thanks in advance for your help.
email: guy at guysherman.com
phone: +64 21 355 190
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Mono-devel-list