7 Nisan 2015 Salı

Unification (Birleştirme - Entegrasyon)



Unification (Birleştirme)

                İletişim teknolojilerinde (IT) kullanılan yazılım ve çözümlerin çoğu belli zamanlar içerisinde birbirleri ile iletişim halinde olmak isterler. Farklı ölçeklerdeki firmalarda IT sistemlerinden fayda sağlayan alt birimler farklı sistemlerden elde edilen verileri bir başlık altında toplayıp bu verileri analiz etmek, aynı anda değişik ortamlardan erişmek ve etkileşimde olmak isterler. Örneğin müşteri ilişkileri sisteminden alınan bir siparişin kurum içerisinde ilgili sisteme aktarılması veya aynı sistemi kullanan uç birimlerin birbirleri ile ilgili anlık haberleşmesi bu birleştirmelerdendir.

            Birleştirmenin ana mantığından bir taneside; uç birimlerde kullanıcı deneyimini yüksek tutup, uygulamayı kullanan insanları sistemlerin karmaşasından uzak tutarak bir uygulama içerisinde birden fazla çözüm sunmaktır. Bu çalışmayı yaparken eldeki kaynakların ne şekilde kullanılacağı, gerçekten sadece gerekli sistemlerin bu gruba dahil edilmesi gerekmektedir.
Sistem birleştirmesinde elde edilmesi planlanan faydalardan bazıları;

·         Entegrasyon ve  yönetim maliyetlerinin düşmesi
·         Güncel tutarlı veri bütünlüğü sağlanması
·         İstenilen raporların daha hızlı ve doğru elde edilmesi.
·         İş ve iş akışlarının basitleşmesi ve performansın artması
·         Gelişen mobil dünyaya entegre olunması
·         İş gücü (çalışan) memnuniyeti artması
·         Şirket içi birimler arası iletişimin artması
·         Müşteriye daha hızlı dönüşler ve artan memnuniyet

Bulut bilişimin gelişmesine paralel olarak sistemler arası yapılacak bu çalışmalar için daha önce karşılaşılan platform tabanlı zorluklarda kısmen aşılmıştır. Maliyet, güvenlik, geliştirme, erişilebilirlik, kalite vb sistemler için düşünülmesi gereken sorunlar olmaktan çıkıp, standartlar haline gelmiştir.
Sonuç olarak birleştirme kurum, çalışan ve müşteri arasında konumlanmış IT sistemlerinin daha yararlı kullanımı için düşünülmüş mobil projeler olarak karşımıza çıkmakta.

14 Kasım 2014 Cuma

İp ucu: NET 2.0 için eski projelerinizde C# için Asenkron Çağrım

Asenkron çalışma veya metod çağırımlarını fazla detaylandırmadan; Programınızda aynı anda birbirinden bağımsız işler yapılma durumu varsa, esneklik anlamında programınızın bir yerinde çok uzun süren işlemler yapıyor ve bu durum sizin programızın kitlenmesi vb sonuçlar üretiyorsa Asenkron programlamayla ilgilenme zamanınız gelmiştir. Aşağıda bir örnek üzerinde devam edeceğim....

using System;

using System.Collections.Generic;

using System.Data;

using System.Data.SqlClient;

using System.Linq;

using System.Text;

using System.Threading.Tasks;



namespace TaskForm2

{

    class OnDataEventArgs : EventArgs

    {

        public DataTable dr;



        public OnDataEventArgs(DataTable ResTable)

        {

            dr = ResTable;

        }

    }



    class AsyncData

    {





        private DataTable DataResult;

//Asenkron olarak çalıştırılacak fonksiyonu tutacak delege



        public delegate DataTable GetAsyncData(string SQL);



//Worker fonksiyonun işi bittiğinde çalıştıracağı event ve delege

        public delegate void OnGetData(object sender, OnDataEventArgs e);

        public event OnGetData OnGetDataCall;



        public AsyncData()

        {

           //init

        }

//Asenkron çağrım için geliştirilmiş fonksiyon

        public void AsyncGetDataSet(GetAsyncData asyncdelegate, string SQL)

        {

            asyncdelegate.BeginInvoke(SQL, new AsyncCallback(AsyncGetDataSetCallBack), asyncdelegate);

        }

//Geri dönüş fonksiyonu

        private void AsyncGetDataSetCallBack(IAsyncResult ar)

        {

            GetAsyncData ret = (GetAsyncData)ar.AsyncState;

            DataResult = ret.EndInvoke(ar);

            //Event Fırlatılıyor

            OnGetDataCall(this,new OnDataEventArgs(DataResult));

        }





//Worker Fonksiyon Asynchronous Processing=true dikkat edin



        public DataTable GetDataSet(string SQL)

        {

            SqlConnection con = new SqlConnection("Data Source=(localdb)\\Projects;Initial Catalog=MyAdventureWorks;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;Asynchronous Processing=true");

            SqlDataAdapter da = new SqlDataAdapter(SQL, con);

            DataSet ds = new DataSet();

            da.Fill(ds);

            return ds.Tables[0];

        }

    }

}





Form1.cs

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;



namespace TaskForm2

{

    public partial class Form1 : Form

    {

        private AsyncData asyncdata;



        public Form1()

        {

            InitializeComponent();

            asyncdata = new AsyncData();

        }



        private void Form1_Load(object sender, EventArgs e)

        {

            AsyncData asyncdata = new AsyncData();

            asyncdata.OnGetDataCall += asyncdata_OnGetDataCall;

            AsyncData.GetAsyncData asyncdel = new AsyncData.GetAsyncData(asyncdata.GetDataSet);

            asyncdata.AsyncGetDataSet(asyncdel,"Select * From Person.Person");

            asyncdata.AsyncGetDataSet(asyncdel, "select * from production.product");



  //Normal

            //dataGridView1.DataSource = asyncdata.GetDataSet("Select * From Person.Person");

            //dataGridView1.DataSource = asyncdata.GetDataSet("select * from production.product");

        }







        void asyncdata_OnGetDataCall(object sender, OnDataEventArgs e)

        {

            //thread safe hale getirin

            //dataGridView1.Invoke((Action)(() => dataGridView1.DataSource = e.dr));

            //veya

            //dataGridView1.Invoke((MethodInvoker)delegate() { dataGridView1.DataSource = e.dr; });

            //veya

            dataGridView1.Invoke((Action)delegate() { dataGridView1.DataSource = e.dr; });

        }

    }

}

21 Kasım 2013 Perşembe

Microsoft Solver Foundation ve Optimizasyon


