Hi,

My article has been published on CSharpcorner

 

Maybe you should check it out!

http://www.c-sharpcorner.com/UploadFile/iersoy/515/Default.aspx

Etiketler : XNA Asset Encryption Microsoft
Kategoriler : Microsoft XNA
Yorumlar : 0 Yorum Yorum Yaz

Merhabalar,

Eminim ki Asset Şifreleme makalelerimi neden yazdığımı merak etmişsinizdir.Bu makaleleri aslında -esas anlatmak istediğim- “XNB Güvenliği” adlı makaleme alıştırmak için yazdım J
XNB nin tanımını yapalım...

XNB Dosyası Nedir?
XNB dosyası,Oyun içinde bulunan içeriklerinizin yani Assetlerinizi çalışma anında şifreleyen ve XNA frameworkünde kullanılmasını sağlayan şifrelenmiş bir dosya tipidir.

Oyununuzu yayınlarken endişe etmemeniz gerekir demem lazımdı aslında ama size bir haberim var: Bir XNA geliştiricisinin “XNB Builder” yazdığını gördüm.Bu uygulama sayesinde, XNB dosyası “Reverse Engineering” yapılarak XNA projemizde kullandığımız tüm Assetlerimiz bu uygulama içerisinde görüntülenebilmektedir.

Bu bana göre ve XNA de oyun geliştiren çoğu kişiye(eğer ki ticari bir oyun projesinde bulunuyorlarsa) çok ciddi bir sorundur.Ama çözümü de çok basittir:
”XNB Dosyalarımızı Şifreleyeceğiz”

Assetlerin çalışma anında kullanılabilmesi ve kapandıktan sonra tekrar şifrelenmesine yönelik çok basit bir örnek yapacağız.

Yapacağımız uygulama aslında Model,Video  ve Doku Yükleme ile alakalı olacaktır.

Öncelikle belirtmem gereken bir durum bulunmaktadır:

Video Dosyalarını Content Importer vasıtasıyla projemize eklerken,bir adet XNB ve bir adet de orjinal dosyayı oluşturmaktadır.Bu durumda yapacağımız her iki dosyayı da şifrelemek olacak.


Bu yazımı o kadar fazla uzun yazmamaya özen göstereceğim.Aslında yapmak istediklerimizi Asset Şifreleme -2 makalesinde zaten yaptık.Bu yazımızda sadece üzerine birkaç adet kodlama ekleyeceğiz.

O haldeyse başlıyoruz:


Sistem olarak bir önceki makaledeki Rijndael(AES) Algoritmasında kullandığımız altyapıyı kullanacağız.

 1.png

Bu tarz bir sistem kuruyoruz.Contentimizin içerisinde Dokular,Modeller,Videolar diye klasörler oluşturup içlerine Assetlerimizi yerleştiriyoruz.Content in içine yerleştirmemizin sebebi; Content Importerların Assetlerimizi XNB dosyalarına dönüştürmesini sağlamak amacıyladır.

 

Tüm uygulamaya ait kodları yayınlayıp ardından açıklayacağım...

 

using System;

using System.Collections.Generic;

using System.Linq;

using Microsoft.Xna.Framework;

using Microsoft.Xna.Framework.Audio;

using Microsoft.Xna.Framework.Content;

using Microsoft.Xna.Framework.GamerServices;

using Microsoft.Xna.Framework.Graphics;

using Microsoft.Xna.Framework.Input;

using Microsoft.Xna.Framework.Media;

using Microsoft.Xna.Framework.Net;

using Microsoft.Xna.Framework.Storage;

using System.Windows.Forms;

using System.Drawing;

using System.IO;

using System.Security.Cryptography;

using System.Text;

 

namespace XNBSifrele

{

    public class Game1 : Microsoft.Xna.Framework.Game

    {

        GraphicsDeviceManager graphics;

        SpriteBatch spriteBatch;

        private string password = "ornek";

        MenuStrip menuStrip1;

        ToolStripMenuItem gosterToolStripMenuItem;

        ToolStripMenuItem modelToolStripMenuItem;

        ToolStripMenuItem dokuToolStripMenuItem;

        ToolStripMenuItem videoToolStripMenuItem;

        bool vcal;

        bool model_yuklendi,doku_yuklendi,video_yuklendi;

              

        Label dosyaenc = new Label();

        Label dosyade = new Label();

      

        //Model Yukleme Değişkenleri

        Model myModel;

        float aspectRatio;

        Vector3 modelPosition = Vector3.Zero;

        float modelRotation = 0.0f;

        Vector3 cameraPosition = new Vector3(100.0f, 500.0f, 500.0f);

 

        //Doku Yükleme Değişkenleri

        Texture2D myTexture;

        Vector2 spritePosition = Vector2.Zero;

 

        //Video Yükleme Değişkenleri

        Video myVideoFile;

        VideoPlayer videoPlayer=new VideoPlayer();

 

 

        public Game1()

        {

            graphics = new GraphicsDeviceManager(this);

            Content.RootDirectory = "Content";

            DecryptFile("Content/Modeller/torus_xnb.ibo");

            DecryptFile("Content/Dokular/armor_xnb.ibo");

            DecryptFile("Content/Videolar/Wildlife_xnb.ibo");

            DecryptFile("Content/Videolar/Wildlife_wmv.ibo");

        }

 

        protected override void Initialize()

        {

            this.menuStrip1 = new System.Windows.Forms.MenuStrip();

            this.gosterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

            this.modelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

            this.dokuToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

            this.videoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

                                

            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {

            this.gosterToolStripMenuItem});

            this.menuStrip1.BackColor = System.Drawing.Color.CornflowerBlue;

            this.menuStrip1.Location = new System.Drawing.Point(0, 0);

            this.menuStrip1.Name = "menuStrip1";

            this.menuStrip1.Size = new System.Drawing.Size(707, 24);

            this.menuStrip1.TabIndex = 0;

            this.menuStrip1.Text = "menuStrip1";

            //

            // gosterToolStripMenuItem

            //

            this.gosterToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {

            this.modelToolStripMenuItem,

            this.dokuToolStripMenuItem,

            this.videoToolStripMenuItem});

            this.gosterToolStripMenuItem.Name = "gosterToolStripMenuItem";

            this.gosterToolStripMenuItem.Size = new System.Drawing.Size(53, 20);

            this.gosterToolStripMenuItem.Text = "Goster";

            //

            // modelToolStripMenuItem

            //

            this.modelToolStripMenuItem.Name = "modelToolStripMenuItem";

            this.modelToolStripMenuItem.Size = new System.Drawing.Size(152, 22);

            this.modelToolStripMenuItem.Text = "Model";

            modelToolStripMenuItem.Click+=new EventHandler(Model_Yukle);

            //

            // dokuToolStripMenuItem

            //

            this.dokuToolStripMenuItem.Name = "dokuToolStripMenuItem";

            this.dokuToolStripMenuItem.Size = new System.Drawing.Size(152, 22);

            this.dokuToolStripMenuItem.Text = "Doku";

            dokuToolStripMenuItem.Click+=new EventHandler(Doku_Yukle);

            //

            // videoToolStripMenuItem

            //

            this.videoToolStripMenuItem.Name = "videoToolStripMenuItem";

            this.videoToolStripMenuItem.Size = new System.Drawing.Size(152, 22);

            this.videoToolStripMenuItem.Text = "Video";

            videoToolStripMenuItem.Click+=new EventHandler(Video_Yukle);

 

                                  

            Control.FromHandle(Window.Handle).Controls.Add(menuStrip1);

            base.Initialize();

        }

 

        protected override void LoadContent()

        {

            spriteBatch = new SpriteBatch(GraphicsDevice);

            myModel = Content.Load<Model>("Modeller\\torus");

            aspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio;

            myTexture = Content.Load<Texture2D>("Dokular\\Armor");

            myVideoFile = Content.Load<Video>("Videolar\\Wildlife");

        }

 

        protected void Model_Yukle(Object sender, EventArgs e)

        {

            model_yuklendi = true;

            doku_yuklendi = false;

            video_yuklendi = false;

        }

 

        protected void Doku_Yukle(Object sender, EventArgs e)

        {

            doku_yuklendi = true;

            video_yuklendi = false;

            model_yuklendi = false;

        }

 

        protected void Video_Yukle(Object sender, EventArgs e)

        {

            video_yuklendi = true;

            doku_yuklendi = false;

            model_yuklendi = false;

        }

 

        protected override void UnloadContent()

        {

            videoPlayer.Stop();

            videoPlayer.Dispose();

           

            EncryptFile("Content/Modeller/torus.xnb");

            EncryptFile("Content/Dokular/Armor.xnb");

            EncryptFile("Content/Videolar/Wildlife.wmv");

            EncryptFile("Content/Videolar/Wildlife.xnb");

        }

 

        protected override void Update(GameTime gameTime)

        {

            if (model_yuklendi == true)

            {

                modelRotation += (float)gameTime.ElapsedGameTime.TotalMilliseconds *

       MathHelper.ToRadians(0.1f);

            }

 

            if (video_yuklendi == true)

            {

                KeyboardState stat = Keyboard.GetState();

                if (stat.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Space))

                {

                    vcal = true;

                    videoPlayer.Play(myVideoFile);

 

                }

                else if (stat.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape))

                {

                    vcal = false;

                    videoPlayer.Stop();

                }

            }          

 

            base.Update(gameTime);

        }

 

        protected override void Draw(GameTime gameTime)

        {

            GraphicsDevice.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);

 

 

            if (model_yuklendi == true)

            {

                Matrix[] transforms = new Matrix[myModel.Bones.Count];

                myModel.CopyAbsoluteBoneTransformsTo(transforms);

 

                foreach (ModelMesh mesh in myModel.Meshes)

                {

                    foreach (BasicEffect effect in mesh.Effects)

                    {

                        effect.EnableDefaultLighting();

                        effect.World = transforms[mesh.ParentBone.Index] *

                            Matrix.CreateRotationY(modelRotation)

                            * Matrix.CreateTranslation(modelPosition);

                        effect.View = Matrix.CreateLookAt(cameraPosition,

                            Vector3.Zero, Vector3.Up);

                        effect.Projection = Matrix.CreatePerspectiveFieldOfView(

                            MathHelper.ToRadians(90.0f), aspectRatio,

                            1.0f, 10000.0f);

                    }

                    mesh.Draw();

                }

            }

 

            if (doku_yuklendi == true)

            {

                spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

                spriteBatch.Draw(myTexture, spritePosition, Microsoft.Xna.Framework.Graphics.Color.White);

                spriteBatch.End();

            }          

 

            if (vcal == true)

            {

                spriteBatch.Begin();

                spriteBatch.Draw(videoPlayer.GetTexture(), new Microsoft.Xna.Framework.Rectangle(0, 0, myVideoFile.Width, myVideoFile.Height), Microsoft.Xna.Framework.Graphics.Color.White);

                spriteBatch.End();               

            }                     

 

            base.Draw(gameTime);

        }

 

        private void EncryptFile(string encyol)

        {

            int position = 0, t = 0;

            while (encyol.IndexOf('\\', t) != -1)

            {

                position = encyol.IndexOf('\\', t);

                t = position;

            }

 

            string outfile = encyol.Substring(position);

            outfile = outfile.Replace('.', '_');

            dosyaenc.Text = outfile + ".ibo";

 

            try

            {

                if (password.Length > 8)

                    password = password.Substring(0, 8);

                else if (password.Length < 8)

                {

                    int add = 8 - password.Length;

                    for (int i = 0; i < add; i++)

                        password = password + i;

                }

                UnicodeEncoding UE = new UnicodeEncoding();

                byte[] key = UE.GetBytes(password);

 

                string cryptFile = dosyaenc.Text;

                FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);

 

                RijndaelManaged RMCrypto = new RijndaelManaged();

 

                CryptoStream cs = new CryptoStream(fsCrypt,

                    RMCrypto.CreateEncryptor(key, key),

                    CryptoStreamMode.Write);

 

                FileStream fsIn = new FileStream(encyol, FileMode.Open);

 

                int data;

                while ((data = fsIn.ReadByte()) != -1)

                    cs.WriteByte((byte)data);

             

                fsIn.Close();

                cs.Close();

                fsCrypt.Close();

                File.Delete(encyol);

            }

            catch

            {

                MessageBox.Show("Şifreleme Başarısız Oldu!", "Hata");

            }          

        }

 

        private void DecryptFile(string decyol)

        {

            int position = 0, t = 0;

            while (decyol.IndexOf('\\', t) != -1)

            {

                position = decyol.IndexOf('\\', t);

                t = position;

            }

            string outfile = decyol.Substring(0, decyol.Length - 4);

            outfile = outfile.Substring(position);

            dosyade.Text = outfile.Replace('_', '.');

 

            try

            {

                if (password.Length > 8)

                    password = password.Substring(0, 8);

                else if (password.Length < 8)

                {

                    int add = 8 - password.Length;

                    for (int i = 0; i < add; i++)

                        password = password + i;

                }

 

                UnicodeEncoding UE = new UnicodeEncoding();

                byte[] key = UE.GetBytes(password);

 

                FileStream fsCrypt = new FileStream(decyol, FileMode.Open);

 

                RijndaelManaged RMCrypto = new RijndaelManaged();

 

                CryptoStream cs = new CryptoStream(fsCrypt,

                    RMCrypto.CreateDecryptor(key, key),

                    CryptoStreamMode.Read);

 

                FileStream fsOut = new FileStream(dosyade.Text, FileMode.Create);

 

                int data;

                while ((data = cs.ReadByte()) != -1)

                    fsOut.WriteByte((byte)data);

 

                fsOut.Close();

                cs.Close();

                fsCrypt.Close();              

                File.Delete(decyol);

            }

            catch

            {

                MessageBox.Show("Bir hata alınmıştır.Özür dileriz:", "Hata");

            }

        }

    }

}

 

 

 

**************************************

 

MenuStrip menuStrip1;

ToolStripMenuItem gosterToolStripMenuItem;

ToolStripMenuItem modelToolStripMenuItem;

ToolStripMenuItem dokuToolStripMenuItem;

ToolStripMenuItem videoToolStripMenuItem;

 

Burada projemizde kullanacağımız menüye ait elemanları tanımlıyoruz.

Goruntule adlı esas menü başlığı ve Model,Doku,Video adlı 3 adet menü elemanı bulunacaktır.

 

 

bool vcal;

bool model_yuklendi,doku_yuklendi,video_yuklendi;

 

Bu kodlamada “vcal” video yüklendiğinde “Space” tuşuna bastığımızda videoyu oynatmamıza “Escape” tuşuna bastığımızda da videoyu durdurmamızı sağlamaktadır.

Model_yuklendi,doku_yuklendi,video_yuklendi : model,doku ve video nun yüklenip yüklenmediğini kontrol etmektedir.

 

 //Model Yukleme Değişkenleri

 Model myModel;

 float aspectRatio;

 Vector3 modelPosition = Vector3.Zero;

 float modelRotation = 0.0f;

 Vector3 cameraPosition = new Vector3(100.0f, 500.0f, 500.0f);

 

Bu kodlama yorumda da belirttiğim üzere Model Yükleme işlemleri gerçekleşmesi için gereken değişkenlerin tanımlanmasıdır.Model’in instance’ı,bulunacağı yer,kameranın pozisyon bilgisi gibi değişkenleri tanımlamaktadır.

 

 //Doku Yükleme Değişkenleri

Texture2D myTexture;

Vector2 spritePosition = Vector2.Zero;

 

 

Bu kodlamada da yükleyeceğimiz dokuya ait değişkenleri barındırmaktayız.

 

 

//Video Yükleme Değişkenleri

Video myVideoFile;

VideoPlayer videoPlayer=new VideoPlayer();

 

Bu kodlamada ise Video yüklemeye ait değişkenlerimizi barındırmaktayız.

 

public Game1()

{

  graphics = new GraphicsDeviceManager(this);

  Content.RootDirectory = "Content";

  DecryptFile("Content/Modeller/torus_xnb.ibo");

  DecryptFile("Content/Dokular/armor_xnb.ibo");

  DecryptFile("Content/Videolar/Wildlife_xnb.ibo");

  DecryptFile("Content/Videolar/Wildlife_wmv.ibo");

}

 

Bu kısımda uygulama ilk açıldığında Şifrelenen Assetlerimizin şifrelerinin ortadan kaldırılarak kullanıma açılmasını göstermektedir.

Uygulama ilk açıldığında Şifreler ortadan kalkarken,kapandığında tekrar şifreleme yapılmaktadır.Aynen aşağıda gördüğünüz üzere;

protected override void UnloadContent()

{

  videoPlayer.Stop();

  videoPlayer.Dispose();

           

  EncryptFile("Content/Modeller/torus.xnb");

  EncryptFile("Content/Dokular/Armor.xnb");

  EncryptFile("Content/Videolar/Wildlife.wmv");

  EncryptFile("Content/Videolar/Wildlife.xnb");

}

 

 

 

Devam ediyoruz...

 

 

