Hi,
I attached a simple GDI+ apps that works well on .NET, but failed with
mono, both on Windows and Linux (with mono 1.1.13) with this error :
Mono System.Windows.Forms Assembly [Revision: 54007; built: 2005/12/6
14:35:24]
Keyboard: French keyboard layout
Gtk not found (missing LD_LIBRARY_PATH to libgtk-x11-2.0.so?), using
built-in colorscheme
Unhandled Exception: System.IndexOutOfRangeException: Array index is out
of range.
in <0x0008d> System.Drawing.Graphics:DrawBeziers (System.Drawing.Pen
pen, System.Drawing.Point[] points)
in (wrapper remoting-invoke-with-check)
System.Drawing.Graphics:DrawBeziers
(System.Drawing.Pen,System.Drawing.Point[])
in <0x002f2> Exemple6d.Form1:OnPaint
(System.Windows.Forms.PaintEventArgs e)
in <0x00498> System.Windows.Forms.Control:WndProc
(System.Windows.Forms.Message m)
in <0x0000d> System.Windows.Forms.ScrollableControl:WndProc
(System.Windows.Forms.Message m)
in <0x0000d> System.Windows.Forms.ContainerControl:WndProc
(System.Windows.Forms.Message m)
in <0x008dc> System.Windows.Forms.Form:WndProc
(System.Windows.Forms.Message m)
in <0x00014> System.Windows.Forms.Control+ControlNativeWindow:WndProc
(System.Windows.Forms.Message m)
in <0x0011e> System.Windows.Forms.NativeWindow:WndProc (IntPtr hWnd, Msg
msg, IntPtr wParam, IntPtr lParam)
in <0x00016> System.Windows.Forms.XplatUIX11:DispatchMessage
(System.Windows.Forms.MSG msg)
in <0x00015> System.Windows.Forms.XplatUI:DispatchMessage
(System.Windows.Forms.MSG msg)
in <0x0061d> System.Windows.Forms.Application:RunLoop (Boolean Modal,
System.Windows.Forms.ApplicationContext context)
in <0x00024> System.Windows.Forms.Application:Run
(System.Windows.Forms.Form mainForm)
in <0x0001f> Exemple6d.Form1:Main ()
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Drawing2D;
namespace Exemple6d
{
/// <summary>
/// Description résumée de Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Variable nécessaire au concepteur.
/// </summary>
///
const int MAX = 10; // nombre de points 3.n+1
private Point [] points = new Point[MAX]; // tableau de points
private int lePoint; // no. du point cliqué
private bool dessin = false;
private bool contraintes = false; // contraintes aux jointures
private bool tangentes = false; // points de contrôle tangents
private System.Windows.Forms.CheckBox checkBoxContrainte;
private System.Windows.Forms.CheckBox checkBoxTangentes; // bouton enfoncé
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Requis pour la prise en charge du Concepteur Windows Forms
//
InitializeComponent();
//
// TODO : ajoutez le code du constructeur après l'appel à InitializeComponent
//
// code permettant d'utiliser le double buffering
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
}
/// <summary>
/// Nettoyage des ressources utilisées.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Code généré par le Concepteur Windows Form
/// <summary>
/// Méthode requise pour la prise en charge du concepteur - ne modifiez pas
/// le contenu de cette méthode avec l'éditeur de code.
/// </summary>
private void InitializeComponent()
{
this.checkBoxContrainte = new System.Windows.Forms.CheckBox();
this.checkBoxTangentes = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// checkBoxContrainte
//
this.checkBoxContrainte.Location = new System.Drawing.Point(16, 8);
this.checkBoxContrainte.Name = "checkBoxContrainte";
this.checkBoxContrainte.Size = new System.Drawing.Size(160, 24);
this.checkBoxContrainte.TabIndex = 0;
this.checkBoxContrainte.Text = "contraintes aux jointures";
this.checkBoxContrainte.CheckedChanged += new System.EventHandler(this.checkBoxContrainte_CheckedChanged);
//
// checkBoxTangentes
//
this.checkBoxTangentes.Location = new System.Drawing.Point(208, 8);
this.checkBoxTangentes.Name = "checkBoxTangentes";
this.checkBoxTangentes.Size = new System.Drawing.Size(160, 24);
this.checkBoxTangentes.TabIndex = 1;
this.checkBoxTangentes.Text = "points de contrôle tangents";
this.checkBoxTangentes.CheckedChanged += new System.EventHandler(this.checkBoxTangentes_CheckedChanged);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(520, 350);
this.Controls.Add(this.checkBoxTangentes);
this.Controls.Add(this.checkBoxContrainte);
this.Name = "Form1";
this.Text = "Exemple 6d";
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseDown);
this.Load += new System.EventHandler(this.Form1_Load);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseUp);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// Point d'entrée principal de l'application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
for (int i=0; i < MAX; i++) // initialisation des points
points[i] = new Point(50+50*i,100);
this.Invalidate(); // affichage initial
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{ // redéfinition de l'événement OnPaint
Graphics g = e.Graphics;
SolidBrush bNoir = new SolidBrush(Color.Gray);
Pen pRouge = new Pen(Color.Red);
Pen pGris = new Pen(Color.Gray);
g.SmoothingMode = SmoothingMode.AntiAlias; // anticrénelage
for (int i=0; i < MAX; i++) // dessin des points
{
if (i % 3 == 0)
g.DrawRectangle (pRouge, points[i].X-3, points[i].Y-3, 6, 6);
else
g.FillRectangle (bNoir, points[i].X-3, points[i].Y-3, 6, 6); // points de contrôle
}
g.DrawBeziers (new Pen(Color.Blue,2), points); // courbe
g.DrawLine(pGris,points[0],points[1]); // lignes de contrôle
g.DrawLine(pGris,points[MAX-2],points[MAX-1]);
for (int i=3; i < MAX-1; i+=3)
{
g.DrawLine(pGris,points[i],points[i-1]); // lignes des points de contrôle
g.DrawLine(pGris,points[i],points[i+1]);
}
base.OnPaint(e);
}
private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
dessin = true;
lePoint = -1;
for (int i=0; i < MAX; i++)
{
Rectangle r1 = new Rectangle(points[i].X-3, points[i].Y-3,6,6);
if (r1.Contains(new Point(e.X, e.Y)))
{
lePoint = i;
break;
}
}
}
private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
int diff1X = 0; // stockage des distances à préserver
int diff1Y = 0;
int diff2X = 0;
int diff2Y = 0;
if (lePoint == -1) // aucun point sélectionné
return;
if (dessin)
{
if (contraintes)
{
if (lePoint > 0 && lePoint < MAX-1)
{
if (lePoint % 3 == 0)
{ // distances par rapport aux 2 points de contrôle
diff1X = points[lePoint].X - points[lePoint-1].X;
diff1Y = points[lePoint].Y - points[lePoint-1].Y;
diff2X = points[lePoint].X - points[lePoint+1].X;
diff2Y = points[lePoint].Y - points[lePoint+1].Y;
}
else
if (tangentes && lePoint != 1 && lePoint != MAX-2)
{
if ((lePoint+1) % 3 == 0)
{ // point de contrôle avant le point
diff1X = points[lePoint].X - points[lePoint+1].X;
diff1Y = points[lePoint].Y - points[lePoint+1].Y;
}
else
{ // point de contrôle après le point
diff1X = points[lePoint].X - points[lePoint-1].X;
diff1Y = points[lePoint].Y - points[lePoint-1].Y;
}
}
}
else
switch (lePoint) // cas des 2 points des extrémités
{
case 0:
diff1X = points[lePoint].X - points[lePoint+1].X;
diff1Y = points[lePoint].Y - points[lePoint+1].Y;
break;
case MAX-1:
diff1X = points[lePoint].X - points[lePoint-1].X;
diff1Y = points[lePoint].Y - points[lePoint-1].Y;
break;
}
}
points[lePoint].X = e.X; // déplacement du point sélectionné
points[lePoint].Y = e.Y;
if (contraintes)
{
if (lePoint > 0 && lePoint < MAX-1) // extrémités intermédiaires
{
if (lePoint % 3 == 0)
{ // rétablissement des distances par rapport aux 2 points de contrôle
points[lePoint-1].X = points[lePoint].X - diff1X;
points[lePoint-1].Y = points[lePoint].Y - diff1Y;
points[lePoint+1].X = points[lePoint].X - diff2X;
points[lePoint+1].Y = points[lePoint].Y - diff2Y;
}
else
if (tangentes && lePoint != 1 && lePoint != MAX-2)
{
if ((lePoint+1) % 3 == 0)
{ // point de contrôle avant le point
points[lePoint+2].X = points[lePoint+1].X - diff1X;
points[lePoint+2].Y = points[lePoint+1].Y - diff1Y;
}
else
{ // point de contrôle après le point
points[lePoint-2].X = points[lePoint-1].X - diff1X;
points[lePoint-2].Y = points[lePoint-1].Y - diff1Y;
}
}
}
else // extrémités terminales
switch (lePoint) // application des différences
{
case 0:
points[lePoint+1].X = points[lePoint].X - diff1X;
points[lePoint+1].Y = points[lePoint].Y - diff1Y;
break;
case MAX-1:
points[lePoint-1].X = points[lePoint].X - diff1X;
points[lePoint-1].Y = points[lePoint].Y - diff1Y;
break;
}
}
this.Invalidate();
}
}
private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
dessin = false;
}
private void checkBoxContrainte_CheckedChanged(object sender, System.EventArgs e)
{
contraintes = checkBoxContrainte.Checked;
if (!checkBoxContrainte.Checked)
checkBoxTangentes.Checked = false;
}
private void checkBoxTangentes_CheckedChanged(object sender, System.EventArgs e)
{
tangentes = checkBoxTangentes.Checked;
if (checkBoxTangentes.Checked)
checkBoxContrainte.Checked = true;
}
}
}
_______________________________________________
Mono-winforms-list maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-winforms-list