Çoğumuz eğitim yaşantımız boyunca matematik, trigonometri, numerik analiz vb dersler gördük. Dersin sizi en sıkan yerinde içinizden geçen şu kelimelerdi değil mi ? "Ne anlamsız bir ders, iyi de biz bunu nerede kullanacağız". Belki durum diğerleri için böyle ama bu yazıyı okuyorsanız muhtemelen sizin için değil. Günler, aylar, yıllar geçer ve o kişi bir yerinden yazılım işine bulaşır ve insanların işlerini otomatize etmek için çalışır. İşler market, muhtar, fatura, belediye takip programı geliştirirken gayet güzeldir. Taki belirli girdilerle çalışan bir sistemin en az(minumum) kaynaklarını kullanarak en fazla(maximum) çıktı üretmek için çalışan bir yapıyla karşılaşıncaya kadar.

Bu durumun adı Optimizasyondur.
Optimizasyon, elimizdeki kaynakları en verimli şekilde kullanarak en iyi sonuca ulaşmak olarak tanımlanabilir.

Yani (Wikipedia) Matematikte matematiksel programlama ya da optimizasyon terimi; bir gerçel fonksiyonu minimize ya da maksimize etmek amacı ile gerçek ya da tamsayı değerlerini tanımlı bir aralıkta seçip fonksiyona yerleştirerek sistematik olarak bir problemi incelemek ya da çözmek işlemlerini ifade eder.
Bir kaç durum senaryosu örnek vermek gerekirse;
  • Yatırım maliyeti, kapasitesi, ürünlerinin birim başına karlılığı belirli bir şirketin üretiminden en fazla karı elde etmesi için hangi miktarda ne üretmesi gerektiği durumu.(Profit Optimization) 
  • Kargo taşımacılığı yapan bir firmanın yasal taşıma sınırlarını aşmadan en hızlı ve en fazla karlılıkla hangi malları taşıması gerektiği durumu.(Transportation-Logistics Optimization) 
  • Ahşap, Pvc veya Cam kesecek bir makinaya sahip olan bir işletmenin elindeki tabakalardan istediği kesim ölçülerinin en az fireyle kesilmesi (Cutting stock)

Bu gibi durumda girdilerin ne olduğu (Decisions, Parameters)hangi şartlar dahilinde çalışılacağı (Constraints) sonuçta ne istendiği çok önemlidir (Goals).

Evet, bundan sonra sorun artık çözülmesi gereken bir matematiksel problemdir. Peki bu problemi nasıl çözeceğiz sorusunu yanıtı ise karşılaştığınız soruna özgü veya benzer ücretsiz veya ücretli algoritmaları bulmanız olası.

Bu algoritmaları kullanabileceğiniz gibi diğer taraftan imdadınıza yetişen matematiksel modelinizi belirli bir sytaxta hazırlayıp (Optimization Modeling Language (OML) gibi) çözüme ulaştıran "solver" lar mevcut. Solverlardan farklı platformda çalışanlar yine ücretli ve ücretsiz olanlar mevcut. Çoğu cross platformu destekliyor hatta birbirleri ile ortak konuşma dilleri de var. Cplex ve gurobiyi de bir inceleyin derim.

Benim makaleme konu olan ise Microsoft Solver Foundation.



Microsoft Solver Foundation Nedir ?

Gerçek optimizasyon modellerini hızlı ve kolay bir şekilde modellemek ve çözmek için kullanılan bir kütüphane. Bu belirlemeyi yaparken Optimization Modeling Language (OML) olarak adlandırılan bir dil kullanıyor. Bu işlemleri yaparken herhangi bir .NET dili kullanabileceğiniz bu kütüphane diğer popüler solverler(çözücü) ile entegre olabiliyor. Yine geliştirilen pluginler ile Excel, SharePoint gibi uygulamalara entegre olabiliyor.

İndirmek için
http://msdn.microsoft.com/en-us/devlabs/hh145003.aspx
http://msdn.microsoft.com/en-us/library/ff524509(v=vs.93).aspx

Sözü fazla uzatmadan bir örnek yaparak pratiğe dökelim.

Soru: bir fabrika 3 farklı ürün üretmektedir. 3 ürünün de maliyet, kar ve stoklama kapasitesi bellidir. Buna göre 5000 TL bir bütçeyle en fazla kar sağlayacak üretim yapmamız için hangi üründen ne kadar üretmeliyiz ?

 class Urun
    {
        public string Ad;
        public int Maliyet;
        public int Satis;
        public int MaksimumStok;

        public int Kar
        {
            get { return Satis - Maliyet; }
        }
    }


 class Program

    {
        static void Main(string[] args)

        {

            //En fazla 5000 TL üretim yapabiliriz. 

            int UretimButce = 5000;

            //Örnek basit ve anlaşılır olsun diye collection kullanılmadı.

            //İstenilirse collection türünden nesne kabul eden versiyonlarıda var 

            //Urunlerimiz : Decision

            Urun A_Urun = new Urun { Ad = "A_Ürünü", Maliyet = 5, Satis = 8, MaksimumStok = 1350 };

            Urun B_Urun = new Urun { Ad = "B_Ürünü", Maliyet = 8, Satis = 13, MaksimumStok = 875 };

            Urun C_Urun = new Urun { Ad = "C_Ürünü", Maliyet = 3, Satis = 5, MaksimumStok = 1100 };

            Decision DecisionA = new Decision(Domain.IntegerNonnegative, A_Urun.Ad);

            Decision DecisionB = new Decision(Domain.IntegerNonnegative, B_Urun.Ad);

            Decision DecisionC = new Decision(Domain.IntegerNonnegative, C_Urun.Ad);

            // Çözücü

            var solver = SolverContext.GetContext();


            //Model Tanımı Decision + Constraint

            var model = solver.CreateModel();

            model.AddDecision(DecisionA);

            model.AddDecision(DecisionB);

            model.AddDecision(DecisionC);


            //Kısıtlamalar, Şartlar

            model.AddConstraint("Butce_Kisitlamasi",

                           A_Urun.Maliyet * DecisionA +

                           B_Urun.Maliyet * DecisionB +

                           C_Urun.Maliyet * DecisionC <= UretimButce);

            //Ürettiğimiz ürünlerin toplam maliyeti üretim bütcemizden kücük veya eşit olmalı



            model.AddConstraint("A_Urunu_Stoklama_Kapasitemiz", DecisionA < A_Urun.MaksimumStok);

            model.AddConstraint("B_Urunu_Stoklama_Kapasitemiz", DecisionB < B_Urun.MaksimumStok);

            model.AddConstraint("C_Urunu_Stoklama_Kapasitemiz", DecisionC < C_Urun.MaksimumStok);

            //Üreteceğimiz ürünler depomuza sığmalı



            //Girdiler tanımlandı.

            //Şimdi sonuç olarak ne istediğimizi tanımlayalım

            //Üreteceğimiz ürünlerin karlığının en fazla olduğu optimizasyonu istiyoruz

            model.AddGoal("En_iyi_uretim_stok", GoalKind.Maximize,

            (A_Urun.Kar * DecisionA) +

            (B_Urun.Kar * DecisionB) +

            (C_Urun.Kar * DecisionC));


            Stopwatch sw = new Stopwatch();

            sw.Start();

            Console.WriteLine("Lütfen Bekleyiniz");


            // Çöz

            Solution solution = solver.Solve();


            // Get our decisions

            Console.WriteLine("Çözüm Kalitesi : " + solution.Quality.ToString());

            Console.WriteLine("A Ürününden {0} adet ", DecisionA);

            Console.WriteLine("B Ürününden {0} adet ", DecisionB);

            Console.WriteLine("C Ürününden {0} adet ", DecisionC);


            double gerceklesen_toplam_maliyet =

            DecisionA.ToDouble() * A_Urun.Maliyet +

            DecisionB.ToDouble() * B_Urun.Maliyet +

            DecisionC.ToDouble() * C_Urun.Maliyet;
            double toplam_satis_fiyat =

            DecisionA.ToDouble() * A_Urun.Satis +

            DecisionB.ToDouble() * B_Urun.Satis +

            DecisionC.ToDouble() * C_Urun.Satis;


            Console.WriteLine("Üretim: Harcanan : {0} Planlanan: {1}", gerceklesen_toplam_maliyet, UretimButce);

            Console.WriteLine("Satış Değeri : {0} Kar: {1}", toplam_satis_fiyat, toplam_satis_fiyat - gerceklesen_toplam_maliyet);

            Console.WriteLine("Optimizasyon {0} milisaniyede tamamlandı" , sw.ElapsedMilliseconds);

            Console.ReadLine();


        }

    }