protected override void Initialize()

        {

            this.menuStrip1 = new System.Windows.Forms.MenuStrip();

            this.gosterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

            this.modelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

            this.dokuToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

            this.videoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

                                

            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {

            this.gosterToolStripMenuItem});

            this.menuStrip1.BackColor = System.Drawing.Color.CornflowerBlue;

            this.menuStrip1.Location = new System.Drawing.Point(0, 0);

            this.menuStrip1.Name = "menuStrip1";

            this.menuStrip1.Size = new System.Drawing.Size(707, 24);

            this.menuStrip1.TabIndex = 0;

            this.menuStrip1.Text = "menuStrip1";

            //

            // gosterToolStripMenuItem

            //

            this.gosterToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {

            this.modelToolStripMenuItem,

            this.dokuToolStripMenuItem,

            this.videoToolStripMenuItem});

            this.gosterToolStripMenuItem.Name = "gosterToolStripMenuItem";

            this.gosterToolStripMenuItem.Size = new System.Drawing.Size(53, 20);

            this.gosterToolStripMenuItem.Text = "Goster";

            //

            // modelToolStripMenuItem

            //

            this.modelToolStripMenuItem.Name = "modelToolStripMenuItem";

            this.modelToolStripMenuItem.Size = new System.Drawing.Size(152, 22);

            this.modelToolStripMenuItem.Text = "Model";

            modelToolStripMenuItem.Click+=new EventHandler(Model_Yukle);

            //

            // dokuToolStripMenuItem

            //

            this.dokuToolStripMenuItem.Name = "dokuToolStripMenuItem";

            this.dokuToolStripMenuItem.Size = new System.Drawing.Size(152, 22);

            this.dokuToolStripMenuItem.Text = "Doku";

            dokuToolStripMenuItem.Click+=new EventHandler(Doku_Yukle);

            //

            // videoToolStripMenuItem

            //

            this.videoToolStripMenuItem.Name = "videoToolStripMenuItem";

            this.videoToolStripMenuItem.Size = new System.Drawing.Size(152, 22);

            this.videoToolStripMenuItem.Text = "Video";

            videoToolStripMenuItem.Click+=new EventHandler(Video_Yukle);

 

                                   

            Control.FromHandle(Window.Handle).Controls.Add(menuStrip1);

            base.Initialize();

        }

 

 

Initialize() fonksiyonumuzda Menümüzü oluşturuyoruz...

 

 

 

protected override void LoadContent()

{

   spriteBatch = new SpriteBatch(GraphicsDevice);

   myModel = Content.Load<Model>("Modeller\\torus");

   aspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio;

   myTexture = Content.Load<Texture2D>("Dokular\\Armor");

   myVideoFile = Content.Load<Video>("Videolar\\Wildlife");

}

 

LoadContent() fonksiyonumuzda projemize ait Contentlerimizi yüklüyoruz.Model,Doku,Video ya ait değişkenlerimiz vasıtasıyla ilgili Assetlerimizi çağırıyoruz...

 


protected void Model_Yukle(Object sender, EventArgs e)

        {

            model_yuklendi = true;

            doku_yuklendi = false;

            video_yuklendi = false;

        }

 

        protected void Doku_Yukle(Object sender, EventArgs e)

        {

            doku_yuklendi = true;

            video_yuklendi = false;

            model_yuklendi = false;

        }

 

        protected void Video_Yukle(Object sender, EventArgs e)

        {

            video_yuklendi = true;

            doku_yuklendi = false;

            model_yuklendi = false;

        }


Bu fonksiyonlarda Modelin,Dokunun,Videonun yüklenip yüklenmediğini kontrol ettiriyoruz.Menü den ilgili eleman seçildiğinde burada bulunan ilgili fonksiyon çalıştırılmaktadır.Bunun neticesinde de Model,Doku ve Video nun yükleme işleminin altyapısını oluşturmaktayız.

 

protected override void Update(GameTime gameTime)

{

 if (model_yuklendi == true)

 {

  modelRotation += (float)gameTime.ElapsedGameTime.TotalMilliseconds *

  MathHelper.ToRadians(0.1f);

 }

 if (video_yuklendi == true)

 {

  KeyboardState stat = Keyboard.GetState();

  if (stat.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Space))

  {

    vcal = true;

    videoPlayer.Play(myVideoFile);

  }

  else if (stat.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape))

  {

    vcal = false;

    videoPlayer.Stop();

  }

 }          
 base.Update(gameTime);
}

 

 

 

 

 

Bu kısımda eğer model yükleme işlemi yapıldıysa modelin belirli bir açı vasıtasıyla döndürüleceğini bildiriyoruz.


Eğer video yüklendiyse;
Eğer Space tuşuna basıldıysa Video nesnemizin ilgili videoyu oynatmasını,Escape tuşuna bastıysa da videoyu durdurmasını belirtiyoruz.

 

 

 

protected override void Draw(GameTime gameTime)

{

GraphicsDevice.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);

 if (model_yuklendi == true)

 {

  Matrix[] transforms = new Matrix[myModel.Bones.Count];

  myModel.CopyAbsoluteBoneTransformsTo(transforms);

 

  foreach (ModelMesh mesh in myModel.Meshes)

  {

   foreach (BasicEffect effect in mesh.Effects)

   {

    effect.EnableDefaultLighting();

    effect.World = transforms[mesh.ParentBone.Index] *

    Matrix.CreateRotationY(modelRotation)

    * Matrix.CreateTranslation(modelPosition);

    effect.View = Matrix.CreateLookAt(cameraPosition,

    Vector3.Zero, Vector3.Up);

    effect.Projection = Matrix.CreatePerspectiveFieldOfView;          MathHelper.ToRadians(90.0f), aspectRatio,1.0f, 10000.0f);

   }

   mesh.Draw();

  }

 }

 

 if (doku_yuklendi == true)

 {

  spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

  spriteBatch.Draw(myTexture, spritePosition, Microsoft.Xna.Framework.Graphics.Color.White);

  spriteBatch.End();

 }          

 

 if (vcal == true)

 {

  spriteBatch.Begin();

  spriteBatch.Draw(videoPlayer.GetTexture(), new Microsoft.Xna.Framework.Rectangle(0, 0, myVideoFile.Width, myVideoFile.Height), Microsoft.Xna.Framework.Graphics.Color.White);

  spriteBatch.End();               

 }                     

 

 base.Draw(gameTime);

}

 

 

Bu kısımda da Model yükleme işlemi başlatıldıysa Model yükleme kodunun çalıştırılmasını,Doku yüklendiyse Doku yükleme kodunun çalıştırılmasını ve vcal değeri true ya eşit ise de Videoyu çizmesini söylüyoruz...

 

 

Projemizi çalıştırdığımızda dosya boyutlarına göre şifrenin ortadan kaldırılmasını beklememiz gerekmektedir.

 

2.png

 

Uygulamamızın ilk açıldığı ekran...

 

3.png

 

Göster->Model e tıkladığımızda Modelimizi görüntülüyoruz...

 

4.png

 

Göster-> Doku ya basınca Dokumuzu görüntülüyoruz...

 

5.png

 

Göster->Video ya basınca da Videomuzu oynatıyoruz...

 

 

 

Bu projemizde bu kadar.Artık Assetleriniz konusunda endişe etmemeniz gerekmektedir.Çünkü Rijndael(AES) ile meraklı gözlerden Assetlerimizi korumuş olacağız...

 

Umarım bu makale dizimin sizlere bir faydası olur.

 

Bol bol XNA kodlamanız dileğiyle...

 

 


Uygulamanın Kaynak Kodları

 

 

 

İyi Günler Dilerim

Merhabalar,

 

İlk makalemizde Find&Replace algoritmasını .X dosyasında uygulamıştık ve dosyamızı şifreleyip ardından kullanıma açmıştık.Ve Find&Replace algoritmasının Text tabanlı dosya tipleriyle uyumlu çalıştığından söz etmiştik(Encoding den ötürü)

Makalemizin Kaynak Kodları

 

İşte bu bölümde  Oyun Assetlerinizin şifrelenmesini bir adım daha ileriye götüreceğim.

Ama ondan önce Hazırlamamız gereken birkaç sınıfımız olacaktır.

Ses ve Video Oynatmak için bir sınıf yazmalıyız.XNA in Content Importer larına bu işi bırakmadan halledeceğiz.


Projemizi Oluşturalım:


Projemizi oluşturduk şimdi sırada Projemize bir Class eklemekte.Projenize Mouse Sağ Tuş-> Add New Item-> Class ı seçip “VidSnd” adında yeni bir Class ekliyoruz:

 

 

 

Şimdi sırada Referanslarımızı eklemede:

Project->Add Reference ile DirectX ve AudioVideoPlayback aduzaylarımızı projeye dahil ediyoruz.

 

 

Şimdi de bu Class ı aşağıda gördüğünüz gibi güncelleyiniz...

Ek olarak “System.Windows.Forms” u da dahil ediniz.



using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.DirectX.AudioVideoPlayback;

using System.Windows.Forms;

 

namespace CryptAsset

{

    class VidSnd

    {

        public static Video vd;

        public static Audio ad;

 

        public VidSnd()

        {

 

        }

 

        public static void film_ac(string dosya_adi,IntPtr ownervid)

        {

            vd =new Video(dosya_adi);

            vd.Owner = Control.FromHandle(ownervid);                     

        }

 

        public static void film_oynat()

        {

            vd.Play();

        }

 

        public static void film_durdur()

        {

            vd.Stop();

        }

 

        public static void film_duraklat()

        {

            vd.Pause();

        }

       

        public static string ses_ac(string sesdosya)

        {

            ad = new Audio(sesdosya,false);

            return sesdosya;

        }

 

        public static void ses_oynat()

        {

            ad.Play();

        }

 

        public static void ses_durdur()

        {

            ad.Stop();

        }

 

        public static void ses_duraklat()

        {

            ad.Pause();

        }

    }

}

 

 

Görüldüğü üzere oldukça anlaşılır bir biçimde Video ve Ses işlemleri yapmaktayız.Oluşturma,açma,durdurma ve kapatma gibi basit görevler için fonksiyon yazmış olduk.

 

 

Video ve Ses işlemleri için Classımızı yazmış olduk.Deneme yapmak için projenize 1 video ve 1 ses dosyası ekleyiniz.Ve

Game1.cs dosyamızda video dosyası oynatmak için herhangi bir yerde:

 

VidSnd.film_ac("Ornek.wmv", Window.Handle);

VidSnd.film_oynat();

Demeniz yeterli olacaktır.ve ilgili film dosyası GameWindow da gözükecektir.

 

Farkettiyseniz “Video Content Importer” kullanmadan bu işimizi hallettik.

 

Şimdi de sıra projemize daha fazla Asset ekleyip bunları Rijndael algoritması vasıtasıyla şifrelemek ardından tekrar kullanıma açmak olacaktır.

.FX(Efekt dosyaları)
.DDS(Doku Dosyası)
.X(DirectX Model)
.FBX(Autodesk Model)
.MP3(Müzik Dosyası)
.WMV(Video Dosyası)
.LUA(Lua Scripti)

 

Bu dosya tiplerine ait birkaç klasör oluşturalım.Şekilde görüldüğü :

 


Dokular,Efektler,Modeller,Scriptler,Sesler,Videolar adında klasörler oluşturalım.Genelde Oyun Assetleri düzenli olsunlar diye klasörlere ayrılır ve oralarda saklanırlar.

Geri kalan Assetlerimizi de projemize dahil edelim

 

Dokular:



Projemize yukarda gördüğünüz gibi bir örnek bir doku yükledik.

Efektler:

Ekleyeceğimiz 2 adet efekt dosyası olacaktır; HLSL ve CGFX

HLSL; DirectX ve XNA’in resmi efekt dosya tipiyken,CGFX ise “CGFX API”si vasıtasıyla OpenGL’de kullanılmaktadır.Ama XNA için de kullanabileceğimiz bir Content Importer yazmaktayım.Yakında onu da sizinle paylaşırım.

 

2 efektimizi de projemize dahil ediyoruz.Bu iki efektimizde “Post Glow” Efekti vermektedir.

Nvidia FX Composer 2.5 ile yazılmışlardır:

 



Modeller:

İki adet model dosyamız bulunmaktadır

 

 

 

 

 

ev.fbx adlı Autodesk Model dosya tipimiz ve fish.x adlı DirectX model dosya tipimiz Modeller Klasörümüze gördüğünüz gibi eklenmiştir.

 


Scriptler:

 

Basit bir bayrak çizim LUA scripti ekliyoruz.”LUAEdit” adlı program kullanılarak hazırlanmıştır.

 

 

 

 

 

 

 

BAYRAK.LUA

local r, g, b

 

 local x, y

 

 for y = 0, height - 1 do

   for x = 0, width - 1 do

      set_rgb(x, y, 1,0,0)

   end

   progress(y / height)

 end

 

 for y = 0.4 * height, 0.6 * height do

   for x = 0.2 * width, 0.8 * width do

      set_rgb(x, y, 1,1,1)

   end

   progress(y / height)

 end

 

 

 for y = 0.2 * height, 0.8 * height do

   for x = 0.4 * width, 0.6 * width do

      set_rgb(x, y, 1,1,1)

   end

   progress(y / height)

 end

 

 

Projenin son hali bu şekilde olacaktır.Tüm Proje Assetlerimizin Özelliklerine girip “Copy To Output Directory” özelliğini “Copy always” şeklinde güncelleyiniz.Bu projede bu Assetleri dahil etmemin sebebi farklı Dosya tiplerinde dahi tek bir algoritma(Rijndael) ile şifreleme işleminin yapılabileceğini göstermektir.Sadece gösterme amaçlı eklenmişlerdir.Birlikte kullanımına yönelik ilerleyen dönemlerde bir makale yazmayı düşünüyorum.Ama şimdilik yazımıza kaldığımız yerden devam edelim.Sırada Rijndael Algoritmasını tanıtmak ve kodlamak var

 

Rijndael Algoritması nedir?

Rijndael Algoritması aslında bu algoritmayı geliştirenlerin(Vincent Rijmen ve Joan Daemen) adlarının birleşiminden oluşan kod isimdir.Bu algoritmanın orjinal ismi AES yani “Advanced Encryption Standard” dır.1997 yılındaki NIST yarışmasında 1.olan Algoritmadır.Sağlam bir key kullanıldığında içimiz rahat olmalıdır.

Rijndael 128, 160, 192, 224, ve 256 bit blok boyutlarını desteklerken AES'te sadece 128 bit blok boyutu standarda dahil edilmiştir. Aynı şekilde Rijndael 128, 160, 192, 224, ve 256 bit anahtar boyutlarını desteklerken AES'te 128, 192 ve 256 bit anahtar boyutları standarda dahil edilmiştir. DES'in linear ve differential cryptoanalysis karşısında yenik düştüğü durumlara düşmemesi için özel önlemler alınmış, round içerisindeki xor'lamaların birbirine yakın bitlerdeki probabilistic bias'larının takip edilememesi için, des'te yer almayan mixcolomn ve shiftrow türü işlemlerle 128bitlik 8bitlik 4 satır ve 4 sütüna ayrılmış plaintexti çorbaya döndürmektedir. bugün bilinen tüm akademik ve pratik saldırılara, bruteforce'lara karşı dayanıklı olduğu düşünülmektedir. 8bitlik smart card işlemcilerinden 128bitlik olası fütüristik çiplere kadar destekleyebilecek şekilde tasarlanmıştır.

Oyun Projelerinizde assetlerinizi, Rijndael nam-ı diğer AES algoritması ile güvenli bir şekilde koruyabilirsiniz.Benim de bu makaleyi yazma amacım budur.Sizin hazırladığınız assetlerinizi başkalarının okuyamayacağı şekilde şifrelemek ve oyununuzda kullanabilmek.

O halde kısa bir açıklama yaptıktan sonra Algoritmamızı yazalım ve yukarıda belirttiğimiz tüm assetlerimizi şifreleyelim.ve ardından şifrelerini çözelim!


Game1.cs dosyamız üzerinde çalışacağız:

Öncelikle yapmamız gereken işlem bir takım aduzaylarının projemize dahil edilmesi.Nedir bunlar?


using System.IO;

using System.Security.Cryptography;

using System.Text;

 

Dosya tabanlı işlemlerimiz için IO,Şifreleme için Security.Cryptography ve Text tabanlı işlemlerimiz için de Text aduzaylarını projemize dahil ettik.

 

 

MenuStrip menuStrip1 = new MenuStrip();

ToolStripMenuItem enToolStripMenuItem = new ToolStripMenuItem();

ToolStripMenuItem encryptToolStripMenuItem = new ToolStripMenuItem();

ToolStripMenuItem deToolStripMenuItem = new ToolStripMenuItem();

ToolStripMenuItem decryptToolStripMenuItem = new ToolStripMenuItem();
Label dosyaenc = new Label();
private string password="ornek";

Label dosyade = new Label();
string dosyaencpath,dosyadecpath;

 Uygulamamıza Menü sistemi oluşturmak için Menu nesneleri ve şifreleme işlemleri için işimize yarayacak 2 adet Label nesnesi ekledik.ardından çevrilecek dosyalara ait yolları tutacak 2 adet string değişken tanımladık.


Initialize() fonksiyonumuzu da aşağıda görüldüğü gibi güncelliyoruz.Burada Menülerimizi yüklemiş oluyoruz:

menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {

            enToolStripMenuItem,deToolStripMenuItem});

            menuStrip1.Location = new System.Drawing.Point(0, 0);

            menuStrip1.Name = "menuStrip1";

            menuStrip1.Size = new System.Drawing.Size(877, 24);

            menuStrip1.TabIndex = 0;

            menuStrip1.Text = "menuStrip1";

            menuStrip1.BackColor = System.Drawing.Color.CornflowerBlue;

 

            //

            // fileToolStripMenuItem

            //

            enToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {

            encryptToolStripMenuItem});

            enToolStripMenuItem.Name = "fileToolStripMenuItem";

            enToolStripMenuItem.Size = new System.Drawing.Size(37, 20);

            enToolStripMenuItem.Text = "Encoding";

 

            //

            // Content

            //

            deToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {

            decryptToolStripMenuItem});

            deToolStripMenuItem.Name = "Contenta";

            deToolStripMenuItem.Size = new System.Drawing.Size(37, 20);

            deToolStripMenuItem.Text = "Decoding";

 

            //

            // Content dosyasını bildir

            //

            decryptToolStripMenuItem.Name = "Contentbildir";

            decryptToolStripMenuItem.Size = new System.Drawing.Size(152, 22);

            decryptToolStripMenuItem.Text = "Decode";

            decryptToolStripMenuItem.Click += new EventHandler(decryptToolStripMenuItem_Click);

 

            //

            // openFBXToolStripMenuItem

            //

 

 

            encryptToolStripMenuItem.Name = "openFBXToolStripMenuItem";

            encryptToolStripMenuItem.Size = new System.Drawing.Size(152, 22);

            encryptToolStripMenuItem.Text = "Encode";
            encryptToolStripMenuItem.Click += new EventHandler(encryptToolStripMenuItem_Click);

            Control.FromHandle(Window.Handle).Controls.Add(menuStrip1);

 

 

