Oui, Oui, vous n'avez pas rêver, le domigrille d'origine c2i un peu améliorer pour tenter la girafe sans avoir besoin de relancer vsnet à chaque fois (avec un peu de CodeDom pour éviter le Process.Start("csc.exe") ...)

J'ai du modifier un peu la Form d'origine notamment pour la modification des PictureBox car j'en avais marre du NullException que j'avais une fois sur 2 quand je tentais d'enlever les existants pour en créer de nouveau. Résultat, maintenant ils sont tous dans un panel et j'ai juste à faire un Clear();
Bon, je vous balance le code source, j'écrirais un petit article plus détaillé plus tard sur le pourquoi du comment, mais j'ai envie que quelq'un arrive à nous faire une girafe pour Richard, comme ca il pourra présenter fièrement au MVP Summit hein ;)
(Là j'ai peur pour le code source à cause de dotText, mais on va essayé :p)
#################################
using
System;
using
System.Drawing;
using
System.Collections;
using
System.ComponentModel;
using
System.Windows.Forms;
using
System.Data;
using
System.CodeDom;
using
System.CodeDom.Compiler;
using
Microsoft.CSharp;
using
System.Reflection;
///
/// Description résumée de Form1.
///
///
namespace
DomiTicTacToe
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TextBox tbCode;
private System.Windows.Forms.NumericUpDown numNombre;
private System.Windows.Forms.NumericUpDown numTaille;
private System.Windows.Forms.NumericUpDown numRupture;
private System.Windows.Forms.Label lbNombrePbox;
private System.Windows.Forms.Label lbRupture;
private System.Windows.Forms.Label lbTaille;
private System.Windows.Forms.Panel pnPbox;
private System.Windows.Forms.Button btModifier;
///
/// Variable nécessaire au concepteur.
///
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
//
}
///
/// Nettoyage des ressources utilisées.
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region
Windows Form Designer generated code
///
/// Méthode requise pour la prise en charge du concepteur - ne modifiez pas
/// le contenu de cette méthode avec l'éditeur de code.
///
private void InitializeComponent()
{
this.tbCode = new System.Windows.Forms.TextBox();
this.btModifier = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.lbTaille = new System.Windows.Forms.Label();
this.lbRupture = new System.Windows.Forms.Label();
this.lbNombrePbox = new System.Windows.Forms.Label();
this.numRupture = new System.Windows.Forms.NumericUpDown();
this.numTaille = new System.Windows.Forms.NumericUpDown();
this.numNombre = new System.Windows.Forms.NumericUpDown();
this.pnPbox = new System.Windows.Forms.Panel();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(
this.numRupture)).BeginInit();
((System.ComponentModel.ISupportInitialize)(
this.numTaille)).BeginInit();
((System.ComponentModel.ISupportInitialize)(
this.numNombre)).BeginInit();
this.SuspendLayout();
//
// tbCode
//
this.tbCode.AutoSize = false;
this.tbCode.Location = new System.Drawing.Point(160, 8);
this.tbCode.Multiline = true;
this.tbCode.Name = "tbCode";
this.tbCode.Size = new System.Drawing.Size(264, 160);
this.tbCode.TabIndex = 0;
this.tbCode.Text = @" if (Convert.ToInt32(pct.Name)%5==0) pct.BackColor=Color.AliceBlue;
if (Convert.ToInt32(pct.Name)%7==0) pct.BackColor=Color.Chartreuse;
if (Convert.ToInt32(pct.Name)%9==0) pct.BackColor=Color.DarkGoldenrod;
if (Convert.ToInt32(pct.Name)%11==0) pct.BackColor=Color.Gold;
if (Convert.ToInt32(pct.Name)%11==0) pct.BackColor=Color.Tomato;";
//
// btModifier
//
this.btModifier.Location = new System.Drawing.Point(432, 136);
this.btModifier.Name = "btModifier";
this.btModifier.TabIndex = 1;
this.btModifier.Text = "Modifier";
this.btModifier.Click += new System.EventHandler(this.button1_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.lbTaille);
this.groupBox1.Controls.Add(this.lbRupture);
this.groupBox1.Controls.Add(this.lbNombrePbox);
this.groupBox1.Controls.Add(this.numRupture);
this.groupBox1.Controls.Add(this.numTaille);
this.groupBox1.Controls.Add(this.numNombre);
this.groupBox1.Controls.Add(this.tbCode);
this.groupBox1.Controls.Add(this.btModifier);
this.groupBox1.Location = new System.Drawing.Point(0, 200);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(520, 168);
this.groupBox1.TabIndex = 2;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Modification Motif";
//
// lbTaille
//
this.lbTaille.Location = new System.Drawing.Point(56, 96);
this.lbTaille.Name = "lbTaille";
this.lbTaille.Size = new System.Drawing.Size(100, 24);
this.lbTaille.TabIndex = 7;
this.lbTaille.Text = " : Taille PBox";
this.lbTaille.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// lbRupture
//
this.lbRupture.Location = new System.Drawing.Point(56, 72);
this.lbRupture.Name = "lbRupture";
this.lbRupture.Size = new System.Drawing.Size(100, 24);
this.lbRupture.TabIndex = 6;
this.lbRupture.Text = " : Point de Rupture";
this.lbRupture.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// lbNombrePbox
//
this.lbNombrePbox.Location = new System.Drawing.Point(56, 48);
this.lbNombrePbox.Name = "lbNombrePbox";
this.lbNombrePbox.Size = new System.Drawing.Size(100, 24);
this.lbNombrePbox.TabIndex = 5;
this.lbNombrePbox.Text = " : Nombre de PBox";
this.lbNombrePbox.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// numRupture
//
this.numRupture.Location = new System.Drawing.Point(8, 72);
this.numRupture.Maximum = new System.Decimal(new int[] {
200,
0,
0,
0});
this.numRupture.Name = "numRupture";
this.numRupture.Size = new System.Drawing.Size(48, 20);
this.numRupture.TabIndex = 4;
this.numRupture.Value = new System.Decimal(new int[] {
7,
0,
0,
0});
//
// numTaille
//
this.numTaille.Location = new System.Drawing.Point(8, 96);
this.numTaille.Maximum = new System.Decimal(new int[] {
40,
0,
0,
0});
this.numTaille.Name = "numTaille";
this.numTaille.Size = new System.Drawing.Size(48, 20);
this.numTaille.TabIndex = 3;
this.numTaille.Value = new System.Decimal(new int[] {
20,
0,
0,
0});
//
// numNombre
//
this.numNombre.Location = new System.Drawing.Point(8, 48);
this.numNombre.Maximum = new System.Decimal(new int[] {
500,
0,
0,
0});
this.numNombre.Name = "numNombre";
this.numNombre.Size = new System.Drawing.Size(48, 20);
this.numNombre.TabIndex = 2;
this.numNombre.Value = new System.Decimal(new int[] {
49,
0,
0,
0});
//
// pnPbox
//
this.pnPbox.Location = new System.Drawing.Point(0, 0);
this.pnPbox.Name = "pnPbox";
this.pnPbox.Size = new System.Drawing.Size(528, 200);
this.pnPbox.TabIndex = 3;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(526, 371);
this.Controls.Add(this.pnPbox);
this.Controls.Add(this.groupBox1);
this.Name = "Form1";
this.Text = "DomiGrille";
this.Load += new System.EventHandler(this.Form1_Load);
this.groupBox1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(
this.numRupture)).EndInit();
((System.ComponentModel.ISupportInitialize)(
this.numTaille)).EndInit();
((System.ComponentModel.ISupportInitialize)(
this.numNombre)).EndInit();
this.ResumeLayout(false);
}
#endregion
///
/// Point d'entrée principal de l'application.
///
[STAThread]
static void Main()
{
Application.Run(
new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
addPict(
this.pnPbox.Controls,49,new Size(20,20),new Point(14,14),7);
}
private void addPict(Control.ControlCollection Ctrls, int iNbPict,
Size LaTaille, Point AquelEndroit,
int Rupture)
{
int Rangee=AquelEndroit.X,Colonne=AquelEndroit.Y;
for (int i=1;i<=iNbPict;i++)
{
PictureBox b=
new PictureBox();
b.Name=i.ToString();
// pas oblig.
b.Size=LaTaille;
b.BackColor=Color.White;
b.BorderStyle=BorderStyle.FixedSingle;
b.Click+=
new EventHandler(ClickSurPict);
b.Location=
new Point(Colonne,Rangee);
Ctrls.Add(b);
Colonne+=b.Width;
if (i%Rupture==0)
{
Colonne=AquelEndroit.Y;
//retour colonne de départ
Rangee+=b.Height;
}
}
}
// procédure d'évenement
private void ClickSurPict(object sender, System.EventArgs e)
{
MessageBox.Show(((PictureBox)sender).Name);
}
private void button1_Click(object sender, System.EventArgs e)
{
RegenerationPBox();
// panel de PictureBox
GenerationCouleur();
// coloriage des Pictures Box
}
private void GenerationCouleur()
{
// On compilera du C# hein ;)
CSharpCodeProvider codeProvider =
new CSharpCodeProvider();
ICodeCompiler compiler = codeProvider.CreateCompiler();
// Parmètres qu'on passera au compilateur
System.CodeDom.Compiler.CompilerParameters parameters =
new CompilerParameters();
parameters.GenerateInMemory =
true; // On gardera l'assembly uniquement en mémoire
// DLL Story pour la compilation
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Drawing.dll");
parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
parameters.ReferencedAssemblies.Add("System.Data.dll");
// Source du Code pour la compilation
// Il sera plus interessant de le mettre dans un fichier à part et de le lire
// Mais bon, à 1H du mat, j'avais la flemme :p
string codeAgenerer = @"using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace DomiTicTacToe{
public class CDTic {
System.Windows.Forms.Form parentForm;
public CDTic(System.Windows.Forms.Form mForm){
parentForm = mForm;
GenereTic();}
private void GenereTic(){
foreach ( Control pct in ((Panel)parentForm.GetChildAtPoint(new Point(20,20))).Controls){
if(pct.GetType().ToString() == ""System.Windows.Forms.PictureBox""){";
// On ajoute le code inséré dans la TextBox et on ferme la source :)
codeAgenerer = String.Concat(codeAgenerer,tbCode.Text,"}}}}}");
//On Compile
CompilerResults cr = compiler.CompileAssemblyFromSource(parameters, codeAgenerer);
// on regarde si il y a des erreurs
if (cr.Errors.Count > 0)
{
//On affiche toutes les erreurs
foreach(CompilerError CompErr in cr.Errors)
{
MessageBox.Show("Ligne " + CompErr.Line + ", Erreur Numero : " + CompErr.ErrorNumber + ", '" + CompErr.ErrorText + ";" + Environment.NewLine + Environment.NewLine);
}
}
else // On tente d'utiliser l'assembly
{
try
{
// On récupère l'assembly en mémoire
Assembly asm = cr.CompiledAssembly;
// On récupère son Type
Type t = asm.GetType("DomiTicTacToe.CDTic");
// Flags pour la construction d'une instance de l'object
BindingFlags bflags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
// Construit une instance de l'Object (noté le passage d'argument au constructeur à la fin
Object obj = t.InvokeMember("CDTic", bflags |
BindingFlags.CreateInstance,
null, null, new object[]{this});
}
catch(Exception eX)
{
MessageBox.Show(eX.Message,"Oooops",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
}
private void RegenerationPBox()
{
// On vide le panel ;)
// C'est toujours mieux que de faire un Foreach sur This.Controls et de se retrouver avec une null Exception :p
this.pnPbox.Controls.Clear();
// Alors la, cest la ligne inmangeable !
addPict(
this.pnPbox.Controls, Convert.ToInt32(numNombre.Value), new Size(Convert.ToInt32(numTaille.Value),Convert.ToInt32(numTaille.Value)),new Point(10,10), Convert.ToInt32(numRupture.Value));
}
}
}
########################
Bon Amusement ;)
Après avoir lu l'article paru hier matin sur c2i sur les "petits jeux esthétiques", j'ai eu le malheure de dire à Richard, ca serait tellement plus drole avec de la reflection ...
Et bien, cette petite phrase est devenue réalité après quelques petites prises de tête :
Premier essai (on est encore loin de la girafe là) :

En modifiant un peu le code dans la TextBox (on y arrive toujours pas ... à la girafe) :
En tout cas, je vous mets à dispo le code, dès que je laurais un peu améliorer (là, cest du porcinet d'or en puissance) et surtout commenter (le commentaire de sources, c'est pas mon fort hein Vlad ;)
En tout cas, cest bien marrant de faire du CodeDom, de la Reflection, le tout en mémoire sur/avec des Assemblies ! Au fait, Vlad pour te rassurer, j'ai pas fait de reflection à partir de l'assembly reflectionée pour Form1, j'ai seulement casté avec System.Windows.Forms.Form ! lol
Au fait, pour ceux qui diront, Rolala, mais c'est un malade, on aurait pu faire ça beaucoup plus proprement avec une interface ici ... ou là .... bah... je leur répondrais ...que je me suis pas tapé à refaire l'original depuis zéro pour justement montrer la puissance de la Reflection et Codedom :D
Par contre c'est vrai, que maintenant, avant de me lancer dans l'inconnu, je serais qu'avec une interface c'est beaucoup mieux et surtout moins prise de tête :p
Allez dodo, si vous voulez avoir les sources pas trop tard dans la journée :)
NB: Promis Richard, je te fais un applet .net pour ton chat, mais pas tout de suite hein, ca attendra un peu que les projets de classe soient bien avancées ;)
[UPDATE] :
Je vais ajouter ce qu'il faut aussi pour choisir le nombre de picturebox que l'on désire ainsi que l'endroit de la rupture et la taille :p Je suis plus à une ligne de code hein, alors autant le faire bien :D