Peki bu tarz optimizasyon hesapları enterprise projlerde nasıl kullanılabilir sorusunun zihninizde canlandığını düşünerek cevap vermek gerekirse;
ERP projelerinde üretim maliyetlerini minimize etmek adına kaynaklardan ham madde, depolama, iş gücü hesaplamalarında, üretim çizelgeleme ve planlanmasında.
MRP projelerinde üretim - stok miktarlarını optimum tutmakta.
Navigasyon uygulamalarında en kısa , en hızlı route hesaplamalarında.
Gemicilik - Logistik sektöründe yine route planının yapılıp, yükün yükleneceği ve indirileceği yere göre araç içindeki en ideal yere yüklenmesi.
Call Center uygulamalarında otomatik çağrı başlatılması ve dağıtımı senaryosunda kestirimde bulunurken. 
Yani neredeyse sınırsız kullanım alanı var. Kütüphaneyi yapanlar oldukça zengin örnekler hazırlamışlar. 


İlgimi çeken hisse senedi portföy yönetimi ile ilgili bir örneğin ekran görüntüsü. Bu kadar karmaşık ve yoğun bir algoritmanın çok kolay modellenip hesaplandığını görünce şaşırmamak elde değil.


Google' da biraz araştırma yaptığımda bu kütüphaneyi kullanarak Einstein Puzzle olarak bilinen zebra bulmacasını, sudoku bulmacaları çözen eğlenceli örnekler var. 

Sonuç olarak Microsoft Solver Foundation probleminizi belirleyip modelledikten sonra işinizi oldukça kolaylaştıracak bir kütüphane. Örnekte kod içerisindeki açıklamalarda mümkün olduğu kadar açıklama yapmaya çalıştım. 
Size tavsiyem kütüphaneye ait örnekleri de mutlaka inceleyin. Bundan sonraki makalelerde bilindik optimizasyon türlerini modelleyip çözmeye çalışacağım. 

Görüşmek üzere...

23 Ekim 2012 Salı

C# ile OPC Bağlantısı ve Uygulama Geliştirmek

Bir önceki yazıda Opc Server kurulumu ve test için birkaç değişken eklemeyi gördük.
Şimdi bir C# projesi oluşturup bu değişkenleri okuyup yazma işlemi yapacağız.

İlk önce OPC apilierini referanlara ekleyelim.


Aşağıdaki kodu adm adım inceleyelim.


  Opc.Da.Server server = null;

        OpcCom.Factory fact = new OpcCom.Factory();

        Opc.Da.Item[] items;

        Opc.Da.Subscription group;

        Opc.IRequest req;

        Opc.Da.WriteCompleteEventHandler WriteEventHandler;

        Opc.Da.ReadCompleteEventHandler ReadEventHandler;


//Networkteki OPC serverların listesin getiren fonksiyon



private void GetOpcServers()

        {

            try

            {

                OpcCom.ServerEnumerator se = new OpcCom.ServerEnumerator();



                Opc.Server[] servers = se.GetAvailableServers(Opc.Specification.COM_DA_20);



                ListServers(servers);

            }

            catch (Exception)

            {

                throw;

            }

        }



//OPC Server connection stringlerini hazırlayan fonksiyon



private void ListServers(Opc.Server[] OpsServerList)

        {

            trwServers.Nodes.Clear();

            lstUrlList.Items.Clear();

            foreach (Opc.Server serv in OpsServerList)

            {

                TreeNode trn = new TreeNode(serv.Name);

                trn.Nodes.Add(serv.Url.HostName + " : " + serv.Url.Path + " : " + serv.Url.Port);

                trn.Nodes.Add(serv.Url.ToString());

                trn.Nodes.Add(serv.IsConnected.ToString());

                trwServers.Nodes.Add(trn);

                lstUrlList.Items.Add(serv.Url.ToString());

            }

        }