Şimdide Şifreleme kodlarımızı yazacağız:

private void EncryptFile(string encyol)

 {

   int position = 0, t = 0;

   while (encyol.IndexOf('\\', t) != -1)

    {

      position = encyol.IndexOf('\\', t);

      t = position;

    }

 

   string outfile = encyol.Substring(position);

   outfile = outfile.Replace('.', '_');

   dosyaenc.Text = outfile + ".ibo";

 

   try

    {

      if (password.Length > 8)

      password = password.Substring(0, 8);

      else if (password.Length < 8)

       {

         int add = 8 - password.Length;

         for (int i = 0; i < add; i++)

           password = password + i;

       }

      UnicodeEncoding UE = new UnicodeEncoding();

      byte[] key = UE.GetBytes(password);

 

      string cryptFile = dosyaenc.Text;

      FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);

 

      RijndaelManaged RMCrypto = new RijndaelManaged();
      CryptoStream cs = new CryptoStream(fsCrypt,

                    RMCrypto.CreateEncryptor(key, key),

      CryptoStreamMode.Write);

 

      FileStream fsIn = new FileStream(encyol, FileMode.Open);

 

      int data;

      while ((data = fsIn.ReadByte()) != -1)

              cs.WriteByte((byte)data);

 

      MessageBox.Show("Şifreleme Başarıyla Oluşturulmuştur!", "Tamamdır");

      fsIn.Close();

      cs.Close();

      fsCrypt.Close();

        File.Delete(encyol);

       }

      catch

       {

        MessageBox.Show("Şifreleme Başarısız Oldu!", "Hata");

       }

      

}

 

 

*******************

 

Şifrelemeyle ilgili kodları açıklayalım...

 

int position = 0, t = 0;

   while (encyol.IndexOf('\\', t) != -1)

    {

      position = encyol.IndexOf('\\', t);

      t = position;

    }

 

string outfile = encyol.Substring(position);

outfile = outfile.Replace('.', '_');

dosyaenc.Text = outfile + ".ibo";

 

 

Burada yapılan işlem; çıktı olacak dosyanın yol bilgisini alıp ters işaretleri ve “.” İşaretini ortadan kaldırıp yerine “_” işareti koyup dosya uzantısını “.ibo” olacak şekilde oluşturmaya yönelik ön hazırlıktır.Mesela dosyamız “okul.x” ise bu dosyayı “okul_x.ibo” şeklinde kaydedecektir.

 

 

if (password.Length > 8)

      password = password.Substring(0, 8);

      else if (password.Length < 8)

       {

         int add = 8 - password.Length;

         for (int i = 0; i < add; i++)

           password = password + i;

       }

 

 

Şifremizi “ornek” olarak vermiştik.burada maksimum 8 harfli bir şifre verebileceğimizi sağlamış oluyoruz.

 

 

UnicodeEncoding UE = new UnicodeEncoding();

 

Bu değişkenimiz dosyamızı şifrelerken hangi Encodinge göre şifreleyeceğimizi belirtmemizde işimize yarayacaktır.

 

 


FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);

RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,

                    RMCrypto.CreateEncryptor(key, key),   CryptoStreamMode.Write);

FileStream fsIn = new FileStream(encyol, FileMode.Open);

 

 

Bu kodlama yapısında yeni bir dosya oluşturuyor ve dosyaları key ler aracılığıyla şifreliyoruz.Gördüğünüz gibi “AES” .NET in Cryptography aduzayının bir parçası olmuştur.

 

 

 

 

Şimdi de Şifreyi Kaldırmayla ilgili fonksiyonumuzu yazalım...

 

 

 

private void DecryptFile(string decyol)

 {

   int position = 0, t = 0;

   while (decyol.IndexOf('\\', t) != -1)

    {

     position = decyol.IndexOf('\\', t);

     t = position;

    }

   string outfile = decyol.Substring(0, decyol.Length - 4);

   outfile = outfile.Substring(position);

   dosyade.Text = outfile.Replace('_', '.');

 

   try

    {

     if (password.Length > 8)

         password = password.Substring(0, 8);

     else if (password.Length < 8)

      {

       int add = 8 - password.Length;

       for (int i = 0; i < add; i++)

       password = password + i;

      }

 

    UnicodeEncoding UE = new UnicodeEncoding();

    byte[] key = UE.GetBytes(password);

    FileStream fsCrypt = new FileStream(decyol, FileMode.Open);

    RijndaelManaged RMCrypto = new RijndaelManaged();

    CryptoStream cs = new CryptoStream(fsCrypt,

    RMCrypto.CreateDecryptor(key, key),

    CryptoStreamMode.Read);

 

    FileStream fsOut = new FileStream(dosyade.Text, FileMode.Create);

 

    int data;

    while ((data = cs.ReadByte()) != -1)

            fsOut.WriteByte((byte)data);

 

    fsOut.Close();

    cs.Close();               

    fsCrypt.Close();

    MessageBox.Show("Şifreleme Kaldırılmıştır!", "Tamamdır");

    File.Delete(decyol);

   }

catch

   {

    MessageBox.Show("Bir hata alınmıştır.Özür dileriz:", "Hata");

   }           
} 

 

 

 

Bu kısımı tekrar anlatmama gerek var mı bilmiyorum ama EncryptFile fonksiyonumuzun “somut” olarak tam tersi işlemi yapmaktadır.

 

Gelin şimdi sizler ile Assetlerimizi şifreleyelim...

 

 

encryptToolStripMenuItem_Click fonksiyonumuzu aşağıda gördüğünüz üzere güncelleyiniz...

 

protected void encryptToolStripMenuItem_Click(Object sender, EventArgs e)

 {

   EncryptFile("Dokular/Armor.dds");

   EncryptFile("Efektler/Post_glow.cgfx");

   EncryptFile("Efektler/Post_glow.fx");

   EncryptFile("Modeller/ev.fbx");

   EncryptFile("Modeller/fish.x");           

   EncryptFile("Scriptler/Bayrak.lua");

   EncryptFile("Sesler/Bruises.mp3");

   EncryptFile("Videolar/Ornek.wmv");

 }

 


Bu şekliyle çalıştırdığımız zaman Projemizde kullandığımız tüm Assetlerimizin dosya isimlerinin ve de tiplerinin değiştiğini göreceksinizdir.Yani Şifreleme işlemimiz başarıyla gerçekleştirilmiştir.Artık Assetlerinizi kullanamazlar
:)

 

 

 

 

Bu işlemin tam tersi yani Şifreleri kaldırmak için ne yapabilirsiniz?

Onun kodunu da aşağıdaki decryptToolStripMenuItem_Click fonksiyonumuzda gördüğünüz üzere güncellemeniz gerekmektedir...

 

 

protected void decryptToolStripMenuItem_Click(object sender, EventArgs e)

 {

   DecryptFile("Dokular/Armor_dds.ibo");

   DecryptFile("Efektler/Post_glow_cgfx.ibo");

   DecryptFile("Efektler/Post_glow_fx.ibo");

   DecryptFile("Modeller/ev_fbx.ibo");

   DecryptFile("Modeller/fish_x.ibo");

   DecryptFile("Scriptler/Bayrak_lua.ibo");

   DecryptFile("Sesler/Bruises_mp3.ibo");

   DecryptFile("Videolar/Ornek_wmv.ibo");

 }

 

 

Bu kod ile de Şifrelediğiniz Assetlerinizi eski haline getirdiniz.Ve uygulamanızın herhangi bir noktasından çağrıda bulunabilirsiniz.


Bu tarz projelerde Assetlerinizin güvenliği için 1 kere EncryptFile ı çalıştırmanız ardından, Initialize() veya LoadContent() fonksiyonunuzda Decryption yapmanız ve oyunu kullanıcı kapatınca UnLoadContent() fonksiyonunda EncryptFile() fonksiyonunu tekrardan çağırmanız gerekecektir.Böylelikle sadece Uygulama açıldığında Assetlerinize erişim sağlanacaktır,bu durum projenizin güvenliği açısından çok önemlidir.Milyon Dolarlık oyun projelerinin Assetlerine erişilebildiğini düşünsenize...Birbirine benzeyen modellerde ve dokularda oyunlar piyasaya sürülür ve oyunların sanatsal seviyesi yerlerde sürünür.Oyun Sektörü resmen birbirinin kopyası “Çin Ürünleri” halini alırdı.Bu yüzden Assetlerinizi şifrelemelisiniz.Herkes sizin kadar iyi niyetli olmayabiliyor.Önceden önlemlerinizi almanızda fayda vardır kanaatindeyim...

DRM(Digital Rights Management) durumu söz konusu olduğundan ötürü projede kullandığım Assetlerimi sizler ile paylaşamıyorum.Bunun için özür dilerim.Ama kendi Assetlerinizi oluşturabilir ve klasörünü oluşturduğumuz yerlere yerleştirebilirsiniz.Umarım bu makalem işinizi kolaylaştıracaktır.

 

 

 

Bir sonraki makalemde “XNA Community”sine çok yararı dokunacağına inandığım Orjinal bir makale yazacağım.

 


Beni takip etmenizi öneriyorum sadece ;)

 

 

Merhaba,

Evet aslında bu pek XNA'in alanına girmiyor gibi gözükebilir sizlere.

Ama oyun projelerinizi release ettiğiniz zaman ses dosyalarını da paketleyip sunmak yerine,bir hostunuzda saklayabilir,ve uygulamanızdan o ses dosyalarını çağırabilirsiniz.Aslında internet üzerinden bu ses dosyalarınızı okumak gayet mantıklıdır.Bunu bize XNA kendisi sunmamaktadır ama DirectX in AudioVideoPlayback aduzayı sağolsun bu işi oldukça basitleştiriyor.

 

Projenizde yapmanız gereken;

* DirectX ve AudioVideoPlayBack'inizi referanslarınıza eklemeniz

* Projenizin namespace tanımlama alanına:

using Microsoft.DirectX.AudioVideoPlayback;

yazmanız

* Uygulamanızın herhangi bir kısmında:

Audio.FromUrl(new Uri("http://www.mp3sale.ru/_mp3_prev/2486703/My_Happy_Ending.mp3"), true);

tarzında bir kodlama kullanmanız kafi olacaktır.

 

İşe yarar bir ipucu yazayım istedim.
Umarım faydasını görürsünüz.

 


Etiketler : AudioVideoPlayback DirectX XNA
Kategoriler : Microsoft XNA
Yorumlar : 0 Yorum Yorum Yaz

Merhabalar,

Bu makalemde sizlere “XNA GS” unun ContentManager vasıtasıyla zaten yaptığı “Asset” (yani Oyun içi nesnelerimizi) Şifrelemeyi en basit şekliyle nasıl yapabileceğimizden söz edeceğim.XNA deki gibi kompleks bir yapı geliştirmeyeceğiz.Daha anlaşılır,geliştirilebilir ve standart bir yapı ortaya koyacağız.

Yapacağımız uygulama aslında 2 adet olacaktır.1) “Find&Replace Text Algoritması” 2) Rijndael algoritmasıdır.Yaklaşık olarak 3 sene önce Managed DirectX ile uğraşırken(MDX in son zamanlarında) Modelleri(.X dosyaları),Scriptlerimi,Dokularımı,Ses Dosyalarımı,Shader Efektlerimi şifreleyerek nasıl başkaları tarafından kullanılmasını engelleyebileceğimi tartışırken, başından sonuna kadar planladığım ve büyük bir zevk ile yazdığım iki algoritmaydı.Ancak XNA de bu yazacağımız algoritmamız geçerli olmayacaktır.Sebebi,XNA in Kendi “Content Importer” ları aracılığıyla zaten XNB uzantısında dosyaları oluşturmasıdır.Ancak XNA MVPlerinden öğrendiğim kadarıyla XNB aslında %100 “Encrypted” (yani Şifrelenmiş) bir dosya tipi değil.en azından %100 değil J

Her neyse konumuza dönecek olursak; Meraklı gözlerden çok büyük zaman harcayarak geliştirdiğiniz uygulamalarınızı-oyunlarınızı korumak isterseniz,bu yazımda sizlere adım adım anlatacağımdan emin olabilirsiniz.XNA’de Content Importer’ı bulunmayan bazı “Asset” tipleri vardır.Mesela Müzik dosya tiplerinden MP3 ü şifreleyebilirsiniz.XACT ile de yapabilirsiniz müzik dosyası işlemlerinizi ama büyük bir ihtimalle MP3 “Yasal” olmadığından ötürü desteklenmiyor – DRM(Digital Rights Management) Olayı.”MP3” leri “WAV” e çevirip XACT’e aktarmak yerine kendi Müzik Sistemimizi yazacağız ve Müzik dosyamızı da şifreleyeceğiz.Videolarınızı da  aynı şekilde şifreleyebilirsiniz.Lakin 3.1 ile birlikte Video dosyalarının da Content Importer desteği geldi.Dolayısıyla sizlere uzun zaman önce(XNA 1.0 zamanlarında) yapmış olduğum Video Sistemimi anlatacak ve hepberaber adım adım yazacağız.Uzun lafın kısası “XNB”ye çevrilmeyen Assetleri nasıl şifreleyeceğinizi ve kullanacağınızı göstereceğim J 

Şifreleyeceğimiz Dosya Tipleri

.FX(Efekt dosyaları) - Rijndael algoritması
.DDS(Doku Dosyası) - Rijndael algoritması
.X(DirectX Model) – Find&Replace veya Rijndael algoritması
.FBX(Autodesk Model) - Rijndael algoritması
.MP3(Müzik Dosyası) - Rijndael algoritması
.WMV(Video Dosyası) - Rijndael algoritması
.LUA(Lua Scripti) - Rijndael algoritması

O halde başlayalım...

 

Öncelikli olarak “Find&Replace Algoritma”mızı kullanabileceğimiz çıktısı okunabilir olan dosya tiplerinden “.X” yani bir zamanlar DirectX’in resmi çıktı formatıyla ilgili işlemler yapacağız.Makalenin 2.bölümünde ise “Rijndael Algoritması”nı anlatarak Dosyaların gerçekte nasıl şifrelendiği ile ilgili birkaç örnek uygulama ile konuyu anlatacağım.

 

Öncelikli olarak bir 3D Tasarım uygulamasını açarak .X çıktısı alacağız:

Adım-1: 3DS MAX in .X Exporterını indirmek(varsa 3.adıma geçiniz)



http://www.andytather.co.uk/Panda/directxmax_downloads.aspx

Adresine gidip uygun Exporter ı indireceğiz.


Adım-2: “Exporter”ın 3DS Max’de kullanılabilmesi için pluginlerin bulunduğu alana kopyalanması

indirdiğiniz arşivin içinden çıkan “PandaDirectXMaxExporter_x86.dle” dosyasını “C:\Program Files\Autodesk\3ds Max {versiyon}\stdplugs” dizinine kopyalayınız.Bu işlemi yapınca 3DS Max sizin indirdiğiniz bu exporter ı otomatikman tanıyacaktır.

Adım-3: Model’in Export edilmesi

Menü den Export->Export a gelerek SaveFileDialog un açılmasını bekliyoruz.



Panda DirectX i seçiyor ve Filename den herhangi bir isim veriyoruz.

Save e bastığımızda bir pencere daha açılacak.



Bu kısımda çıktı alacağımız .X dosyasına ait bilgileri görmektesiniz.OK e basıp .X dosyamızı oluşturuyoruz...

 

Buraya kadar ilgili .X dosyamızın çıktısını almayı gösterdim.Eminim bir çoğunuz zaten bu işlemleri gözünüz kapalı yapıyorsunuzdur ama bilmeyenler için de bilgilendirici oldu.

 

İlgili .X dosyamızı Notepad tarzı Text editörler ile açtığımızda ne kadar rahat okunabildiğini göreceksinizdir.


xof 0303txt 0032
template ColorRGBA {
 <35ff44e0-6c7c-11cf-8f52-0040333594a3>
 FLOAT red;
 FLOAT green;
 FLOAT blue;
 FLOAT alpha;
}

şeklinde bir yapısı vardır.Diğer Model Tiplerine oranla okunabilirliği en kolaydır ve Dolayısıyla da Find&Replace Algoritmasının sorunsuz çalışacağı belki de TEK model tipidir.

Şimdi de sırada XNA tarafında uygulamamızı hazırlamada...

 

Adım-1: Uygulamamızı oluşturuyoruz



Adım-2
:  System.Windows.Forms”  a referansda bulunup projemize dahil ediyoruz

using System.Windows.Forms;


Adım-3: Kontrol Sisteminin Kurulması

Değişken tanımlamaları yapıyoruz:

MenuStrip menuStrip1 = new MenuStrip();

ToolStripMenuItem encodeStripMenuItem = new ToolStripMenuItem();

ToolStripMenuItem encodeopenStripMenuItem = new ToolStripMenuItem();

ToolStripMenuItem decodeStripMenuItem = new ToolStripMenuItem();

ToolStripMenuItem decodeopenStripMenuItem = new ToolStripMenuItem();

Ve ardından Initialize() fonksiyonuna Kontroller ile ilgili bilgileri giriyoruz...

 

menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {

            encodeStripMenuItem,decodeStripMenuItem});

            menuStrip1.Location = new System.Drawing.Point(0, 0);

            menuStrip1.Name = "menuStrip1";

            menuStrip1.Size = new System.Drawing.Size(877, 24);

            menuStrip1.TabIndex = 0;

            menuStrip1.Text = "menuStrip1";

            menuStrip1.BackColor = System.Drawing.Color.CornflowerBlue;

 

            //

            // Encode

            //

            fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {

            encodeopenStripMenuItem});

            encodeStripMenuItem.Name = "encodeStripMenuItem";

            encodeStripMenuItem.Size = new System.Drawing.Size(37, 20);

            encodeStripMenuItem.Text = "Encoding";

 

            //

            // Encode Open

            //

            encodeopenStripMenuItem.Name = "encodeopenStripMenuItem";

            encodeopenStripMenuItem.Size = new System.Drawing.Size(152, 22);

            encodeopenStripMenuItem.Text = "Encode";

            encodeopenStripMenuItem.Click += new EventHandler(encodeopenStripMenuItem_Click);

 

 

            //

            // Decode

            //

            decodeStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {

            decodeopenStripMenuItem});

            decodeStripMenuItem.Name = "Contenta";

            decodeStripMenuItem.Size = new System.Drawing.Size(37, 20);

            decodeStripMenuItem.Text = "Decoding";

 

            //

            // Decode Open

            //

            decodeopenStripMenuItem.Name = "Contentbildir";

            decodeopenStripMenuItem.Size = new System.Drawing.Size(152, 22);

            decodeopenStripMenuItem.Text = "Decode";
decodeopenStripMenuItem.Click += new EventHandler(decodeopenStripMenuItem_Click);

 Control.FromHandle(Window.Handle).Controls.Add(menuStrip1);

 

Adım-4: Bir .X dosyası eklemek(Dokularıyla beraber)





gördüğünüz üzere projeye sağ tul-Add Existing Items diyerek “fish.X ve dokuları “AMBALE.bmp” ile “AMBBODY.bmp” dosyalarını eklemiş bulunmaktayız.

 


Adım-5: Find&Replace Algoritması

 

Kısaca bu algoritma ne iş yapar ondan bahsetmek istiyorum.Find&Replace Algoritması;Bir Dosya veya String üzerinde arama yapar ve 2 adet referans almaktadır: “eskideğer”-“yenideğer”.

Bu yazacağımız algoritmada tek bir kurala bağlı kalınmamaktadır:1 tane değeri bul ve yerine koy olmayacak!

Bunun yerine 2 adet dizi oluşturacak,birisinde encode değerleri,diğerinde de decode değerleri bulunacaktır.Algoritmamızda encode çağrıldığı zaman decode olan listeler yerini encode listesine bırakacak,decode çağrıldığında ise yerini decode listesine bırakacaktır.Böylelikle Find&Replace Algoritması başarıya ulaşacaktır.

O halde Classımızı yazmaya başlıyoruz.



Adım-6: Find&Replace Algoritması Yazmak

Yeni bir Sınıf oluşturun ve adını islem.cs veriniz.Ardından;


using System.IO;

namespace’ini classınıza dahil ediniz

 
İki adet string tabanlı dizi tanımlayınız:

string[] liste = new string[8];
string[] sifre = new string[8];

 

Gibi.

 

Bir fonksiyon oluşturun ve parametre olarak “encode”-“decode” değer alacaklarından ötürü “değer” isimli bir string değişken ve ilgili .x dosyası üzerinde işlem yapabilmek için yol bilgisini tutacak “dosya” adında bir string değişken oluşturunuz.



public void cevir(string deger,string dosya)

{

}

Evet böylelikle cevirme işini(encode-decode) yapacak fonksiyonumuzu yazmış bulunmaktayız.

 

Şimdi de içini dolduralım:

 

int a = 0;

“a” adında bir int değişken oluşturunuz.bu değişken liste iterasyonunda işinize yarayacaktır.


ardından;

string dosya_eski, dosya_yeni;

adlı iki adet string değişken hazırlayın.Bu değişkenler ilgili dosyaların içeriklerini text olarak saklayacaklardır.

 


TextReader tr = new StreamReader(dosya);

dosya_eski = tr.ReadToEnd();

tr.Close();

evet bir Textreader nesnesi oluşturarak dosya yı okuma modunda açıyor ve “dosya_eski” adlı değişkenimizde tüm dosyanın text bilgilerini saklıyoruz.ve ardından bu nesnemizi kapatıyoruz.

 

liste[0] = "template";

liste[1] = "ColorRGBA";

liste[2] = "Material";

liste[3] = "TextureFilename";

liste[4] = "Frame";

liste[5] = "Matrix4x4";

liste[6] = "Vector";

liste[7] = "MeshFace";

 

sifre[0]  = "qwe";

sifre[1]  = "ewq";

sifre[2]  = "rty";

sifre[3]  = "ytr";

sifre[4]  = "uop";

sifre[5] = "pou";

sifre[6] = "bnm";

sifre[7] = "mnb";

 

“liste” deki veriler hakiki .X Dosyasındaki değerler olmasına karşılık,”sifre” kısımındakiler birer aldatmacadır.Ve .X dosyamızı meraklı gözlerden uzak tutmamıza yarayacaktır.Liste uzunluğunu istediğiniz bir rakama getirebilir ve istediğiniz kadar eleman girebilirsiniz bu tamamen sizin insiyatifinize kalmış bişeydir.Ben bu noktada az veri olsun diye 8 elemanlı bir dizi oluşturdum.

 

do

 {

  dosya_yeni = dosya_eski;

  if (deger == "encode")

     {

      dosya_eski = dosya_yeni.Replace(liste[a], sifre[a]);

     }

  else if (deger == "decode")

     {

      dosya_eski = dosya_yeni.Replace(sifre[a], liste[a]);

     }              

      a++;

 }

while (a <= 7);

 

Bu döngümüz liste elemanlarımızı sonuna kadar okuyor ve eğer “deger” parametresine sahip değişkenimize “encode” atandıysa bu demek oluyor ki “Şifrele!”,işte o zaman .X üzerinde “Encode” işlemi yapacak “dosya_eski” değişkenimiz encode değerlerini bünyesine katılıyor.Eğer decode olursa da bu işlemin tam tersi yapılıyor ve dosyamız normal bir .X dosyası şekline getiriliyor.

TextWriter tw = new StreamWriter(dosya);

tw.WriteLine(dosya_eski);

tw.Close();

 

son olarakta ilgili değişiklikleri güncellemesi için bir TextWriter nesnesi oluşturup bunu “dosya” değişkeni vasıtasıyla hallediyoruz.son olarakta bu nesnemizi kapatıyoruz...

 

Adım-7: Geri kalan kodlamaları yapmak

 

Geriye birkaç küçük işlem kalmaktadır:

Encode-Decode menülerinin Click eventlerini yazmak,değişken tanımlamaları ve encode-decode işlemleri.

 

Öncelikle bu classımıza ait yeni bir instance oluşturuyoruz:

islem yeni_islem = new islem();

Ardından Encode-Decode menülerinin Click eventlerini yazıyoruz...

 

protected void encodeopenStripMenuItem_Click(Object sender, EventArgs e)

 {

    yeni_islem.cevir("encode", "fish.x");           

 }

protected void decodeopenStripMenuItem_Click(object sender, EventArgs e)

 {

     yeni_islem.cevir("decode", "fish.x");

 }


Adım-8: Uygulamayı çalıştırıyor ve sonucu görüyoruz

 

 

“Encoding” menüsüne geliyor ve “Encode” ye basıyoruz.Ardından da exe nin bulunduğu yere gidip .X dosyamıza bir text editör de göz atıyoruz...

 


Decode/Normal hali:

xof 0303txt 0032

template ColorRGBA {

 <35ff44e0-6c7c-11cf-8f52-0040333594a3>

 FLOAT red;

 FLOAT green;

 FLOAT blue;

 FLOAT alpha;

}

 

template ColorRGB {

 <d3e16e81-7835-11cf-8f52-0040333594a3>

 FLOAT red;

 FLOAT green;

 FLOAT blue;

}

....

 

Encode/Şifrelenmiş hali:

xof 0303txt 0032

qwe ewq {

 <35ff44e0-6c7c-11cf-8f52-0040333594a3>

 FLOAT red;

 FLOAT green;

 FLOAT blue;

 FLOAT alpha;

}

 

qwe ColorRGB {

 <d3e16e81-7835-11cf-8f52-0040333594a3>

 FLOAT red;

 FLOAT green;

 FLOAT blue;

}

 

....

 

 

Bir Find&Replace Algoritmasını XNA de başarıyla uygulamış olduk.Bu makale serisinin 1.bölümünde yapacaklarımız bu kadar.

 

Diğer makalelerimizde görüşmek üzere...

 

 

Uygulama Kaynak Kod

 

 

Join the XNA Community @ FaceBook:

http://www.facebook.com/pages/XNA/35495648683
Etiketler : XNA Facebook
Kategoriler : Microsoft XNA
Yorumlar : 0 Yorum Yorum Yaz




I have written an article about Building a Simple GUI Editor in XNA.Maybe you'd like to have a look at it...

 

http://www.c-sharpcorner.com/UploadFile/iersoy/395/Default.aspx

 

Etiketler : XNA GUI GUI Editör CSharpCorner
Kategoriler : Microsoft XNA
Yorumlar : 0 Yorum Yorum Yaz
HTML clipboard

Makale serisinin 4.bölümüne hoşgeldiniz. 

Şimdi de işin en heyecanlı kısmına gelelim: Game1.cs

Bu işlemleri Adım Adım anlatmaya özen göstereceğim... 

 

GAME1.CS

İlk iş olarak System.Windows.Forms’u projemize dahil ediyoruz.

using System.Windows.Forms;


Özellikler ve ToolBox ın instance larını oluşturuyoruz:

Ozellikler ozel = new Ozellikler();

Toolbox tool = new Toolbox();

 

Game1 yapıcı fonksiyonumuzda:


graphics.PreferredBackBufferWidth = 600;

graphics.PreferredBackBufferHeight = 600;

şeklinde bir değer atama yapıyoruz.Burada Game1 nesnemize ait Width ve Height değerlerini verdik.

Yine aynı bölümde,

Window.Title = "Basit GUI Editör";

this.IsMouseVisible = true;


şeklinde kodlamaları da ekliyoruz.1.kod Pencereye “Basit GUI Editör” yazarken diğeri Mouse un her halükarda görüntülenmesi gerektiğini belirtiyor.Bu tarz uygulamalarda Mouse İmleci sürekli görüntülenmelidir,öyle değil mi?

Yine aynı kısımda,

Control.FromHandle(Window.Handle).Location = new System.Drawing.Point(337, 86);

ozel.Show();

ozel.DesktopLocation = new System.Drawing.Point(949, 109);

tool.Show();

tool.DesktopLocation = new System.Drawing.Point(141, 109);

form nesnelerimizin pencere ilk açıldığından masaüstünde nerelerde duracaklarını belirtiyor.Aynı zamanda ilgili GameWindow nesnemizinde nerede açılacağına ilişkin X ve Y koordinatlarını veriyoruz.Bu değerler hesaplanarak verilmiştir.


Sonraki işlemlerimiz değişken tanımlamaları olacaktır.

 

Timer zaman = new Timer();

int eskideger;

Infos bilgiler = new Infos();

 

Zaman isimli bir Timer kontrolü oluşturuyoruz.Kontrolleri yüklerken ve Drag işlemi yaparken çok işimize yarayacak.
Bilgiler adında bir Infos classının instance ını oluşturuyoruz.

Game1() Yapıcı fonksiyonumuzda;

zaman.Enabled = true;

zaman adlı timer nesnemizi enabled yaparak başlatıyoruz.

Initialize() fonksiyonumuzda;


//Timer Nesnesi

zaman.Interval = 1;

zaman.Tick += new EventHandler(zaman_Tick);

diyerek Timer nesnemizin Tick olayını oluşturuyoruz ve Interval yani döngü süresini 1 olarak veriyoruz.

Zaman_Tick eventine aşağıdaki gibi bir kod yazıyoruz.

private void zaman_Tick(object sender, EventArgs e)

        {

            //XBUTTON Ekleme

            if (Infos.degerpub == true)

            {

                if (Infos.kapat == true)

                {

                }

                else if (Infos.kapat == false)

                {

                    XButton btn = new XButton();

                    btn.Name = "button" + Infos.a;

                    btn.Text = "button" + Infos.a;

                    btn.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(btn);

                    Infos.strunq.Add(btn);

                    Infos.kapat = true;

                }

            }

            //XCHECKBOX Ekleme

            if (Infos.c_degerpub == true)

            {

                if (Infos.c_kapat == true)

                {

                }

                else

                {

                    XCheckBox chk = new XCheckBox();

                    chk.Name = "checkbox" + Infos.c;

                    chk.Text = "checkbox" + Infos.c;

                    chk.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(chk);

                    Infos.strunq.Add(chk);

                    Infos.c_kapat = true;

                }

            }

            //XCOMBOBOX Ekleme

            if (Infos.co_degerpub == true)

            {

                if (Infos.co_kapat == true)

                {

                }

                else

                {

                    XComboBox cbo = new XComboBox();

                    cbo.Name = "ComboBox" + Infos.co;

                    cbo.Text = "ComboBox" + Infos.co;

                    cbo.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(cbo);

                    Infos.strunq.Add(cbo);

                    Infos.co_kapat = true;

                }

            }

            //XLABEL Ekleme

            if (Infos.l_degerpub == true)

            {

                if (Infos.l_kapat == true)

                {

                }

                else

                {

                    XLabel lbl = new XLabel();

                    lbl.Name = "Label" + Infos.l;

                    lbl.Text = "Label" + Infos.l;

                    lbl.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(lbl);

                    Infos.strunq.Add(lbl);

                    Infos.l_kapat = true;

                }

            }

            //XListBox Ekleme

            if (Infos.lbx_degerpub == true)

            {

                if (Infos.lbx_kapat == true)

                {

                }

                else

                {

                    XListBox list1 = new XListBox();

                    list1.Name = "Listbox" + Infos.lbx;

                    list1.Text = "Listbox" + Infos.lbx;

                    list1.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(list1);

                    Infos.strunq.Add(list1);

                    Infos.lbx_kapat = true;

                }

            }

            //XPictureBox Ekleme

            if (Infos.pic_degerpub == true)

            {

                if (Infos.pic_kapat == true)

                {

                }

                else

                {

                    XPictureBox picx = new XPictureBox();

                    picx.Name = "Picturebox" + Infos.pic;

                    picx.Text = "Picturebox" + Infos.pic;

                    picx.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(picx);

                    Infos.strunq.Add(picx);

                    Infos.pic_kapat = true;

                }

            }

            //XProgressBar Ekleme

            if (Infos.pro_degerpub == true)

            {

                if (Infos.pro_kapat == true)

                {

                }

                else

                {

                    XProgressBar prox = new XProgressBar();

                    prox.Name = "ProgressBar" + Infos.pro;

                    prox.Text = "ProgressBar" + Infos.pro;

                    prox.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(prox);

                    Infos.strunq.Add(prox);

                    Infos.pro_kapat = true;

                }

            }

            //XRadioButton Ekleme

            if (Infos.rad_degerpub == true)

            {

                if (Infos.rad_kapat == true)

                {

                }

                else

                {

                    XRadioButton radio = new XRadioButton();

                    radio.Name = "RadioButton" + Infos.rad;

                    radio.Text = "RadioButton" + Infos.rad;

                    radio.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(radio);

                    Infos.strunq.Add(radio);

                    Infos.rad_kapat = true;

                }

            }

            //XTextbox Ekleme

            if (Infos.txt_degerpub == true)

            {

                if (Infos.txt_kapat == true)

                {

                }

                else

                {

                    XTextBox txt1 = new XTextBox();

                    txt1.Name = "Textbox" + Infos.txt;

                    txt1.Text = "Textbox" + Infos.txt;

                    txt1.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(txt1);

                    Infos.strunq.Add(txt1);

                    Infos.txt_kapat = true;

                }

            }

            foreach (Control v in Control.FromHandle(Window.Handle).Controls)

            {

                Infos.kontroller.Add(v);

                if (v.Focused)

                {

                    Infos.secilikontrol = v;

                    Infos.kontrool = v;

                }

            }

            if (Infos.xmlolustur == true)

            {

               Infos.XMLOlustur();

               Infos.xmlolustur = false;

            }

            else

            {

            }

        } 

Textbox yüklemesi bitene kadar olan kısım ilgili kontrolleri yüklemeyle alakalı kısımlardır.Üzerinde biraz duralım:

Örnek olarak TextBox yüklemeyi konuşalım:

if (Infos.txt_degerpub == true)

            {

                if (Infos.txt_kapat == true)

                {

                }

                else

                {

                    XTextBox txt1 = new XTextBox();

                    txt1.Name = "Textbox" + Infos.txt;

                    txt1.Text = "Textbox" + Infos.txt;

                    txt1.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(txt1);

                    Infos.strunq.Add(txt1);

                    Infos.txt_kapat = true;

                }

            }