Aşağıda bağlanabileceğimiz OPC server listeleri ve bağlantı stringleri gözükmektedir.



        private bool ConnectOPCServer(string OpcUrl)

        {

            // Create a server object and connect to the TwinCATOpcServer

            Opc.URL url = new Opc.URL(OpcUrl);

          

            server = new Opc.Da.Server(fact, null);



            try

            {

                server.Connect(url, new Opc.ConnectData(new System.Net.NetworkCredential()));

            }

            catch (Exception Ex)

            {

                MessageBox.Show(Ex.Message);

                return false;

            }



            // Okuma Grubu

            Opc.Da.SubscriptionState groupState = new Opc.Da.SubscriptionState();

            groupState.Name = "Group1";

            groupState.Active = true;





            group = (Opc.Da.Subscription)server.CreateSubscription(groupState);

            group.DataChanged += new Opc.Da.DataChangedEventHandler(group_DataChanged);





            // Gruba 3 adet OPC değişkeni ekle

            items = new Opc.Da.Item[3];

            items[0] = new Opc.Da.Item();

            items[0].ItemName = "Bucket Brigade.Int1";

            items[1] = new Opc.Da.Item();

            items[1].ItemName = "Bucket Brigade.Int2";

            items[2] = new Opc.Da.Item();

            items[2].ItemName = "Bucket Brigade.Int3";

            items = group.AddItems(items);



            //Write Callback fonksiyonumuzu tutacak handler

            WriteEventHandler = new Opc.Da.WriteCompleteEventHandler(WriteCompleteCallback);

             //Read Callback fonksiyonumuzu tutacak handler

            ReadEventHandler = new Opc.Da.ReadCompleteEventHandler(ReadCompleteCallback);



            return true;

        }



        void group_DataChanged(object subscriptionHandle, object requestHandle, Opc.Da.ItemValueResult[] values)

        {

            foreach (Opc.Da.ItemValueResult chitem in values)

            {

                WriteLogList(chitem.ItemName + " : " +

                                chitem.ItemPath + " : " +

                                chitem.Key + " : " +

                                chitem.Value);

            }

        }





        void WriteLogList(string item)

        {

            lstLog.BeginInvoke((MethodInvoker)delegate

            {

                lstLog.Items.Insert(0, item);

            });

        }



        void WriteCompleteCallback(object clientHandle, Opc.IdentifiedResult[] results)

        {



            WriteLogList("Write completed");

            foreach (Opc.IdentifiedResult writeResult in results)

            {

                WriteLogList(writeResult.ItemName + " : " + writeResult.ResultID);

            }



        }



        void ReadCompleteCallback(object clientHandle, Opc.Da.ItemValueResult[] results)

        {

            WriteLogList("Read completed");

            foreach (Opc.Da.ItemValueResult readResult in results)

            {

                WriteLogList(readResult.ItemName + " : " + readResult.Value);

            }

            Console.WriteLine();

        }



        private void Form1_Load(object sender, EventArgs e)

        {

            GetOpcServers(); 

        }



      



        private void button4_Click(object sender, EventArgs e)

        {

            if (server.IsConnected)

            {

                MessageBox.Show("connected");

            }

        }



        private void btnConnect_Click(object sender, EventArgs e)

        {

            if ((server != null) && (server.IsConnected))

                server.Disconnect();



            if (lstUrlList.SelectedItems.Count != 0)

                ConnectOPCServer(lstUrlList.SelectedItem.ToString());

        }



        private void btnWrite_Click(object sender, EventArgs e)

        {

            Opc.Da.ItemValue[] iv = new Opc.Da.ItemValue[group.Items.Count()];

            Random rnd = new Random();





            for (int i = 0; i < group.Items.Count(); i++)

            {

                Opc.Da.ItemValue iiv = new Opc.Da.ItemValue(group.Items[i].ItemName);

                iiv.ItemPath = group.Items[i].ItemPath;

                iiv.ServerHandle = group.Items[i].ServerHandle;

                iiv.Value = rnd.Next(1,1000);

                iv[i] = iiv;

            }



            //group.Write(iv);

            //Asenkron

            group.Write(iv, 1234, WriteCompleteCallback, out req);

        }



        private void btnRead_Click(object sender, EventArgs e)

        {

            //group.Read(group.Items);

            //and now read the items again

            group.Read(group.Items, 123, ReadCompleteCallback, out req);

        }



Örnek programı indirmek için

21 Ekim 2012 Pazar

OPC (OLE for process control) Nedir 2 ?



Opc haberleşmesi kaynak cihazın Opc Servera bağlanması ile başlamaktadır.
Bu bağlantı farklı Modbus, PLC-5, Melsec-Q, ProfiBus ..vb gibi protokollerle gerçekleştirilir.
Opc Serverlar üreticinin geliştirdiği yazılımlar olabileceği gibi üçüncü parti bir yazılımda olabilir. Opc Servera bağlanıp hizmet alan her noktaya Opc client adı verilir.

Opc server ile denemeler yapmak için bir plc ye ihtiyacınız yok. Bu iş için denemelerinizi yapabileceğiniz Opc Server Simulatörler mevcut.

Benim örneklerimde kullandığımı indirmek için tıklayınız.

OPC.NET20 Api
OPC Client Program

İlk adım olarak OPC Simulatör kurulumunu gerçekleştirmelisiniz. Kurulum gerçekleştikten sonra opc server exploreri açıp aşağıdaki tanımlamaları yapmalısınız.




Çalışan Opc Serverların sol menüde gözükmesi gerekli. Bağlanmak istediğimizi seçiyoruz.
Connect düğmesine tıklıyoruz.



Opc Server üzerinde değişkenler Gruplanarak tutulurlar.
Bu yüzden bir adet grup ekleyip altına değişkenler tanımlamanız gerekli.



Grubun altına add items şeçeneğini seçerek istediğimiz test değişkenlerini ekleyebiliriz.
Simulation items altından sabit ve random değişkenler ekleyebilirsiniz.



Eklediğiniz sabit değişkenlere istediğiniz değerleri yazabilirsiniz.



Eklediğiniz sabit değerlere belirli zaman aralıklarında sürekli artan değerler atabilirsiniz.



Herhangi bir Opc Client ile bağlanmak istediğimiz opc serveri seçmelisiniz.



Az önce eklediğiniz grup adının aynısını buraya eklemelisiniz.



Grubun okunma zamanı ... gibi ayarlar seçilir.



Yine ilk server ekranından eklediğimiz tipte ve aynı isimde değişkenleri ekliyoruz. Değişkenlerin ekranda son değerleri ile gözükmesi gerekli.


Şimdilik bu kadar bir sonraki yazımız uygulama geliştirme ile ilgili olacak..

18 Ekim 2012 Perşembe

OPC (OLE for process control) Nedir 1 ?

OPC günün birinde endüstriyel otomasyonların birbirleriyle veya dış dünyayla haberleşmesi ihtiyacı doğrultusunda doğmuş bir standarttır.

Cihaz üreticilerinin desteğiyle ilk sürümü 1996 yılında yayınlanmıştır. Takibinde OPC Foundation adında başı çeken üreticiler tarafından endüstriyel bir topluluk kurulmuş ve standartlar ve çalışmalar artık bu konsorsiyum tarafından yürütülmektedir.

OPC endüstriyel cihazlara ortak bir platformda haberleşme imkanı sunmaktadır. OPC Farklı marka PLClerin( Programlanabilir Mantıksal Denetleyici - Programmable Logic Controller) birbirleriyle veya dış ortamdaki tüm uygulamalarla haberleşmesini sağlayabilir.

Cümleyi örneklemek gerekirse bir fabrikadaki Siemens kontrol sistemiyle gerçekleştirilmiş bir gıda üretim bandının Panasonic kontrol sistemiyle geliştirilmiş bir soğutma sistemiyle paralel ve gerçek zamanlı haberleşip çalışmasını gösterebiliriz. Keza yine bu sistemin alarmlarının, olaylarının, ölçümlerinin, kontrollerinin yapıldığı uygulamalardan tutunda anlık veya saatlik üretim miktarlarının ERP veritabanlarına aktarımı gibi çözümler OPC yardımıyla çözülmektedir.