Infos daki TextBox_Yuklendi olayının sonucu eğer doğruysa ve timer nesnesini bu esnada txt_kapat ile durdurmuyorsak Textbox nesnemizi klasik yöntem ile oluşturuyor,GameWindow a ekliyor,bunun yanısıra Benzersiz Kontrol Listesi değişkenimiz strunq e ekliyoruz.Ardından da bu işlemi bir kere yapmasını istediğimiz için txt_kapat diyoruz.Aksi takdirde,strunq listemize aynı kontrollerden defalarca kere eklendiğini görecektik ve belki de Benzersiz sonuç alamayacaktık.

TextBox yüklemesi bittikten sonraki kısım hakkında biraz konuşalım:

foreach (Control v in Control.FromHandle(Window.Handle).Controls)

    {

         Infos.kontroller.Add(v);

         if (v.Focused)

            {

              Infos.secilikontrol = v;

              Infos.kontrool = v;

            }

    }

if (Infos.xmlolustur == true)

    {

          Infos.XMLOlustur();

          Infos.xmlolustur = false;

    }

 
else

    {

    }

Öncelikle o anda GameWindow üzerinde bulunan tüm kontrolleri sorguluyor,bunları tekrar eden kontrol listemiz “kontroller” a aktarıyor,ve eğer ilgili kontrol seçiliyse bunu secilikontrol ve kontrool e aktarıp Özellikler Formunun ihtiyacını karşılamış oluyoruz.

Ardından,eğer Özellikler formunda “Kaydet” tuşuna basıldıysa,XMLOlustur() adlı fonksiyonumuzu çalıştırıyor ve tekrardan buna false değer atıyoruz.

C# bir case-sensitive yani Harf Duyarlı Dil olduğundan ötürü XMLOlustur() fonksiyonu ile xmlolustur bool değişkenini karıştırmamanız önemle rica olunur.

Bu işlemlerin dışında Game1() Yapıcı fonksiyonumuza gelip:


Control.FromHandle(Window.Handle).Move += new EventHandler(XNAWindowsTasima);

Gibi bir olay tanımlayalım.Bu olayın yaptığı işlem GameWindow un taşınmasını engellemektir.Bunun sebebi ise diğer 2 formumuz ile Tasarımsal açıdan uyumsuzluk yaşanmasını engellemektir.

public void XNAWindowsTasima(object sender, EventArgs e)

  {

Control.FromHandle(Window.Handle).Location = new System.Drawing.Point(337, 86);

  }

Şeklinde Game1.cs in herhangi bir yerinde bu fonksiyonu yerleştirdiğimizde artık GameWindow hiçbir şekilde taşınamayacaktır J

Game1.cs in tüm kodları:

using System;

using System.Collections.Generic;

using System.Linq;

using Microsoft.Xna.Framework;

using Microsoft.Xna.Framework.Audio;

using Microsoft.Xna.Framework.Content;

using Microsoft.Xna.Framework.GamerServices;

using Microsoft.Xna.Framework.Graphics;

using Microsoft.Xna.Framework.Input;

using Microsoft.Xna.Framework.Media;

using Microsoft.Xna.Framework.Net;

using Microsoft.Xna.Framework.Storage;

using System.Windows.Forms;

namespace GUIEditor

{   

    public class Game1 : Microsoft.Xna.Framework.Game

    {

        GraphicsDeviceManager graphics;

        SpriteBatch spriteBatch;

        Ozellikler ozel = new Ozellikler();

        Toolbox tool = new Toolbox();

        Timer zaman = new Timer();

        int eskideger;

        Infos bilgiler = new Infos();

        public Game1()

        {

            graphics = new GraphicsDeviceManager(this);

            Content.RootDirectory = "Content";

            graphics.PreferredBackBufferWidth = 600;

            graphics.PreferredBackBufferHeight = 600;

            Control.FromHandle(Window.Handle).Move += new EventHandler(XNAWindowsTasima);

            Window.Title = "Basit GUI Editör";

            this.IsMouseVisible = true;

            zaman.Enabled = true;   

            Control.FromHandle(Window.Handle).Location = new System.Drawing.Point(337, 86);

            ozel.Show();

            ozel.DesktopLocation = new System.Drawing.Point(949, 109);

            tool.Show();

            tool.DesktopLocation = new System.Drawing.Point(141, 109);

        }

        public void XNAWindowsTasima(object sender, EventArgs e)

        {

            Control.FromHandle(Window.Handle).Location = new System.Drawing.Point(337, 86);

        }

        protected override void Initialize()

        {

              base.Initialize();

              //Timer Nesnesi

              zaman.Interval = 1;

              zaman.Tick += new EventHandler(zaman_Tick);                       

        }

        protected override void LoadContent()

        {         

            spriteBatch = new SpriteBatch(GraphicsDevice);

        }

        private void zaman_Tick(object sender, EventArgs e)

        {

            //XBUTTON Ekleme

            if (Infos.degerpub == true)

            {

                if (Infos.kapat == true)

                {

                }

                else if (Infos.kapat == false)

                {

                    XButton btn = new XButton();

                    btn.Name = "button" + Infos.a;

                    btn.Text = "button" + Infos.a;

                    btn.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(btn);

                    Infos.strunq.Add(btn);

                    Infos.kapat = true;

                }

            }

            //XCHECKBOX Ekleme

            if (Infos.c_degerpub == true)

            {

                if (Infos.c_kapat == true)

                {

                }

                else

                {

                    XCheckBox chk = new XCheckBox();

                    chk.Name = "checkbox" + Infos.c;

                    chk.Text = "checkbox" + Infos.c;

                    chk.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(chk);

                    Infos.strunq.Add(chk);

                    Infos.c_kapat = true;

                }

            }

            //XCOMBOBOX Ekleme

            if (Infos.co_degerpub == true)

            {

                if (Infos.co_kapat == true)

                {

                }

                else

                {

                    XComboBox cbo = new XComboBox();

                    cbo.Name = "ComboBox" + Infos.co;

                    cbo.Text = "ComboBox" + Infos.co;

                    cbo.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(cbo);

                    Infos.strunq.Add(cbo);

                    Infos.co_kapat = true;

                }

            }

            //XLABEL Ekleme

            if (Infos.l_degerpub == true)

            {

                if (Infos.l_kapat == true)

                {

                }

                else

                {

                    XLabel lbl = new XLabel();

                    lbl.Name = "Label" + Infos.l;

                    lbl.Text = "Label" + Infos.l;

                    lbl.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(lbl);

                    Infos.strunq.Add(lbl);

                    Infos.l_kapat = true;

                }

            }

            //XListBox Ekleme

            if (Infos.lbx_degerpub == true)

            {

                if (Infos.lbx_kapat == true)

                {

                }

                else

                {

                    XListBox list1 = new XListBox();

                    list1.Name = "Listbox" + Infos.lbx;

                    list1.Text = "Listbox" + Infos.lbx;

                    list1.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(list1);

                    Infos.strunq.Add(list1);

                    Infos.lbx_kapat = true;

                }

            }

            //XPictureBox Ekleme

            if (Infos.pic_degerpub == true)

            {

                if (Infos.pic_kapat == true)

                {

                }

                else

                {

                    XPictureBox picx = new XPictureBox();

                    picx.Name = "Picturebox" + Infos.pic;

                    picx.Text = "Picturebox" + Infos.pic;

                    picx.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(picx);

                    Infos.strunq.Add(picx);

                    Infos.pic_kapat = true;

                }

            }

            //XProgressBar Ekleme

            if (Infos.pro_degerpub == true)

            {

                if (Infos.pro_kapat == true)

                {

                }

                else

                {

                    XProgressBar prox = new XProgressBar();

                    prox.Name = "ProgressBar" + Infos.pro;

                    prox.Text = "ProgressBar" + Infos.pro;

                    prox.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(prox);

                    Infos.strunq.Add(prox);

                    Infos.pro_kapat = true;

                }

            }

            //XRadioButton Ekleme

            if (Infos.rad_degerpub == true)

            {

                if (Infos.rad_kapat == true)

                {

                }

                else

                {

                    XRadioButton radio = new XRadioButton();

                    radio.Name = "RadioButton" + Infos.rad;

                    radio.Text = "RadioButton" + Infos.rad;

                    radio.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(radio);

                    Infos.strunq.Add(radio);

                    Infos.rad_kapat = true;

                }

            }

            //XTextbox Ekleme

            if (Infos.txt_degerpub == true)

            {

                if (Infos.txt_kapat == true)

                {

                }

                else

                {

                    XTextBox txt1 = new XTextBox();

                    txt1.Name = "Textbox" + Infos.txt;

                    txt1.Text = "Textbox" + Infos.txt;

                    txt1.Location = new System.Drawing.Point(50, 50);

                    Control.FromHandle(Window.Handle).Controls.Add(txt1);

                    Infos.strunq.Add(txt1);

                    Infos.txt_kapat = true;

                }

            }

      foreach (Control v in Control.FromHandle(Window.Handle).Controls)

            {

                Infos.kontroller.Add(v);

                if (v.Focused)

                {

                    Infos.secilikontrol = v;

                    Infos.kontrool = v;

                }

            }

            if (Infos.xmlolustur == true)

            {

               Infos.XMLOlustur();

               Infos.xmlolustur = false;

            }

            else

            {

            }

        }

        protected override void UnloadContent()

        {

        }

        protected override void Update(GameTime gameTime)

        {          

            base.Update(gameTime);                    

        }

        protected override void Draw(GameTime gameTime)

        {

            GraphicsDevice.Clear(Color.CornflowerBlue);

            eskideger = Infos.co;           

            base.Draw(gameTime);

        }

    }

}

 

Uygulamayı Çalıştıralım ve Denemeler yapalım:

22.png

Açılış ekranı bu şekildedir.Tam da istediğimiz gibi J Görev Çubuğunda 1 adet Proje çalışmakta,2 form + GameWindow Hareket ettirilememekte ve boyutları değiştirilememektedir.

Kontroller ile oynayalım...

23.png

Gördüğünüz gibi Button Kontrolümüz seçili olduğundan ötürü sağ tarafta Özelliklerini hemen anında değiştirebiliyoruz.Gerçek zamanlı da sonucu görebiliyoruz.Değerleriyle oynayalım bakalım ne olacak:

24.png


ForeColor ve Text Değerlerini gördüğünüz üzere değiştirmiş bulunmaktayız...

Şimdi de bu GUI Editörümüzün XML Çıktısına bir bakalım.

Öncelikle birkaç kontrol ekleyelim...

25.png

Şimdi de Özellikler Formundan Kaydet e basarak bunun XML Çıktısını alalım(Bin->Debug içinde kontroller.xml dosyasına bakınız)

<?xml version="1.0" encoding="utf-8"?>

<GUI>

  <Kontrol Name="button1">

    <Tip>GUIEditor.XButton</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>ControlLightLight</ForeColor>

    <LocationX>39</LocationX>

    <LocationY>33</LocationY>

    <SizeW>75</SizeW>

    <SizeH>23</SizeH>

    <Text>Yeni Oyun</Text>

  </Kontrol>

  <Kontrol Name="button2">

    <Tip>GUIEditor.XButton</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>Cyan</ForeColor>

    <LocationX>39</LocationX>

    <LocationY>58</LocationY>

    <SizeW>75</SizeW>

    <SizeH>23</SizeH>

    <Text>Devam Et</Text>

  </Kontrol>

  <Kontrol Name="checkbox1">

    <Tip>GUIEditor.XCheckBox</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>ControlText</ForeColor>

    <LocationX>43</LocationX>

    <LocationY>94</LocationY>

    <SizeW>104</SizeW>

    <SizeH>24</SizeH>

    <Text>Onay 1</Text>

  </Kontrol>

  <Kontrol Name="checkbox2">

    <Tip>GUIEditor.XCheckBox</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>ControlText</ForeColor>

    <LocationX>43</LocationX>

    <LocationY>112</LocationY>

    <SizeW>104</SizeW>

    <SizeH>24</SizeH>

    <Text>Onay 2</Text>

  </Kontrol>

  <Kontrol Name="ComboBox1">

    <Tip>GUIEditor.XComboBox</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>WindowText</ForeColor>

    <LocationX>285</LocationX>

    <LocationY>26</LocationY>

    <SizeW>121</SizeW>

    <SizeH>21</SizeH>

    <Text>Örnek ComboBox 1</Text>

  </Kontrol>

  <Kontrol Name="ComboBox2">

    <Tip>GUIEditor.XComboBox</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>WindowText</ForeColor>

    <LocationX>284</LocationX>

    <LocationY>56</LocationY>

    <SizeW>121</SizeW>

    <SizeH>21</SizeH>

    <Text>Örnek ComboBox 2</Text>

  </Kontrol>

  <Kontrol Name="Label1">

    <Tip>GUIEditor.XLabel</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>ControlText</ForeColor>

    <LocationX>33</LocationX>

    <LocationY>203</LocationY>

    <SizeW>100</SizeW>

    <SizeH>23</SizeH>

    <Text>Örnek Label1</Text>

  </Kontrol>

  <Kontrol Name="Label2">

    <Tip>GUIEditor.XLabel</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>ControlText</ForeColor>

    <LocationX>32</LocationX>

    <LocationY>224</LocationY>

    <SizeW>100</SizeW>

    <SizeH>23</SizeH>

    <Text>Örnek Label2</Text>

  </Kontrol>

  <Kontrol Name="Listbox1">

    <Tip>GUIEditor.XListBox</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>WindowText</ForeColor>

    <LocationX>24</LocationX>

    <LocationY>275</LocationY>

    <SizeW>120</SizeW>

    <SizeH>95</SizeH>

    <Text>0</Text>

  </Kontrol>

  <Kontrol Name="Picturebox1">

    <Tip>GUIEditor.XPictureBox</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>ControlText</ForeColor>

    <LocationX>299</LocationX>

    <LocationY>445</LocationY>

    <SizeW>300</SizeW>

    <SizeH>150</SizeH>

    <Text>Picturebox1</Text>

  </Kontrol>

  <Kontrol Name="ProgressBar1">

    <Tip>GUIEditor.XProgressBar</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>Highlight</ForeColor>

    <LocationX>298</LocationX>

    <LocationY>402</LocationY>

    <SizeW>300</SizeW>

    <SizeH>35</SizeH>

    <Text>ProgressBar1</Text>

  </Kontrol>

  <Kontrol Name="RadioButton1">

    <Tip>GUIEditor.XRadioButton</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>ControlText</ForeColor>

    <LocationX>329</LocationX>

    <LocationY>181</LocationY>

    <SizeW>104</SizeW>

    <SizeH>24</SizeH>

    <Text>Seçim1</Text>

  </Kontrol>

  <Kontrol Name="RadioButton2">

    <Tip>GUIEditor.XRadioButton</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>ControlText</ForeColor>

    <LocationX>329</LocationX>

    <LocationY>202</LocationY>

    <SizeW>104</SizeW>

    <SizeH>24</SizeH>

    <Text>Seçim2</Text>

  </Kontrol>

  <Kontrol Name="RadioButton3">

    <Tip>GUIEditor.XRadioButton</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>ControlText</ForeColor>

    <LocationX>330</LocationX>

    <LocationY>223</LocationY>

    <SizeW>104</SizeW>

    <SizeH>24</SizeH>

    <Text>Seçim3</Text>

  </Kontrol>

  <Kontrol Name="Textbox1">

    <Tip>GUIEditor.XTextBox</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>WindowText</ForeColor>

    <LocationX>26</LocationX>

    <LocationY>456</LocationY>

    <SizeW>100</SizeW>

    <SizeH>20</SizeH>

    <Text>Örnek TextBox</Text>

  </Kontrol>

  <Kontrol Name="Textbox2">

    <Tip>GUIEditor.XTextBox</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>WindowText</ForeColor>

    <LocationX>26</LocationX>

    <LocationY>482</LocationY>

    <SizeW>100</SizeW>

    <SizeH>20</SizeH>

    <Text>Örnek TextBox2</Text>

  </Kontrol>

  <Kontrol Name="Textbox3">

    <Tip>GUIEditor.XTextBox</Tip>

    <AllowDrop>False</AllowDrop>

    <Enabled>True</Enabled>

    <ForeColor>WindowText</ForeColor>

    <LocationX>25</LocationX>

    <LocationY>509</LocationY>

    <SizeW>100</SizeW>

    <SizeH>20</SizeH>

    <Text>Örnek TextBox3</Text>

  </Kontrol>

</GUI>

Evet gördüğünüz üzere tüm kontrolleri daha önceden GUI.XML dosyamızda belirttiğimiz element ve attributelere göre kaydetmektedir.

Bu demek oluyor ki burada yapılan tasarımları bir XML dosyasını okuyarak XNA Oyununuzda kullanabilirsiniz.

Peki ama Olaylar?
XNA Oyununa nasıl yükleyeceğiz?
Screen’leri nasıl oluşturacağız?

Onları da gelecek makalem de anlatmaya çalışarak GUI Editör örnek uygulamamızı sonlandıracağız...




XNA’de “TOOL Programming” in nasıl yapıldığını bu vesileyle az da olsa size göstermiş oldum.Gönül isterdi ki 300-400 sayfalık makaleler yazayım.Ama herkesin bu işlere ayırabileceği vakitleri kısıtlı.Dolayısıyla diğer makalelerimi beklemenizi tavsiye edeceğim...

 

 

Etiketler : XNA Microsoft GUI Editör GUI
Kategoriler : Microsoft XNA
Yorumlar : 0 Yorum Yorum Yaz
HTML clipboard

Merhabalar,

Makale Serisinin 3.bölümünde sizlere Özellikle ve Toolbox formları ile ilgili işlemler anlatılmaktadır.

 

Şimdi de sıra da Özellikler formumuzun kodlarını anlatmakta.

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Runtime.InteropServices;