Bundan sonraki yazımızda OPC ile uygulama geliştirmek için simulatorden bahsedip örnekler yapacağım...
Devam....

19 Eylül 2012 Çarşamba

Cross Platform Bazen Hayat Kurtarır

Lazarustan daha önceki yazılarımda biraz bahsetmiştim. Hatta WinCE üzerinde çalışan bir klavye tuş yakalama örneği eklemiştim. Geçen süre içerisinde aynı çözümü Win32 sistemlerde ihtiyacım oldu. Lazarusla kısa bir çalışma sonunda hem CE için hemde Win32 sistemler için uygulamayı bitirdim.





unit Unit1; 
{$mode objfpc}{$H+}
interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
ComCtrls, ExtCtrls, Sockets,Windows,IniFiles, types;
type
{ TFrmMain }
TFrmMain = class(TForm)
btnClose: TButton;
btnClear: TButton;
btnMin: TButton;
btnOpen: TButton;
btnSaveIni: TButton;
btnWriteDefault: TButton;
edtPort: TEdit;
edtMacID: TEdit;
lblIp: TEdit;
edtIP: TEdit;
lblIp1: TEdit;
lblIp2: TEdit;
lblIp3: TEdit;
edtBarcodeStart: TEdit;
memData: TMemo;
memKey: TMemo;
memError: TMemo;
pageMain: TPageControl;
Panel1: TPanel;
Panel2: TPanel;
tbSettings: TTabSheet;
tbDebug: TTabSheet;
tmrHide: TTimer;

procedure btnClearClick(Sender: TObject);
procedure btnOpenClick(Sender: TObject);
procedure btnCloseClick(Sender: TObject);
procedure btnMinClick(Sender: TObject);
procedure btnSaveIniClick(Sender: TObject);
procedure btnWriteDefaultClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure lblIp3DblClick(Sender: TObject);
procedure tmrHideTimer(Sender: TObject);

private
{ private declarations }
function SendData(Data:String):Boolean;
function LoadIniFiles():Boolean;
function WriteIniFile():Boolean;
procedure LogYaz(Data:String);

public
{ public declarations }
end;

type
PKBDLLHOOKSTRUC = ^KBDLLHOOKSTRUCT;
KBDLLHOOKSTRUCT = packed record
vkCode: DWORD;
scanCode: DWORD;
flags: DWORD;
time: DWORD;
dwExtraInfo: Pointer;
end;

type
HOOKPROC = function (_para1:longint; _para2:PtrInt; _para3:PtrInt):PtrInt;
//{$IFDEF winCE}
//{$ENDIF}
//{$IFDEF win32}
//{$ENDIF}

var
FrmMain: TFrmMain;
KBHook: Cardinal = 0;
srvip: String;
srvport: String;
startchr: String;
machid: String;

Barcode_Islem: Integer;
Barcode_Start_i: Integer;
Barcode_Data: String;
Barcode_Detect: Boolean;
ChrKeyPress: DWORD;
ChrKeyUp: DWORD;

const
{$IFDEF winCE}
//inifile = '\flash\Settings.ini';
inifile = '\Windows\Settings.ini';
WH_KEYBOARD_LL = 20;
{$ENDIF}
{$IFDEF win32}
inifile = 'C:\Settings.ini';
WH_KEYBOARD_LL = 13;
{$ENDIF}
HC_ACTION = 0;
GWL_EXSTYLE = -20;
WS_EX_TOOLWINDOW = $80;
{ ShowWindow }
SW_HIDE = 0;
SW_MAXIMIZE = 3;
SW_MINIMIZE = 6;
SW_NORMAL = 1;
SW_RESTORE = 9;
SW_SHOW = 5;
SW_SHOWDEFAULT = 10;
SW_SHOWMAXIMIZED = 3;
SW_SHOWMINIMIZED = 2;
SW_SHOWMINNOACTIVE = 7;
SW_SHOWNA = 8;
SW_SHOWNOACTIVATE = 4;
SW_SHOWNORMAL = 1;
WPF_RESTORETOMAXIMIZED = 2;
WPF_SETMINPOSITION = 1;

implementation

procedure ParseKeyboard(Key: DWORD);
begin
if FrmMain.tbDebug.TabVisible then
FrmMain.memKey.Lines.Insert(0,chr(Key));
case Barcode_Islem of
0: begin
Barcode_Start_i:= 1;
if chr(Key) = startchr[1] then begin
Barcode_Start_i:= 2;
Barcode_Islem:= 1;
Barcode_Data:= chr(Key);
Barcode_Detect:= True;
end;
end;
1: begin
if (Barcode_Start_i <= Length(startchr)) then begin
if chr(Key) = startchr[Barcode_Start_i] then begin
Barcode_Start_i:= Barcode_Start_i + 1;
Barcode_Data:= Barcode_Data + chr(Key);
Barcode_Islem:= 1;
end else begin
Barcode_Detect:= False;
Barcode_Islem:= 0;
end;
end else begin
Barcode_Data:= Barcode_Data + chr(Key);
Barcode_Islem:= 2;
end;
end;
2:begin
if Key = 13 then begin//enter
Barcode_Detect:= False;
Barcode_Islem:= 0;
if FrmMain.tbDebug.TabVisible then
FrmMain.memKey.Lines.Insert(0,Barcode_Data);
FrmMain.SendData('MACHID:' + machid + 'BRCD:'+ Barcode_Data+ '@');
end else begin
Barcode_Data:= Barcode_Data + chr(Key);
end;
end;
end;
////
end;

procedure MemWrite(Data:String);
begin
FrmMain.memData.Lines.Insert(0,Data);
end;

procedure ParseCode(pkh: KBDLLHOOKSTRUCT);
begin
if FrmMain.tbDebug.TabVisible then
MemWrite(chr(pkh.vkCode)+':'+IntToStr(pkh.vkCode)+'-'+inttostr(pkh.scanCode)+'-'+inttostr(pkh.flags)+'-'+inttostr(pkh.time));

if pkh.vkCode = 36 then
ShowWindow(FrmMain.Handle,SW_NORMAL);

//harf aralarında "?" geliyor ne alaka
if (((pkh.vkCode > 31)and(pkh.vkCode<127))or(pkh.vkCode = 13)) then begin
//Tuş Yakalama
if ChrKeyPress = 0 then
ChrKeyPress:= pkh.vkCode
else if ((ChrKeyPress <> 0) and (ChrKeyUp = 0)) then
ChrKeyUp:=pkh.vkCode;

//Tuş Kontrol
if ((ChrKeyPress <> 0) and (ChrKeyUp <> 0)) then begin
if ChrKeyPress = ChrKeyUp then
ParseKeyboard(ChrKeyUp);
ChrKeyPress:= 0;
ChrKeyUp:= 0;
end;
end;
end;

{$IFDEF winCE}
function TaskKeyHookLL(nCode: LongInt;
wp: LongWord; lp:LongInt): LongInt; cdecl;
var
ppkh: KBDLLHOOKSTRUCT;
key: WORD;
begin
ppkh:= PKBDLLHOOKSTRUC(lp)^;
if nCode = HC_ACTION then
ParseCode(ppkh);
Result:= CallNextHookEx(KBHook, nCode, wp, lp);
end;
{$ENDIF}


{$IFDEF win32}
function TaskKeyHookLL(nCode: LongInt;
wp: LongInt; lp:LongInt): LongInt; stdcall;
var
ppkh: KBDLLHOOKSTRUCT;
key: WORD;
begin
ppkh:= PKBDLLHOOKSTRUC(lp)^;
if nCode = HC_ACTION then
ParseCode(ppkh);
Result:= CallNextHookEx(KBHook, nCode, wp, lp);
end;
{$ENDIF}

function KeyboardHook(ADisable: Boolean): Boolean;
begin
if ADisable then
begin
if KBHook = 0 then
KBHook:= SetWindowsHookEx(WH_KEYBOARD_LL,
@TaskKeyHookLL, HInstance, 0);
end else
if KBHook <> 0 then
begin
UnhookWindowsHookEx(KBHook);
KBHook:= 0;
end;
Result:= KBHook <> 0;
end;


{ TFrmMain }
procedure TFrmMain.btnOpenClick(Sender: TObject);
begin
if KeyboardHook(True) then
LogYaz('System Hooked')
else
LogYaz('System Not Hooked');
end;

procedure TFrmMain.btnClearClick(Sender: TObject);
begin
memData.Clear;
memKey.Clear;
end;

procedure TFrmMain.btnCloseClick(Sender: TObject);
begin
KeyboardHook(False);
end;

procedure TFrmMain.btnMinClick(Sender: TObject);
begin
//FrmMain.WindowState:= wsMinimized;
ShowWindow(FrmMain.Handle,SW_HIDE);
end;

procedure TFrmMain.btnSaveIniClick(Sender: TObject);
begin
WriteIniFile();
end;

procedure TFrmMain.btnWriteDefaultClick(Sender: TObject);
var
MyFile: TIniFile;
begin
MyFile := TIniFile.Create(inifile);
try
MyFile.WriteString('Program', 'IP','192.168.100.1');
MyFile.WriteString('Program', 'PORT','509');
MyFile.WriteString('Program', 'MACID','XXX');
MyFile.WriteString('Program', 'BARCODESTART','K1');
finally
MyFile.Free;
end;
end;

procedure TFrmMain.FormCreate(Sender: TObject);
begin
pageMain.ActivePage:= tbSettings;
pageMain.Pages[1].TabVisible:= false;
LoadIniFiles();
if not KeyboardHook(True) then
LogYaz('Err: System Not Hooked');
Barcode_Islem := 0;
Barcode_Data:= '';
Barcode_Detect:= False;
ChrKeyPress:= 0;
ChrKeyUp:= 0;
end;

procedure TFrmMain.FormShow(Sender: TObject);
begin
tmrHide.Enabled:= True;
end;

procedure TFrmMain.lblIp3DblClick(Sender: TObject);
begin
pageMain.Pages[1].TabVisible:= not pageMain.Pages[1].TabVisible;
end;

procedure TFrmMain.tmrHideTimer(Sender: TObject);
begin
ShowWindow(FrmMain.Handle,SW_HIDE);
tmrHide.Enabled:= false;
end;

function TFrmMain.SendData(Data: String): Boolean;
var
adr : TInetSockAddr;
soc : Tsocket;
buf : String[255];
Sin,Sout : Text;
begin

soc := fpsocket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if soc=-1 then begin
LogYaz('Socket hatası');
exit;
end;

adr.sin_family := AF_INET;
adr.sin_port := htons(StrToInt(srvport));
if srvip='' then
adr.sin_addr := StrToNetAddr('127.0.0.1')
else
adr.sin_addr := StrToNetAddr(srvip);

if not Connect (soc,adr,Sin,Sout) then
begin
LogYaz('Bağlantı hatası : '+NetAddrToStr(adr.sin_addr));
exit;
end;

buf := Data;

fpsend(soc,@buf,length(buf)+1,0);//gönderim

fpshutdown(soc,0); // kapat
CloseSocket(soc);
end;


function TFrmMain.LoadIniFiles(): Boolean;
var
MyFile: TIniFile;
begin
MyFile := TIniFile.Create(inifile);
try
srvip:= MyFile.ReadString('Program', 'IP','127.0.0.1');
edtIp.Text:= srvip;
srvport:= MyFile.ReadString('Program', 'PORT','509');
edtPort.Text:= srvport;
machid:= MyFile.ReadString('Program', 'MACID','xxxx');
edtMacID.Text:= machid;
startchr:= MyFile.ReadString('Program', 'BARCODESTART','K1');
edtBarcodeStart.Text:= startchr;
finally
MyFile.Free;
end;
end;


function TFrmMain.WriteIniFile(): Boolean;
var
MyFile: TIniFile;
begin
MyFile := TIniFile.Create(inifile);
try
MyFile.WriteString('Program', 'IP',edtIp.Text);
MyFile.WriteString('Program', 'PORT',edtPort.Text);
MyFile.WriteString('Program', 'MACID',edtMacID.Text);
MyFile.WriteString('Program', 'BARCODESTART',edtBarcodeStart.Text);
finally
MyFile.Free;
end;
end;


procedure TFrmMain.LogYaz(Data: String);
begin
memError.Lines.Insert(0,Data);
end;

{$R *.lfm}

end.



17 Ağustos 2012 Cuma

Windows CE Keyboard Hook (Win Ce Tuş Yakalama)



WinCe kullanan bir sistemde basılan tuşları yakalayıp belli bir formatta olanları soket üzerinden  gönderen bir uygulamaya ihtiyacım oldu. Kullanılan pc endüstriyel bir bilgisayardı ve oldukça kısıtılı ayarları olan bir bilgisayardı. İlk önce .ne compact framework ile bir uygulama geliştirmek istedim. Geliştirdiğim uygulama klavye hareketlerini yakaladı. Fakat seçim formdan ayrıldıktan sonra tuş yakala duruyor ve daha sonra çalışmıyordu. Bunun üzerine benzer bir örneği LAZARUS ile geliştirdim. 



unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ComCtrls, ExtCtrls, Sockets, IniFiles, types;