namespace GUIEditor

{

    public partial class Ozellikler : Form

    {

        private const int SC_CLOSE = 0xF060;

        private const int MF_GRAYED = 0x1;

        [DllImport("user32.dll")]

        private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

        [DllImport("user32.dll")]

        private static extern int EnableMenuItem(IntPtr hMenu, int wIDEnableItem, int wEnable);

        public Ozellikler()

        {

            InitializeComponent();

        }

        private void Ozellikler_Load(object sender, EventArgs e)

        {

            this.ShowInTaskbar = false;

            EnableMenuItem(GetSystemMenu(this.Handle, false), SC_CLOSE, MF_GRAYED);

        }

        private void Ozellikler_Resize(object sender, EventArgs e)

        {

            this.Size = new Size(219, 600);

        }

        private void Ozellikler_Move(object sender, EventArgs e)

        {

            this.DesktopLocation = new System.Drawing.Point(949, 109);

        }

        private void button1_Click(object sender, EventArgs e)

        {

            Infos.xmlolustur = true;

        }       

    }

}

Sırayla ne işlem yaptıklarından bahsedeyim...

private const int SC_CLOSE = 0xF060;

        private const int MF_GRAYED = 0x1;

        [DllImport("user32.dll")]

        private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

        [DllImport("user32.dll")]

        private static extern int EnableMenuItem(IntPtr hMenu, int wIDEnableItem, int wEnable);

Bu kodlar Windows API çağrılarıdır.Hem Özellikler formunda hem de Toolbox formunda kullanılmışlardır.

Kullanım amaçları ilgili form nesnesinin kapatma düğmesini Disable etmektir.

private void Ozellikler_Load(object sender, EventArgs e)

        {

            this.ShowInTaskbar = false;

            EnableMenuItem(GetSystemMenu(this.Handle, false), SC_CLOSE, MF_GRAYED);

        }

Uygulama ilk başlatıldığında Görev Çubuğunda görünmesini engellemekteyiz.Aksi takdirde GUI Editörü çalıştırdığımızda Özellikler,Toolbox ve Game pencerelerinin hepsi görülecektir.Görev Çubuğunda fazladan yer kaplamaması açısından bunu engellemekteyiz.

Ve son olarak da yukarıda bahsettiğim Windows API çağrısını çalıştırmaktayız.Böylece kapatma tuşunu engelliyoruz...

        private void Ozellikler_Resize(object sender, EventArgs e)

        {

            this.Size = new Size(219, 600);

        }

Bu işlemimiz Özellikler formununun boyutunu çalışma zamanında değiştirilmesini engellemektedir.

        private void Ozellikler_Move(object sender, EventArgs e)

        {

            this.DesktopLocation = new System.Drawing.Point(949, 109);

        }

Bu işlemimiz Özellikler formumuzun taşınmasını çalışma zamanında engellemektedir.

        private void button1_Click(object sender, EventArgs e)

        {

            Infos.xmlolustur = true;

        }  

Bu işlem Özellikler formumuzun üzerinde bulunan “Kaydet” isimli button un GameWindow üzerinde bulunan kontrolleri alıp XML olarak kaydetmesini sağlamaktadır.

Şimdi de ToolBox ımızı açıklayalım:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Runtime.InteropServices;

namespace GUIEditor

{

    public partial class Toolbox : Form

    {

        private const int SC_CLOSE = 0xF060;

        private const int MF_GRAYED = 0x1;

        [DllImport("user32.dll")]

        private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

        [DllImport("user32.dll")]

        private static extern int EnableMenuItem(IntPtr hMenu, int wIDEnableItem, int wEnable);

        public Toolbox()

        {

            InitializeComponent();

        }

        private void pictureBox1_MouseLeave(object sender, EventArgs e)

        {

            pictureBox1.BorderStyle = BorderStyle.None;

        }

        private void pictureBox1_MouseEnter(object sender, EventArgs e)

        {

            pictureBox1.BorderStyle = BorderStyle.FixedSingle;

        }

        private void pictureBox1_Click(object sender, EventArgs e)

        {

            Infos dun = new Infos();

            dun.Button_Eklendi(true);

            Infos.kapat = false;

            Infos.enazbir = true;

        }

        //PictureBox2 Olayları - Checkbox

        private void pictureBox2_MouseLeave(object sender, EventArgs e)

        {

            pictureBox2.BorderStyle = BorderStyle.None;

        }

        private void pictureBox2_MouseEnter(object sender, EventArgs e)

        {

            pictureBox2.BorderStyle = BorderStyle.FixedSingle;

        }

        private void pictureBox2_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.CheckBox_Eklendi(true);

            Infos.c_kapat = false;

            Infos.c_enazbir = true;

        }

        //PictureBox3 Olayları - ComboBox

        private void pictureBox3_MouseLeave(object sender, EventArgs e)

        {

            pictureBox3.BorderStyle = BorderStyle.None;

        }

        private void pictureBox3_MouseEnter(object sender, EventArgs e)

        {

            pictureBox3.BorderStyle = BorderStyle.FixedSingle;

        }

        private void pictureBox3_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.ComboBox_Eklendi(true);

            Infos.co_kapat = false;

            Infos.co_enazbir = true;

        }

        //PictureBox4 Olayları - Label

        private void pictureBox4_MouseLeave(object sender, EventArgs e)

        {

            pictureBox4.BorderStyle = BorderStyle.None;

        }

        private void pictureBox4_MouseEnter(object sender, EventArgs e)

        {

            pictureBox4.BorderStyle = BorderStyle.FixedSingle;

        }

        private void pictureBox4_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.Label_Eklendi(true);

            Infos.l_kapat = false;

            Infos.l_enazbir = true;

        }

        //PictureBox5 Olayları - ListBox

        private void pictureBox5_MouseLeave(object sender, EventArgs e)

        {

            pictureBox5.BorderStyle = BorderStyle.None;

        }

        private void pictureBox5_MouseEnter(object sender, EventArgs e)

        {

            pictureBox5.BorderStyle = BorderStyle.FixedSingle;

        }

        private void pictureBox5_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.ListBox_Eklendi(true);

            Infos.lbx_kapat = false;

            Infos.lbx_enazbir = true;

        }

        //PictureBox6 Olayları - PictureBox

        private void pictureBox6_MouseLeave(object sender, EventArgs e)

        {

            pictureBox6.BorderStyle = BorderStyle.None;

        }

        private void pictureBox6_MouseEnter(object sender, EventArgs e)

        {

            pictureBox6.BorderStyle = BorderStyle.FixedSingle;

        }

        private void pictureBox6_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.PictureBox_Eklendi(true);

            Infos.pic_kapat = false;

            Infos.pic_enazbir = true;

        }

        //PictureBox7 Olayları - Progressbar

        private void pictureBox7_MouseLeave(object sender, EventArgs e)

        {

            pictureBox7.BorderStyle = BorderStyle.None;

        }

        private void pictureBox7_MouseEnter(object sender, EventArgs e)

        {

            pictureBox7.BorderStyle = BorderStyle.FixedSingle;

        }

        private void pictureBox7_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.ProgressBar_Eklendi(true);

            Infos.pro_kapat = false;

            Infos.pro_enazbir = true;

        }

        //PictureBox8 Olayları - RadioButton

        private void pictureBox8_MouseLeave(object sender, EventArgs e)

        {

            pictureBox8.BorderStyle = BorderStyle.None;

        }

        private void pictureBox8_MouseEnter(object sender, EventArgs e)

        {

            pictureBox8.BorderStyle = BorderStyle.FixedSingle;

        }

        private void pictureBox8_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.RadioButton_Eklendi(true);

            Infos.rad_kapat = false;

            Infos.rad_enazbir = true;

        }

        //PictureBox9 Olayları - Textbox

        private void pictureBox9_MouseLeave(object sender, EventArgs e)

        {

            pictureBox9.BorderStyle = BorderStyle.None;

        }

        private void pictureBox9_MouseEnter(object sender, EventArgs e)

        {

            pictureBox9.BorderStyle = BorderStyle.FixedSingle;

        }

        private void pictureBox9_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.TextBox_Eklendi(true);

            Infos.txt_kapat = false;

            Infos.txt_enazbir = true;

        }

        //PictureBox10 Olayları - Tooltip

        private void pictureBox10_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.Tooltip_Eklendi(true);

            Infos.tot_kapat = false;

            Infos.tot_enazbir = true;

        }

        private void Toolbox_Load(object sender, EventArgs e)

        {

            this.ShowInTaskbar = false;

            EnableMenuItem(GetSystemMenu(this.Handle, false), SC_CLOSE, MF_GRAYED);

        }

        private void Toolbox_Move(object sender, EventArgs e)

        {

            this.DesktopLocation = new System.Drawing.Point(141, 109);

        }

        private void Toolbox_Resize(object sender, EventArgs e)

        {

            this.Size = new Size(190, 600);

        }

    }

}

Kodları Açıklayalım...

        private const int SC_CLOSE = 0xF060;

        private const int MF_GRAYED = 0x1;

        [DllImport("user32.dll")]

        private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

        [DllImport("user32.dll")]

        private static extern int EnableMenuItem(IntPtr hMenu, int wIDEnableItem, int wEnable);

Aynı tarz işlemi bildiğiniz üzere Özellikler formumuzda da yapmıştık.Windows API leri yardımıyla Formun kapatma tuşunu disable etmektedir.

 

private void pictureBox1_MouseLeave(object sender, EventArgs e)

        {

            pictureBox1.BorderStyle = BorderStyle.None;

        }

Mouse unuz PictureBox’ların üzerinden ayrılınca Köşe Stili uygulamamasını belirtiyoruz.PictureBox ın üzerine gelindiği anlaşılsın diye böyle bir kodlama yaptık

 

        private void pictureBox1_MouseEnter(object sender, EventArgs e)

        {

            pictureBox1.BorderStyle = BorderStyle.FixedSingle;

        }

Mouse unuz PictureBox’ların üzerine gelince Köşe Stili(FixedSingle) uygulamasını belirtiyoruz.

 

        private void pictureBox1_Click(object sender, EventArgs e)

        {

            Infos dun = new Infos();

            dun.Button_Eklendi(true);

            Infos.kapat = false;

            Infos.enazbir = true;

        }

PictureBox1 yani Button kontrolümüzü eklememize yarayan kontrole tıklayınca GameWindow’a bir button eklemesini söylüyoruz.kapat ve enazbir değişkenlerinin de yardımıyla sadece 1 adet button yüklenmesini sağlıyoruz.

        //PictureBox2 Olayları - Checkbox

        private void pictureBox2_MouseLeave(object sender, EventArgs e)

        {

            pictureBox2.BorderStyle = BorderStyle.None;

        }

Mouse unuz PictureBox’ların üzerinden ayrılınca Köşe Stili(None) uygulamamasını belirtiyoruz.

        private void pictureBox2_MouseEnter(object sender, EventArgs e)

        {

            pictureBox2.BorderStyle = BorderStyle.FixedSingle;

        }

Mouse unuz PictureBox’ların üzerine gelince Köşe Stili(FixedSingle) uygulamasını belirtiyoruz.

        private void pictureBox2_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.CheckBox_Eklendi(true);

            Infos.c_kapat = false;

            Infos.c_enazbir = true;

        }

PictureBox2 yani CheckBox kontrolümüzü eklememize yarayan kontrole tıklayınca GameWindow’a bir CheckBox eklemesini söylüyoruz.kapat ve enazbir değişkenlerinin de yardımıyla sadece 1 adet CheckBox yüklenmesini sağlıyoruz.

        //PictureBox3 Olayları - ComboBox

        private void pictureBox3_MouseLeave(object sender, EventArgs e)

        {

            pictureBox3.BorderStyle = BorderStyle.None;

        }

Mouse unuz PictureBox’ların üzerinden ayrılınca Köşe Stili(None) uygulamamasını belirtiyoruz.

 

        private void pictureBox3_MouseEnter(object sender, EventArgs e)

        {

            pictureBox3.BorderStyle = BorderStyle.FixedSingle;

        }

Mouse unuz PictureBox’ların üzerine gelince Köşe Stili(FixedSingle) uygulamasını belirtiyoruz.

 

        private void pictureBox3_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.ComboBox_Eklendi(true);

            Infos.co_kapat = false;

            Infos.co_enazbir = true;

        }

PictureBox3 yani ComboBox kontrolümüzü eklememize yarayan kontrole tıklayınca GameWindow’a bir ComboBox eklemesini söylüyoruz.kapat ve enazbir değişkenlerinin de yardımıyla sadece 1 adet ComboBox yüklenmesini sağlıyoruz.

 

        //PictureBox4 Olayları - Label

        private void pictureBox4_MouseLeave(object sender, EventArgs e)

        {

            pictureBox4.BorderStyle = BorderStyle.None;

        }

Mouse unuz PictureBox’ların üzerinden ayrılınca Köşe Stili(None) uygulamamasını belirtiyoruz.

 

        private void pictureBox4_MouseEnter(object sender, EventArgs e)

        {

            pictureBox4.BorderStyle = BorderStyle.FixedSingle;

        }

Mouse unuz PictureBox’ların üzerine gelince Köşe Stili(FixedSingle) uygulamasını belirtiyoruz.

 

        private void pictureBox4_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.Label_Eklendi(true);

            Infos.l_kapat = false;

            Infos.l_enazbir = true;

        }

PictureBox4 yani Label kontrolümüzü eklememize yarayan kontrole tıklayınca GameWindow’a bir Label eklemesini söylüyoruz.kapat ve enazbir değişkenlerinin de yardımıyla sadece 1 adet Label yüklenmesini sağlıyoruz.

 

        //PictureBox5 Olayları - ListBox

        private void pictureBox5_MouseLeave(object sender, EventArgs e)

        {

            pictureBox5.BorderStyle = BorderStyle.None;

        }

Mouse unuz PictureBox’ların üzerinden ayrılınca Köşe Stili(None) uygulamamasını belirtiyoruz.

 

        private void pictureBox5_MouseEnter(object sender, EventArgs e)

        {

            pictureBox5.BorderStyle = BorderStyle.FixedSingle;

        }

Mouse unuz PictureBox’ların üzerine gelince Köşe Stili(FixedSingle) uygulamasını belirtiyoruz.

 

        private void pictureBox5_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.ListBox_Eklendi(true);

            Infos.lbx_kapat = false;

            Infos.lbx_enazbir = true;

        }

PictureBox5 yani ListBox kontrolümüzü eklememize yarayan kontrole tıklayınca GameWindow’a bir ListBox eklemesini söylüyoruz.kapat ve enazbir değişkenlerinin de yardımıyla sadece 1 adet ListBox yüklenmesini sağlıyoruz.

 

        //PictureBox6 Olayları - PictureBox

        private void pictureBox6_MouseLeave(object sender, EventArgs e)

        {

            pictureBox6.BorderStyle = BorderStyle.None;

        }

Mouse unuz PictureBox’ların üzerinden ayrılınca Köşe Stili(None) uygulamamasını belirtiyoruz.

 

        private void pictureBox6_MouseEnter(object sender, EventArgs e)

        {

            pictureBox6.BorderStyle = BorderStyle.FixedSingle;

        }

Mouse unuz PictureBox’ların üzerine gelince Köşe Stili(FixedSingle) uygulamasını belirtiyoruz.

 

        private void pictureBox6_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.PictureBox_Eklendi(true);

            Infos.pic_kapat = false;

            Infos.pic_enazbir = true;

        }

PictureBox6 yani PictureBox kontrolümüzü eklememize yarayan kontrole tıklayınca GameWindow’a bir PictureBox eklemesini söylüyoruz.kapat ve enazbir değişkenlerinin de yardımıyla sadece 1 adet PictureBox yüklenmesini sağlıyoruz.

        //PictureBox7 Olayları - Progressbar

        private void pictureBox7_MouseLeave(object sender, EventArgs e)

        {

            pictureBox7.BorderStyle = BorderStyle.None;

        }

Mouse unuz PictureBox’ların üzerinden ayrılınca Köşe Stili(None) uygulamamasını belirtiyoruz.

        private void pictureBox7_MouseEnter(object sender, EventArgs e)

        {

            pictureBox7.BorderStyle = BorderStyle.FixedSingle;

        }

Mouse unuz PictureBox’ların üzerine gelince Köşe Stili(FixedSingle) uygulamasını belirtiyoruz.

 

        private void pictureBox7_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.ProgressBar_Eklendi(true);

            Infos.pro_kapat = false;

            Infos.pro_enazbir = true;

        }

PictureBox7 yani ProgressBar kontrolümüzü eklememize yarayan kontrole tıklayınca GameWindow’a bir ProgressBar eklemesini söylüyoruz.kapat ve enazbir değişkenlerinin de yardımıyla sadece 1 adet ProgressBar yüklenmesini sağlıyoruz.

        //PictureBox8 Olayları - RadioButton

        private void pictureBox8_MouseLeave(object sender, EventArgs e)

        {

            pictureBox8.BorderStyle = BorderStyle.None;

        }

Mouse unuz PictureBox’ların üzerinden ayrılınca Köşe Stili(None) uygulamamasını belirtiyoruz.

 

        private void pictureBox8_MouseEnter(object sender, EventArgs e)

        {

            pictureBox8.BorderStyle = BorderStyle.FixedSingle;

        }

Mouse unuz PictureBox’ların üzerine gelince Köşe Stili(FixedSingle) uygulamasını belirtiyoruz.

 

        private void pictureBox8_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.RadioButton_Eklendi(true);

            Infos.rad_kapat = false;

            Infos.rad_enazbir = true;

        }