type

  { TFrmMain }

  TFrmMain = class(TForm)
    btnClose: TButton;
    btnMin: TButton;
    btnOpen: TButton;
    btnSaveIni: TButton;
    btnWriteDefault: TButton;
    edtPort: TEdit;
    edtMacID: TEdit;
    lblIp: TEdit;
    edtIP: TEdit;
    lblIp1: TEdit;
    lblIp2: TEdit;
    lblIp3: TEdit;
    edtBarcodeStart: TEdit;
    memData: TMemo;
    memKey: TMemo;
    memError: TMemo;
    pageMain: TPageControl;
    Panel1: TPanel;
    Panel2: TPanel;
    tbSettings: TTabSheet;
    tbDebug: TTabSheet;
    tmrHide: TTimer;
    procedure btnOpenClick(Sender: TObject);
    procedure btnCloseClick(Sender: TObject);
    procedure btnMinClick(Sender: TObject);
    procedure btnSaveIniClick(Sender: TObject);
    procedure btnWriteDefaultClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure lblIp3DblClick(Sender: TObject);
    procedure tmrHideTimer(Sender: TObject);
  private
    { private declarations }
    function SendData(Data:String):Boolean;
    function LoadIniFiles():Boolean;
    function WriteIniFile():Boolean;
    procedure LogYaz(Data:String);
  public
    { public declarations }
  end;

  type
  PKBDLLHOOKSTRUC = ^KBDLLHOOKSTRUCT;
  KBDLLHOOKSTRUCT = packed record
    vkCode: DWORD;
    scanCode: DWORD;
    flags: DWORD;
    time: DWORD;
    dwExtraInfo: Pointer;
  end;

  type
  HOOKPROC = function (_para1:longint; _para2:PtrInt; _para3:PtrInt):PtrInt;

  {$include F:\lazarus\fpc\2.6.0\source\rtl\wince\wininc\coredll.inc}
  {$include F:\lazarus\fpc\2.6.0\source\rtl\wince\wininc\base.inc}
  {$include F:\lazarus\fpc\2.6.0\source\rtl\wince\wininc\defines.inc}
  function CallNextHookEx(hhk:THandle; nCode:longint; wParam:PtrInt; lParam:PtrInt):PtrInt;  external 'coredll.dll' name 'CallNextHookEx';
  //function CallNextHookEx(hhk:HHOOK; nCode:longint; wParam:WPARAM; lParam:LPARAM):LRESULT; external KernelDLL name 'CallNextHookEx';
  function SetWindowsHookEx(idHook:longint; lpfn:HOOKPROC; hmod:THandle; dwThreadId:DWORD):THandle; external 'coredll.dll'  name 'SetWindowsHookExW';
  //function SetWindowsHookEx(idHook:longint; lpfn:HOOKPROC; hmod:HINST; dwThreadId:DWORD):HHOOK; external KernelDLL name 'SetWindowsHookExW';
  function UnhookWindowsHookEx(hhk:THandle):LongBool; external 'coredll.dll' name 'UnhookWindowsHookEx';
  //function UnhookWindowsHookEx(hhk:HHOOK):WINBOOL; external 'user32' name 'UnhookWindowsHookEx';
  function SetWindowLong(hWnd:THandle; nIndex:longint; dwNewLong:longint):longint;  external 'coredll.dll' name 'SetWindowLongW';
  //function SetWindowLong(hWnd:HWND; nIndex:longint; dwNewLong:LONG):LONG; external KernelDLL name 'SetWindowLongW';
  function ShowWindow(hWnd:THandle; nCmdShow:longint):Boolean; external KernelDLL name 'ShowWindow';
  //function ShowWindow(hWnd:HWND; nCmdShow:longint):WINBOOL; external KernelDLL name 'ShowWindow';
var
  FrmMain: TFrmMain;
  KBHook: Cardinal = 0;
  srvip: String;
  srvport: String;
  startchr: String;
  machid: String;

  Barcode_Islem: Integer;
  Barcode_Start_i: Integer;
  Barcode_Data: String;
  Barcode_Detect: Boolean;
  ChrKeyPress: DWORD;
  ChrKeyUp: DWORD;

const
  inifile = '\flash\Settings.ini';
  WH_KEYBOARD_LL = 20;
  HC_ACTION = 0;
  GWL_EXSTYLE = -20;
  WS_EX_TOOLWINDOW = $80;
  { ShowWindow  }
     SW_HIDE = 0;
     SW_MAXIMIZE = 3;
     SW_MINIMIZE = 6;
     SW_NORMAL = 1;
     SW_RESTORE = 9;
     SW_SHOW = 5;
     SW_SHOWDEFAULT = 10;
     SW_SHOWMAXIMIZED = 3;
     SW_SHOWMINIMIZED = 2;
     SW_SHOWMINNOACTIVE = 7;
     SW_SHOWNA = 8;
     SW_SHOWNOACTIVATE = 4;
     SW_SHOWNORMAL = 1;
     WPF_RESTORETOMAXIMIZED = 2;
     WPF_SETMINPOSITION = 1;

implementation

procedure ParseKeyboard(Key: DWORD);
begin
     if FrmMain.tbDebug.TabVisible then
        FrmMain.memKey.Lines.Insert(0,chr(Key));

     case Barcode_Islem of
       0: begin
          Barcode_Start_i:= 1;
          if chr(Key) = startchr[1] then begin
             Barcode_Start_i:= 2;
             Barcode_Islem:= 1;
             Barcode_Data:= chr(Key);
             Barcode_Detect:= True;
          end;
       end;
       1: begin
          if (Barcode_Start_i <= Length(startchr)) then begin
             if chr(Key) = startchr[Barcode_Start_i] then begin
                 Barcode_Start_i:= Barcode_Start_i + 1;
                 Barcode_Data:= Barcode_Data + chr(Key);
                 Barcode_Islem:= 1;
             end else begin
                 Barcode_Detect:= False;
                 Barcode_Islem:= 0;
             end;
          end else begin
              Barcode_Data:= Barcode_Data + chr(Key);
              Barcode_Islem:= 2;
          end;
       end;
       2:begin
              if Key = 13 then begin//enter
                 Barcode_Detect:= False;
                 Barcode_Islem:= 0;
                 if FrmMain.tbDebug.TabVisible then
                    FrmMain.memKey.Lines.Insert(0,Barcode_Data);
                 FrmMain.SendData('MACHID:' + machid + 'BRCD:'+ Barcode_Data+ '@');
              end else begin
                  Barcode_Data:= Barcode_Data + chr(Key);
              end;
       end;
     end;
  ////
end;


procedure MemWrite(Data:String);
begin
  FrmMain.memData.Lines.Insert(0,Data);
end;

function TaskKeyHookLL(nCode: Integer;
  wp: PtrInt; lp:PtrInt): PtrInt; stdcall;
var
  pkh: KBDLLHOOKSTRUCT;
  key: WORD;
begin
  pkh:= PKBDLLHOOKSTRUC(lp)^;
  if nCode = HC_ACTION then
  begin
       if FrmMain.tbDebug.TabVisible then
          MemWrite(chr(pkh.vkCode)+':'+IntToStr(pkh.vkCode)+'-'+inttostr(pkh.scanCode)+'-'+inttostr(pkh.flags)+'-'+inttostr(pkh.time));
       if pkh.vkCode = 36 then
           ShowWindow(FrmMain.Handle,SW_NORMAL);

       if ((pkh.vkCode > 31)or(pkh.vkCode = 13)) then begin

          //Tuş Yakalama
          if  ChrKeyPress = 0 then
              ChrKeyPress:= pkh.vkCode
          else if  ((ChrKeyPress <> 0) and (ChrKeyUp = 0)) then
               ChrKeyUp:=pkh.vkCode;

          //Tuş Kontrol
          if  ((ChrKeyPress <> 0) and (ChrKeyUp <> 0)) then begin
            if   ChrKeyPress = ChrKeyUp then
                 ParseKeyboard(ChrKeyUp);
            ChrKeyPress:= 0;
            ChrKeyUp:= 0;
          end;

       end;
  end;
  Result:= CallNextHookEx(KBHook, nCode, wp, lp);
end;

function KeyboardHook(ADisable: Boolean): Boolean;
begin
  if ADisable then
  begin
    if KBHook = 0 then
      KBHook:= SetWindowsHookEx(WH_KEYBOARD_LL,
            @TaskKeyHookLL, HInstance, 0);
  end else
    if KBHook <> 0 then
    begin
      UnhookWindowsHookEx(KBHook);
         KBHook:= 0;
    end;
  Result:= KBHook <> 0;
end;

{ TFrmMain }

procedure TFrmMain.btnOpenClick(Sender: TObject);
begin
 if KeyboardHook(True) then
    LogYaz('System Hooked')
 else
     LogYaz('System Not Hooked');
end;


procedure TFrmMain.btnCloseClick(Sender: TObject);
begin
  KeyboardHook(False);
end;

procedure TFrmMain.btnMinClick(Sender: TObject);
begin
  //FrmMain.WindowState:= wsMinimized;
 ShowWindow(FrmMain.Handle,SW_HIDE);
end;

procedure TFrmMain.btnSaveIniClick(Sender: TObject);
begin
  WriteIniFile();
end;

procedure TFrmMain.btnWriteDefaultClick(Sender: TObject);
var
  MyFile: TIniFile;
begin
  MyFile := TIniFile.Create(inifile);
  try
    MyFile.WriteString('Program', 'IP','192.168.100.1');
    MyFile.WriteString('Program', 'PORT','509');
    MyFile.WriteString('Program', 'MACID','');
    MyFile.WriteString('Program', 'BARCODESTART','K1');
  finally
    MyFile.Free;
  end;
end;


procedure TFrmMain.FormCreate(Sender: TObject);
begin
 pageMain.ActivePage:= tbSettings;
 pageMain.Pages[1].TabVisible:= false;
 LoadIniFiles();
   if not KeyboardHook(True) then
     LogYaz('Err: System Not Hooked');
  Barcode_Islem := 0;
  Barcode_Data:= '';
  Barcode_Detect:= False;
  ChrKeyPress:= 0;
  ChrKeyUp:= 0;
end;

procedure TFrmMain.FormShow(Sender: TObject);
begin
     tmrHide.Enabled:= True;
end;

procedure TFrmMain.lblIp3DblClick(Sender: TObject);
begin
  pageMain.Pages[1].TabVisible:= not pageMain.Pages[1].TabVisible;
end;


procedure TFrmMain.tmrHideTimer(Sender: TObject);
begin
     ShowWindow(FrmMain.Handle,SW_HIDE);
     tmrHide.Enabled:= false;
end;


function TFrmMain.SendData(Data: String): Boolean;
var
 adr : TInetSockAddr;
 soc : Tsocket;
 buf : String[255];
 Sin,Sout : Text;
begin

 soc := fpsocket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 if soc=-1 then begin
      LogYaz('Socket hatası');
      exit;
 end;

 adr.sin_family := AF_INET;
 adr.sin_port := htons(StrToInt(srvport));
 if srvip='' then
    adr.sin_addr := StrToNetAddr('127.0.0.1')
 else
     adr.sin_addr := StrToNetAddr(srvip);

 if not  Connect (soc,adr,Sin,Sout) then
 begin
   LogYaz('Bağlantı hatası : '+NetAddrToStr(adr.sin_addr));   //ip canlı değilse
   exit;
 end;

 buf := Data;

 fpsend(soc,@buf,length(buf)+1,0);//gönderim adımı

 fpshutdown(soc,0);                                 //bağlantıyı kapat
 CloseSocket(soc);
end;

function TFrmMain.LoadIniFiles(): Boolean;
var
  MyFile: TIniFile;
begin
  MyFile := TIniFile.Create(inifile);
  try
    srvip:= MyFile.ReadString('Program', 'IP','127.0.0.1');
    edtIp.Text:= srvip;
    srvport:= MyFile.ReadString('Program', 'PORT','509');
    edtPort.Text:= srvport;
    machid:= MyFile.ReadString('Program', 'MACID','');
    edtMacID.Text:= machid;
    startchr:= MyFile.ReadString('Program', 'BARCODESTART','K1');
    edtBarcodeStart.Text:= startchr;
  finally
    MyFile.Free;
  end;
end;

function TFrmMain.WriteIniFile(): Boolean;
var
  MyFile: TIniFile;
begin
  MyFile := TIniFile.Create(inifile);
  try
    MyFile.WriteString('Program', 'IP',edtIp.Text);
    MyFile.WriteString('Program', 'PORT',edtPort.Text);
    MyFile.WriteString('Program', 'MACID',edtMacID.Text);
    MyFile.WriteString('Program', 'BARCODESTART',edtBarcodeStart.Text);
  finally
    MyFile.Free;
  end;
end;

procedure TFrmMain.LogYaz(Data: String);
begin
  memError.Lines.Insert(0,Data);
end;



{$R *.lfm}

end.
                                                            

30 Temmuz 2012 Pazartesi

Lazarus WinCE Compiler Ayarları

Lazarusla WinCe işletim sistemi için hiçbir değişiklik yapmadan aşağıdaki gibi derleyici ayarlarını değiştirerek derlediğinizde uygulamanız hazır. Fakat uygulama boyutu 13 MB civarı. Wince uygulama geliştirmek için daha compact KOLCE komponenti bulunmakta isterseniz bunu da kullanabilirsiniz. 
Benim test ettiğim son uyumlu release aşağıda