PictureBox8 yani RadioButton kontrolümüzü eklememize yarayan kontrole tıklayınca GameWindow’a bir RadioButton eklemesini söylüyoruz.kapat ve enazbir değişkenlerinin de yardımıyla sadece 1 adet RadioButton yüklenmesini sağlıyoruz.

 

        //PictureBox9 Olayları - Textbox

        private void pictureBox9_MouseLeave(object sender, EventArgs e)

        {

            pictureBox9.BorderStyle = BorderStyle.None;

        }

Mouse unuz PictureBox’ların üzerinden ayrılınca Köşe Stili(None) uygulamamasını belirtiyoruz.

        private void pictureBox9_MouseEnter(object sender, EventArgs e)

        {

            pictureBox9.BorderStyle = BorderStyle.FixedSingle;

        }

Mouse unuz PictureBox’ların üzerine gelince Köşe Stili(FixedSingle) uygulamasını belirtiyoruz.

        private void pictureBox9_Click(object sender, EventArgs e)

        {

            Infos yeni = new Infos();

            yeni.TextBox_Eklendi(true);

            Infos.txt_kapat = false;

            Infos.txt_enazbir = true;

        }

PictureBox9 yani TextBox kontrolümüzü eklememize yarayan kontrole tıklayınca GameWindow’a bir TextBox eklemesini söylüyoruz.kapat ve enazbir değişkenlerinin de yardımıyla sadece 1 adet TextBox yüklenmesini sağlıyoruz.

 

        //PictureBox10 Olayları - Tooltip

        private void Toolbox_Load(object sender, EventArgs e)

        {

            this.ShowInTaskbar = false;

            EnableMenuItem(GetSystemMenu(this.Handle, false), SC_CLOSE, MF_GRAYED);

        }

Özellikler_Load daki kod ile aynı işi yapmaktadır: Görev Çubuğunda görüntülenmesini engellemek ve Kapatma tuşunu disable etmek

       

        private void Toolbox_Move(object sender, EventArgs e)

        {

            this.DesktopLocation = new System.Drawing.Point(141, 109);

        }

Ozellikler_Move ile aynı işi yapar: Toolbox formunun hareket etmesini engeller ve bir noktaya sabitler.

        private void Toolbox_Resize(object sender, EventArgs e)

        {

            this.Size = new Size(190, 600);

        }

Ozellikler_Resize ın yaptığını yapar.Toolbox formunuzun boyutlandırmasını engeller.

Toolbox ı özetlememiz gerekirse:

* Picturebox lardaki kontrollere Mouse un üzerine gelince Köşe Çizgileri değişmektedir.
* PictureBox a tıklanınca GameWindow a Infos classı aracılığıyla Kontroller yüklenmektedir.
* Toolbox ın Kapatılmasını engellemek için Windows API leri kullanılmıştır.


Aslında Toolbox-Ozellikler-GameWindow  iletişimini “Infos.cs” dosyamız sayesinde sağlamaktayız...


Makalenin devamı için serinin 4.bölümüne geçiş yapınız...

Etiketler : XNA Microsoft GUI Editör GUI
Kategoriler : Microsoft XNA
Yorumlar : 0 Yorum Yorum Yaz
HTML clipboard

Makalenin 2.Bölümüne Hoşgeldiniz.Bu bölümde Diğer Kontrol Classlarımız ile ilgili bilgiler verilecektir.


Diğer Kontrol Classlarımızda da benzer işlemler vardır dolayısıyla tekrardan ne işe yaradıklarını anlatmayacağım ama yinede kodlarını paylaşmak istiyorum:

XCheckBox Classı:

using System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Drawing;

namespace GUIEditor
{
   
class XCheckBox:CheckBox
   
{
       
private Boolean dragInProgress = false;
       
public Boolean en = true;
       
int MouseDownX = 0;
       
int MouseDownY = 0;

       
public XCheckBox()
       
{
           
this.MouseDown += new MouseEventHandler(MDown);
           
this.MouseUp += new MouseEventHandler(MUp);
           
this.MouseMove += new MouseEventHandler(MMove);
           
this.MouseEnter += new EventHandler(MEnter);
           
this.MouseLeave += new EventHandler(MLeave);
           
this.BackColor = Color.CornflowerBlue;
       
}

        protected override bool ShowFocusCues
       
{
           
get
           
{
               
return false;
           
}
       
}

        private void MDown(Object sender, MouseEventArgs e)
       
{
           
if (!this.dragInProgress)
           
{
               
this.dragInProgress = true;
               
this.MouseDownX = e.X;
               
this.MouseDownY = e.Y;
           
}
           
return;
       
}

        private void MUp(Object sender, MouseEventArgs e)
       
{
           
if (e.Button == MouseButtons.Left)
           
{
               
this.dragInProgress = false;
           
}

            else if (e.Button == MouseButtons.Right)
           
{
               
Infos.kontroller.Clear();

                foreach (Control c in Infos.strunq)
               
{
                   
Infos.kontroller.Add(c);
               
}

                Infos.strunq.Remove(Infos.secilikontrol);
               
this.Dispose(true);
           
}
           
return;
       
}

        private void MMove(Object sender, MouseEventArgs e)
       
{
           
if (dragInProgress)
           
{
               
Point temp = new Point();
               
temp.X = this.Location.X + (e.X - MouseDownX);
               
temp.Y = this.Location.Y + (e.Y - MouseDownY);
               
this.Location = temp;
           
}
           
return;
       
}

        private void MEnter(Object sender, EventArgs e)
       
{

        }

        private void MLeave(Object sender, EventArgs e)
       
{

        }
   
}
}

XComboBox Classı:

using System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Drawing;

namespace
GUIEditor
{
   
class XComboBox:ComboBox
   
{
       
private Boolean dragInProgress = false;
       
public Boolean en = true;
       
int MouseDownX = 0;
       
int MouseDownY = 0;

       
public XComboBox()
       
{
           
this.FlatStyle = FlatStyle.Flat;
           
this.MouseDown += new MouseEventHandler(MDown);
           
this.MouseUp += new MouseEventHandler(MUp);
           
this.MouseMove += new MouseEventHandler(MMove);
           
this.MouseEnter += new EventHandler(MEnter);
           
this.MouseLeave += new EventHandler(MLeave);
       
}

        protected override bool ShowFocusCues
       
{
           
get
           
{
               
return false;
           
}
       
}

        private void MDown(Object sender, MouseEventArgs e)
       
{
           
if (!this.dragInProgress)
           
{
               
this.dragInProgress = true;
               
this.MouseDownX = e.X;
               
this.MouseDownY = e.Y;
           
}
           
return;
       
}

        private void MUp(Object sender, MouseEventArgs e)
       
{
           
if (e.Button == MouseButtons.Left)
           
{
               
this.dragInProgress = false;
           
}

            else if (e.Button == MouseButtons.Right)
           
{
               
Infos.kontroller.Clear();

                foreach (Control c in Infos.strunq)
               
{
                   
Infos.kontroller.Add(c);
               
}

                Infos.strunq.Remove(Infos.secilikontrol);
               
this.Dispose(true);
           
}
           
return;
       
}

        private void MMove(Object sender, MouseEventArgs e)
       
{
           
if (dragInProgress)
           
{
               
Point temp = new Point();
               
temp.X = this.Location.X + (e.X - MouseDownX);
               
temp.Y = this.Location.Y + (e.Y - MouseDownY);
               
this.Location = temp; 
           
}
           
return;
       
}

        private void MEnter(Object sender, EventArgs e)
       
{

        }

        private void MLeave(Object sender, EventArgs e)
       
{

        }
   
}
}

XLabel Classı:

using System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Drawing;

namespace GUIEditor
{
   
class XLabel:Label
   
{
       
private Boolean dragInProgress = false;
       
public Boolean en = true;
       
int MouseDownX = 0;
       
int MouseDownY = 0;

        public XLabel()
       
{
           
this.FlatStyle = FlatStyle.Flat;
           
this.BackColor = Color.CornflowerBlue;
           
this.BackgroundImageLayout = ImageLayout.Stretch;
           
this.MouseDown += new MouseEventHandler(MDown);
           
this.MouseUp += new MouseEventHandler(MUp);
           
this.MouseMove += new MouseEventHandler(MMove); 
           
this.MouseEnter += new EventHandler(MEnter);
           
this.MouseLeave += new EventHandler(MLeave);
       
}

        protected override bool ShowFocusCues
       
{
           
get
           
{
               
return false;
           
}
       
}

        private void MDown(Object sender, MouseEventArgs e)
       
{
           
if (!this.dragInProgress)
           
{
               
this.Focus();
               
this.dragInProgress = true;
               
this.MouseDownX = e.X;
               
this.MouseDownY = e.Y;
           
}
           
return;
       
}

        private void MUp(Object sender, MouseEventArgs e)
       
{
           
if (e.Button == MouseButtons.Left)
           
{
               
this.dragInProgress = false;
           
}

            else if (e.Button == MouseButtons.Right)
           
{
               
Infos.kontroller.Clear();

                foreach (Control c in Infos.strunq)
               
{
                   
Infos.kontroller.Add(c);
               
}

                Infos.strunq.Remove(Infos.secilikontrol);
               
this.Dispose(true);
           
}
           
return;
       
}

        private void MMove(Object sender, MouseEventArgs e)
       
{
           
if (dragInProgress)
           
{
               
Point temp = new Point();
               
temp.X = this.Location.X + (e.X - MouseDownX);
               
temp.Y = this.Location.Y + (e.Y - MouseDownY);
               
this.Location = temp;
           
}
           
return;
       
}

        private void MEnter(Object sender, EventArgs e)
       
{

        }

        private void MLeave(Object sender, EventArgs e)
       
{

        }
   
}
}

XListBox Classı:

using System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Drawing;

namespace GUIEditor
{
   
class XListBox:ListBox
   
{
       
private Boolean dragInProgress = false;
       
public Boolean en = true;
       
int MouseDownX = 0;
       
int MouseDownY = 0;

        public XListBox()
       
{
           
this.BackgroundImageLayout = ImageLayout.Stretch;
           
this.MouseDown += new MouseEventHandler(MDown);
           
this.MouseUp += new MouseEventHandler(MUp);
           
this.MouseMove += new MouseEventHandler(MMove);
           
this.Click += new EventHandler(BClick);
           
this.MouseEnter += new EventHandler(MEnter);
           
this.MouseLeave += new EventHandler(MLeave);

            for (int a = 0; a < 10; a++)
           
{
               
this.Items.Add(a.ToString());
           
}
       
}

        private void BClick(object sender, EventArgs e)
       
{

        }

        private void DBClick(object sender, EventArgs e)
       
{

        }

        protected override bool ShowFocusCues
       
{
           
get
           
{
               
return false;
           
}
       
}

        private void MDown(Object sender, MouseEventArgs e)
       
{
           
if (!this.dragInProgress)
           
{
               
this.dragInProgress = true;
               
this.MouseDownX = e.X;
               
this.MouseDownY = e.Y;
           
}
           
return;
       
}

        private void MUp(Object sender, MouseEventArgs e)
       
{
           
if (e.Button == MouseButtons.Left)
           
{
               
this.dragInProgress = false;
           
}

            else if (e.Button == MouseButtons.Right)
           
{
               
Infos.kontroller.Clear();

                foreach (Control c in Infos.strunq)
               
{
                   
Infos.kontroller.Add(c);
               
}

                Infos.strunq.Remove(Infos.secilikontrol);
               
this.Dispose(true);
           
}
           
return;
       
}

        private void MMove(Object sender, MouseEventArgs e)
       
{
           
if (dragInProgress)
           
{
               
Point temp = new Point();
               
temp.X = this.Location.X + (e.X - MouseDownX);
               
temp.Y = this.Location.Y + (e.Y - MouseDownY);
               
this.Location = temp;
           
}
           
return;
       
}

        private void MEnter(Object sender, EventArgs e)
       
{

        }

        private void MLeave(Object sender, EventArgs e)
       
{

        }
   
}
}

XPictureBox Classı:

using System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Drawing;

namespace GUIEditor
{
   
class XPictureBox:PictureBox
   
{
       
private Boolean dragInProgress = false;
       
public Boolean en = true;
       
int MouseDownX = 0;
       
int MouseDownY = 0;

       
public XPictureBox()
       
{
           
this.MouseDown += new MouseEventHandler(MDown);
           
this.MouseUp += new MouseEventHandler(MUp);
           
this.MouseMove += new MouseEventHandler(MMove);
           
this.Click += new EventHandler(BClick);
           
this.MouseEnter += new EventHandler(MEnter);
           
this.MouseLeave += new EventHandler(MLeave);
           
this.Image = Resource1._987_original;
           
this.SizeMode = PictureBoxSizeMode.StretchImage;
           
this.Size = new Size(300, 150);
       
}

        private void BClick(object sender, EventArgs e)
       
{

        }

        private void DBClick(object sender, EventArgs e)
       
{

        }

        protected override bool ShowFocusCues
       
{
           
get
           
{
               
return false;
           
}
       
}

       
private void MDown(Object sender, MouseEventArgs e)
       
{
           
if (!this.dragInProgress)
           
{
               
this.Focus();
               
this.dragInProgress = true;
               
this.MouseDownX = e.X;
               
this.MouseDownY = e.Y;
           
}
           
return;
       
}

        private void MUp(Object sender, MouseEventArgs e)
       
{
           
if (e.Button == MouseButtons.Left)
           
{
               
this.dragInProgress = false;
           
}

            else if (e.Button == MouseButtons.Right)
           
{
               
Infos.kontroller.Clear();

               
foreach (Control c in Infos.strunq)
               
{
                   
Infos.kontroller.Add(c);
               
}

                Infos.strunq.Remove(Infos.secilikontrol);
               
this.Dispose(true);
           
}
           
return;
       
}

        private void MMove(Object sender, MouseEventArgs e)
       
{
           
if (dragInProgress)
           
{
               
Point temp = new Point();
               
temp.X = this.Location.X + (e.X - MouseDownX);
               
temp.Y = this.Location.Y + (e.Y - MouseDownY);
               
this.Location = temp;
           
}
           
return;
       
}

        private void MEnter(Object sender, EventArgs e)
       
{           

        }

        private void MLeave(Object sender, EventArgs e)
       
{

        }
   
}
}

XProgressBar Classı:

using System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Drawing;
using
System.Runtime.InteropServices;
using
System.Globalization;

namespace GUIEditor
{
   
class XProgressBar : ProgressBar
   
{
       
private Boolean dragInProgress = false;
       
public Boolean en = true;
       
int MouseDownX = 0;
       
int MouseDownY = 0;
       
Timer prozaman = new Timer();

       
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
       
private static extern IntPtr SendMessageA(IntPtr hWnd, Int32 wMsg, IntPtr wParam, IntPtr lParam);
       
private const Int32 WM_USER = 0x400;
       
private const Int32 CCM_FIRST = 0x2000;
       
private const Int32 CCM_SETBKCOLOR = (CCM_FIRST + 0x1);
       
private const Int32 PBM_SETBARCOLOR = (WM_USER + 9);
       
private const Int32 PBM_SETBKCOLOR = CCM_SETBKCOLOR;
       
private const uint CLR_DEFAULT = 0xff000000;
       
private ProgressBar m_ProgressBar;
       
private Color m_BackColor;
       
private Color m_ForeColor;
       
private Color m_OldBackColor;
       
private Color m_OldForeColor;

       
public XProgressBar()
       
{
           
this.Style = ProgressBarStyle.Continuous;
           
this.MouseDown += new MouseEventHandler(MDown);
           
this.MouseUp += new MouseEventHandler(MUp);
           
this.MouseMove += new MouseEventHandler(MMove);
           
this.Click += new EventHandler(BClick);
           
this.MouseEnter += new EventHandler(MEnter);
           
this.MouseLeave += new EventHandler(MLeave);
           
this.Minimum = 0;
           
this.Maximum = 100;
           
this.Size = new Size(300, 35);
           
prozaman.Tick += new EventHandler(zamanpro_Tick);
           
ProgressBarHelper(this);
           
this.ForeColor = Color.Red;
           
this.BackColor = Color.White;
       
}

        private void BClick(object sender, EventArgs e)
       
{
           
prozaman.Enabled = true;
       
}

        private void DBClick(object sender, EventArgs e)
       
{

        }

        private void zamanpro_Tick(object sender, EventArgs e)
       
{
           
this.Value += 2;
           
if (this.Value == 100)
           
{
               
if (this.Value == 100)
               
{
                   
this.Value = 0;
               
}
           
}
       
}

        protected override bool ShowFocusCues
       
{
           
get
           
{
               
return false;
           
}
       
}

        private void MDown(Object sender, MouseEventArgs e)
       
{
           
if (!this.dragInProgress)
           
{
               
this.Focus();
               
this.dragInProgress = true;
               
this.MouseDownX = e.X;
               
this.MouseDownY = e.Y;
           
}
           
return;
       
}

        private void MUp(Object sender, MouseEventArgs e)
       
{
           
if (e.Button == MouseButtons.Left)
           
{
               
this.dragInProgress = false;
           
}

            else if (e.Button == MouseButtons.Right)
           
{
               
Infos.kontroller.Clear();

                foreach (Control c in Infos.strunq)
               
{
                   
Infos.kontroller.Add(c);
               
}

                Infos.strunq.Remove(Infos.secilikontrol);
               
this.Dispose(true);
           
}
           
return;
       
}

        private void MMove(Object sender, MouseEventArgs e)
       
{
           
if (dragInProgress)
           
{
               
Point temp = new Point();
               
temp.X = this.Location.X + (e.X - MouseDownX);
               
temp.Y = this.Location.Y + (e.Y - MouseDownY);
               
this.Location = temp;
           
}
           
return;
       
}

        private void MEnter(Object sender, EventArgs e)
       
{

        }

        private void MLeave(Object sender, EventArgs e)
       
{

        }

        public void ProgressBarHelper(ProgressBar ProgressBar)
       
{

       
if (ProgressBar == null)
            {
               
throw new NullReferenceException();
           
}

       
m_ProgressBar = ProgressBar;
       
this.ForeColor = DefaultColor;
       
this.BackColor = DefaultColor;

       
}

    public ProgressBar ProgressBar {

        get { return m_ProgressBar; }
   
}

    public Color ForeColor {
       
get { return m_ForeColor; }
       
set {
           
m_ForeColor = value;
           
SetBarColor(this.ForeColor);
       
}
   
}

   public Color BackColor {
       
get { return m_BackColor; }
       
set {
           
m_BackColor = value;
           
SetBkColor(this.BackColor);
       
}
   
}

    public static Color DefaultColor {
       
get { return Color.Transparent; }
   
}

    private Color SetBarColor(Color Color)
   
{
       
return ProgressBarColorToDotNetColor(SendMessageA(m_ProgressBar.Handle, PBM_SETBARCOLOR, IntPtr.Zero, new IntPtr(DotNetColorToProgressBarColor(Color))).ToInt32());
   
}

    private Color SetBkColor(Color Color)
   
{
       
return ProgressBarColorToDotNetColor(SendMessageA(m_ProgressBar.Handle, PBM_SETBKCOLOR, IntPtr.Zero, new IntPtr(DotNetColorToProgressBarColor(Color))).ToInt32());
   
}

    private Int32 DotNetColorToProgressBarColor(Color Color)
   
{
       
if (Color == DefaultColor) {
           
return unchecked((int)CLR_DEFAULT);
       
}

        else {
           
return ColorTranslator.ToWin32(Color);
       
}
   
}

    private Color ProgressBarColorToDotNetColor(Int32 Color)
   
{
       
if (Color == CLR_DEFAULT) {
           
return DefaultColor;
       
}

       
else {
           
return ColorTranslator.FromWin32(Color);
       
}
   
}
   
}
}

XProgressBar Classımızda ekstradan Windows API çağrılarını kullandım.Yaptıkları tek işlem ProgressBar ın arka plan ve ilerleme çubuğunun rengini değiştirmektir.Örnekte Kırmızı yapmış bulunmaktayız...

XRadioButton Classı:

using System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Drawing;

namespace GUIEditor
{
   
class XRadioButton:RadioButton
   
{
       
private Boolean dragInProgress = false;
       
public Boolean en = true;
       
int MouseDownX = 0;
       
int MouseDownY = 0;

       
public XRadioButton()
       
{
           
this.BackColor = Color.CornflowerBlue;
           
this.FlatStyle = FlatStyle.Popup;
           
this.FlatAppearance.BorderSize = 0;
           
this.MouseDown += new MouseEventHandler(MDown);
           
this.MouseUp += new MouseEventHandler(MUp);
           
this.MouseMove += new MouseEventHandler(MMove);
           
this.Click += new EventHandler(BClick);
           
this.MouseEnter += new EventHandler(MEnter);
           
this.MouseLeave += new EventHandler(MLeave);
       
}

        private void BClick(object sender, EventArgs e)
       
{

        }

        private void DBClick(object sender, EventArgs e)
       
{

        }

        protected override bool ShowFocusCues
       
{
           
get
           
{
               
return false;
           
}
       
}

        private void MDown(Object sender, MouseEventArgs e)
       
{
           
if (!this.dragInProgress)
           
{
               
this.dragInProgress = true;
               
this.MouseDownX = e.X;
               
this.MouseDownY = e.Y;
           
}
           
return;
       
}

        private void MUp(Object sender, MouseEventArgs e)
       
{
           
if (e.Button == MouseButtons.Left)
           
{
               
this.dragInProgress = false;
           
}

            else if (e.Button == MouseButtons.Right)
           
{
               
Infos.kontroller.Clear();

                foreach (Control c in Infos.strunq)
               
{
                   
Infos.kontroller.Add(c);
               
}

                Infos.strunq.Remove(Infos.secilikontrol);
               
this.Dispose(true);
           
}
           
return;
       
}

        private void MMove(Object sender, MouseEventArgs e)
       
{
           
if (dragInProgress)
           
{
               
Point temp = new Point();
               
temp.X = this.Location.X + (e.X - MouseDownX);
               
temp.Y = this.Location.Y + (e.Y - MouseDownY);
               
this.Location = temp;
           
}
           
return;
       
}

        private void MEnter(Object sender, EventArgs e)
       
{

        }

        private void MLeave(Object sender, EventArgs e)
       
{

        }
   
}
}

XTextBox Classı:


using System;

using System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Drawing;

namespace GUIEditor
{
   
class XTextBox:TextBox
   
{
       
private Boolean dragInProgress = false;
       
public Boolean en = true;
       
int MouseDownX = 0;
       
int MouseDownY = 0;

        public XTextBox()
       
{
           
this.BackgroundImage = Resource1.Button_overSkin;
           
this.BackColor = Color.CornflowerBlue;
           
this.BackgroundImageLayout = ImageLayout.Stretch;
           
this.MouseDown += new MouseEventHandler(MDown);
           
this.MouseUp += new MouseEventHandler(MUp);
           
this.MouseMove += new MouseEventHandler(MMove);
           
this.Click += new EventHandler(BClick);
           
this.MouseEnter += new EventHandler(MEnter);
           
this.MouseLeave += new EventHandler(MLeave);
       
}

        private void BClick(object sender, EventArgs e)
       
{

        }

        private void DBClick(object sender, EventArgs e)
       
{

        }

        protected override bool ShowFocusCues
       
{
           
get
           
{
               
return false;
           
}
       
}

        private void MDown(Object sender, MouseEventArgs e)
       
{
           
if (!this.dragInProgress)
           
{
               
this.dragInProgress = true;
               
this.MouseDownX = e.X;
               
this.MouseDownY = e.Y;
           
}
           
return;
       
}

        private void MUp(Object sender, MouseEventArgs e)
       
{
           
if (e.Button == MouseButtons.Left)
           
{
               
this.dragInProgress = false;
               
this.BackgroundImage = Resource1.Button_downSkin;
           
}

            else if (e.Button == MouseButtons.Right)
           
{
               
Infos.kontroller.Clear();

                foreach (Control c in Infos.strunq)
               
{
                   
Infos.kontroller.Add(c);
               
}

                Infos.strunq.Remove(Infos.secilikontrol);
               
this.Dispose(true);
           
}
           
return;
       
}

        private void MMove(Object sender, MouseEventArgs e)
       
{
           
if (dragInProgress)
           
{
               
Point temp = new Point();
               
temp.X = this.Location.X + (e.X - MouseDownX);
               
temp.Y = this.Location.Y + (e.Y - MouseDownY);
               
this.Location = temp;
               
this.BackgroundImage = Resource1.Button_upSkin;
           
}
           
return;
       
}

        private void MEnter(Object sender, EventArgs e)
       
{
           
this.BackgroundImage = Resource1.Button_upSkin;
       
}

        private void MLeave(Object sender, EventArgs e)
       
{
           
this.BackgroundImage = Resource1.Button_overSkin;
       
}
   
}
}

 

Evet şimdi de geldik Control Properties adını verdiğimiz UserControlümüzün kodlamasına.

Bu UserControlün esprisi GameWindow da bir kontrol seçiliyken ona ait bilgilerin bu UserControl üzerinde gösterilmesini sağlamaktır.

Hep beraber kodlamasına bakalım...

using System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Drawing;
using
System.Data;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Threading;

namespace
GUIEditor.Control_Properties
{
   
public partial class Control_Properties : UserControl
   
{
       
string[] colorNames = System.Enum.GetNames(typeof(KnownColor));

       
public Control_Properties()
       
{
           
InitializeComponent();
       
}

        private void Control_Properties_Load(object sender, EventArgs e)

        {           

            comboBox3.Items.AddRange(colorNames);

            timer1.Enabled = true;

        }

        private void timer1_Tick(object sender, EventArgs e)

        {

            if (Infos.kontrool == null)

            {

            }

            else

            {

                textBox1.Text = Infos.kontrool.Name;

                comboBox1.Text = Infos.kontrool.AllowDrop.ToString();

                comboBox2.Text = Infos.kontrool.Enabled.ToString();

                comboBox3.Text = Infos.kontrool.ForeColor.ToKnownColor().ToString();

                textBox2.Text = Infos.kontrool.Location.X.ToString();

                textBox3.Text = Infos.kontrool.Location.Y.ToString();

                textBox4.Text = Infos.kontrool.Size.Width.ToString();

                textBox5.Text = Infos.kontrool.Size.Height.ToString();

                textBox6.Text = Infos.kontrool.Text;                             

            }

        }

        private void textBox1_TextChanged(object sender, EventArgs e)

        {

            Infos.kontrool.Name = textBox1.Text;

        }

        private void comboBox1_SelectedValueChanged(object sender, EventArgs e)

        {

            if (comboBox1.SelectedIndex == 0)

            {

                Infos.kontrool.AllowDrop = true;

            }

            else

            {

                Infos.kontrool.AllowDrop = false;

            }          

        }

        private void comboBox2_SelectedValueChanged(object sender, EventArgs e)

        {

            if (comboBox2.SelectedIndex == 0)

            {

                Infos.kontrool.Enabled  = true;

            }

            else

            {

                Infos.kontrool.Enabled = false;

            }

        }

        private void comboBox3_SelectedValueChanged(object sender, EventArgs e)

        {

            if (comboBox3.Text == null)

            {

            }

            else

            {

                Infos.kontrool.ForeColor = Color.FromName(comboBox3.Text);

            }

        }

        private void textBox2_TextChanged(object sender, EventArgs e)

        {

            if (textBox2.Text == null)

            {

            }

            else

            {

                int xdeger = Infos.kontrool.Location.X;

                int ydeger = Infos.kontrool.Location.Y;             

                xdeger = Int32.Parse(textBox2.Text);

                Infos.kontrool.Location = new Point(xdeger, ydeger);

            }          

        }

        private void textBox3_TextChanged(object sender, EventArgs e)

        {

            if (textBox3.Text == null)

            {

            }

            else

            {

                int xdeger = Infos.kontrool.Location.X;

                int ydeger = Infos.kontrool.Location.Y;

                ydeger = Int32.Parse(textBox3.Text);

                Infos.kontrool.Location = new Point(xdeger, ydeger);

            }           

        }

        private void textBox4_TextChanged(object sender, EventArgs e)

        {

            if (textBox4.Text == null)

            {

            }

            else

            {

                int wdeger = Infos.kontrool.Size.Width;

                int hdeger = Infos.kontrool.Size.Height;

                wdeger = Int32.Parse(textBox4.Text);

                Infos.kontrool.Size = new Size(wdeger, hdeger);

            }

        }

        private void textBox5_TextChanged(object sender, EventArgs e)

        {

            if (textBox5.Text == null)

            {

            }

            else

            {

                int wdeger = Infos.kontrool.Size.Width;

                int hdeger = Infos.kontrool.Size.Height;

                hdeger = Int32.Parse(textBox5.Text);

                Infos.kontrool.Size = new Size(wdeger, hdeger);

            }

        }

        private void textBox6_TextChanged(object sender, EventArgs e)

        {

            Infos.kontrool.Text = textBox6.Text;

        }

    }

}

string[] colorNames = System.Enum.GetNames(typeof(KnownColor));

Burada Sistem kanadında tanımlı tüm renkleri alıp bir string dizisine yerleştiriyoruz.Bunu ForeColor Comboboxımızda kullanacağız.

private void Control_Properties_Load(object sender, EventArgs e)

        {           

            comboBox3.Items.AddRange(colorNames);

            timer1.Enabled = true;

        }

Burada ilgili usercontrolümüz ilk yüklenmeye başladığında tüm renkleri combobox a yüklemesini ve timerı başlatmasını söylüyoruz.

private void timer1_Tick(object sender, EventArgs e)

        {

            if (Infos.kontrool == null)

            {

            }

            else

            {

                textBox1.Text = Infos.kontrool.Name;

                comboBox1.Text = Infos.kontrool.AllowDrop.ToString();

                comboBox2.Text = Infos.kontrool.Enabled.ToString();

                comboBox3.Text = Infos.kontrool.ForeColor.ToKnownColor().ToString();

                textBox2.Text = Infos.kontrool.Location.X.ToString();

                textBox3.Text = Infos.kontrool.Location.Y.ToString();

                textBox4.Text = Infos.kontrool.Size.Width.ToString();

                textBox5.Text = Infos.kontrool.Size.Height.ToString();

                textBox6.Text = Infos.kontrool.Text;                             

            }

        }

Burada birazcık duralım.Timer tick olayı her an kontrolün özelliklerini alıp UserControl üzerindeki kontrollere yazdırmaktadır.ve bunu da Infos da tanımladığımız “kontrool” adlı o anki seçili kontrolü tutan değişkenimizi kullanarak gerçekleştirmektedir.

Seçilen kontrolü aldıktan sonra tek yaptığımız işlem onun özelliklerine erişmek olacaktır.

private void textBox1_TextChanged(object sender, EventArgs e)

        {

            Infos.kontrool.Name = textBox1.Text;

        }

Bu işlem Design anında ilgili nesnenin adını değiştirmemize yaramaktadır.

        private void comboBox1_SelectedValueChanged(object sender, EventArgs e)

        {

            if (comboBox1.SelectedIndex == 0)

            {

                Infos.kontrool.AllowDrop = true;

            }

            else

            {

                Infos.kontrool.AllowDrop = false;

            }          

        }

Bu işlemimiz AllowDrop özelliğinin değerlerini taşıyan 1.combobox ımızın seçili değeri değiştiğinde Design anında ilgili nesnenin AllowDrop özelliğini değiştirmektedir.

private void comboBox2_SelectedValueChanged(object sender, EventArgs e)

        {

            if (comboBox2.SelectedIndex == 0)

            {

                Infos.kontrool.Enabled  = true;

            }

            else

            {

                Infos.kontrool.Enabled = false;

            }

        }

Bu işlemimizde de Enabled özelliğini taşıyan Combobox ın değeri değiştiğinde ilgili kontrolün Enabled özelliğini değiştirmektedir.

private void comboBox3_SelectedValueChanged(object sender, EventArgs e)

        {

            if (comboBox3.Text == null)

            {

            }

            else

            {

                Infos.kontrool.ForeColor = Color.FromName(comboBox3.Text);

            }

        }

Bu işlemimizde 3.combobox ımız yani ForeColor değerlerini tutan kontrolümüz değiştiğinde seçili olan kontrolün ForeColor özelliğini değiştirmemizi sağlamaktadır.

private void textBox2_TextChanged(object sender, EventArgs e)

        {

            if (textBox2.Text == null)

            {

            }

            else

            {

                int xdeger = Infos.kontrool.Location.X;

                int ydeger = Infos.kontrool.Location.Y;             

                xdeger = Int32.Parse(textBox2.Text);

                Infos.kontrool.Location = new Point(xdeger, ydeger);

            }          

        }

Bu işlem textbox2 miz yani LocationX değerimiz değiştiğinde seçili kontrolün Location.X değerini de değiştirmektedir.

        private void textBox3_TextChanged(object sender, EventArgs e)

        {

            if (textBox3.Text == null)

            {

            }

            else

            {

                int xdeger = Infos.kontrool.Location.X;

                int ydeger = Infos.kontrool.Location.Y;

                ydeger = Int32.Parse(textBox3.Text);

                Infos.kontrool.Location = new Point(xdeger, ydeger);

            }           

        }

Bu işlem textbox3 müz yani LocationY değerimiz değiştiğinde seçili kontrolün Location.Y değerini de değiştirmektedir.

        private void textBox4_TextChanged(object sender, EventArgs e)

        {

            if (textBox4.Text == null)

            {

            }

            else

            {

                int wdeger = Infos.kontrool.Size.Width;

                int hdeger = Infos.kontrool.Size.Height;

                wdeger = Int32.Parse(textBox4.Text);

                Infos.kontrool.Size = new Size(wdeger, hdeger);

            }

        }

Bu işlemimiz textbox4 müz yani SizeW değiştiğinde seçili kontrolünde Size.Width değerini değiştirmektedir.   
       

        private void textBox5_TextChanged(object sender, EventArgs e)

        {

            if (textBox5.Text == null)

            {

            }

            else

            {

                int wdeger = Infos.kontrool.Size.Width;

                int hdeger = Infos.kontrool.Size.Height;

                hdeger = Int32.Parse(textBox5.Text);

                Infos.kontrool.Size = new Size(wdeger, hdeger);

            }

        }

Bu işlemimiz textbox5 miz yani SizeH değiştiğinde seçili kontrolünde Size.Height değerini değiştirmektedir.

        private void textBox6_TextChanged(object sender, EventArgs e)

        {

            Infos.kontrool.Text = textBox6.Text;

        }

    }

Bu işlemimiz textbox6 mız yani Text değiştiğinde seçili kontrolünde Text değerini değiştirmektedir.Bazı kontrollerin Text değeri olurken bazılarının olmamaktadır(PictureBox,ProgressBar gibi)

Control_Properties UserControlümüzün kodlarını elimden geldiğinde anlatmaya çalıştım.

 


Makale serisinin 3.bölümüne geçiş yapınız...

Etiketler : GUI Editör GUI XNA Microsoft
Kategoriler : Microsoft XNA
Yorumlar : 0 Yorum Yorum Yaz
Sayfalar
Bağlantılar
Tag Bulutu
Dil Seçin
Arama
  Ara