\

Facebook


วันอังคารที่ 1 ตุลาคม พ.ศ. 2556

[WinForm C#] Basic Keyboard Reader

Almost of any software which have builded for user's comfortable have special shortcut keys, so today i would like to present easy WinForm keys reader.

In Winform c#, which interite from base Form of Windows.system also include reading key method. just create new project call "ReadKeyBoard" and add new main class call "Form1". Then, in properties tab click on Events button to reveal all form's event inside and double click on "KeyDown" event to active usage.


Let's see inside "Form1_KeyDown" method, it accepts two parameter which one is Object and another one is KeyEventArg e. So anytime you press Keyboard and take key up, program should automatically detect on "what key you press" and send it into method with e value. For example, i press "Backspace", i should get valuse as Keys.Back.

For combination keys such as CTRL + C, SHIFT + F4, you should get 2 values while taking inside this method. One modify key and one normal key, so make sure you have check for specific case. Just like combine Ctrl + C = copy :

if (e.Modifiers == Keys.Control && e.KeyCode == Keys.C)
            {
                // Do Copy stuff
            }

For normal key only :

 else  if (e.KeyCode == Keys.Space)
            {
                // Do your stuff
            }

Write other conditions as you want. i post the code example below. Have a nice day with less bug. Thank for interesting.


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 CombineKey
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Modifiers == Keys.Control && e.KeyCode == Keys.C)
            {
                textBox1.Text = "Control + C";
            }
            else if (e.KeyCode == Keys.Back)
            {
                textBox1.Text = "Back";
            }
            else  if (e.KeyCode == Keys.Space)
            {
                textBox1.Text = "Space Bar";
            }
            else if (e.KeyCode == Keys.F4)
            {
                textBox1.Text = "F4";
            }
            else if (e.KeyCode == Keys.Tab)
            {
                textBox1.Text = "Tab";
            }
            else
            {
                textBox1.Text = "None";
            }
        }
    }
}

วันอาทิตย์ที่ 29 กันยายน พ.ศ. 2556

[WinForm c#] Basic send E-mail with Google Sevice


In this tutorial, I gonna show you how to implement basic WinForm with sending E-mail function. Gmail provide you STM port for sending new e-mail to another mail inbox, so we need Gmail account to access though this example code.

First, you must regist GOOGLE MAIL account to use their mail server service. If you have own hosting mail server, just get the same configuration of server side to apply this tutorial.

Google normally use port 587 for send and recieve fresh e-mail, and you can also use Class SmtpClient, which from System.Net.Mail, to declare nesessery property before start sending method.

Create new project call "SendMail" and add new Form into solution, Add componets like sample images below. There are including textEdit controls, LabelEdit and button. Put into the same position and give them EventHandler . Into event simpleButton1_Click(), i should start tring send mail by get valus inside controls and put into MailMessage class and begin connection.

 
 
 
 Totally C# send mail method : 

MailMessage mail = new MailMessage();
                SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");

                mail.From = new MailAddress(textEdit1.Text);
                mail.To.Add(textEdit2.Text);
                mail.Subject = textEdit5.Text;
                mail.Body = memoEdit1.Text;

                SmtpServer.Port = 587;
                SmtpServer.Credentials = new System.Net.NetworkCredential(textEdit1.Text, textEdit3.Text);
                SmtpServer.EnableSsl = true;

                SmtpServer.Send(mail);
 
 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SendEmail
{
    public partial class mail : Form
    {
        public mail()
        {
            InitializeComponent();
        }

        private void simpleButton1_Click(object sender, EventArgs e)
        {
            if (!CheckEmperty())
            {
                MessageBox.Show("Plesae fill all blank input form");
                return;
            }
            try
            {
                MailMessage mail = new MailMessage();
                SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");

                mail.From = new MailAddress(textEdit1.Text);
                mail.To.Add(textEdit2.Text);
                mail.Subject = textEdit5.Text;
                mail.Body = memoEdit1.Text;

                SmtpServer.Port = 587;
                SmtpServer.Credentials = new System.Net.NetworkCredential(textEdit1.Text, textEdit3.Text);
                SmtpServer.EnableSsl = true;

                SmtpServer.Send(mail);

                labelControl4.Text = "success";
                labelControl4.Appearance.ForeColor = System.Drawing.Color.Green;
            }
            catch (Exception ex)
            {
                labelControl4.Text = "fail";
                labelControl4.Appearance.ForeColor = System.Drawing.Color.Red;
            }
        }
        private bool CheckEmperty()
        {
            if (textEdit2.Text.Equals(""))
            {
                return false;
            }
            else if(textEdit1.Text.Equals(""))
            {
                return false;
            }
            else if (textEdit3.Text.Equals(""))
            {
                return false;
            }
            else if (textEdit5.Text.Equals(""))
            {
                return false;
            }
            else if (memoEdit1.Text.Equals(""))
            {
                return false;
            }
            
            return true;
        }

        private void simpleButton2_Click(object sender, EventArgs e)
        {
            textEdit1.Text = textEdit2.Text = textEdit3.Text = textEdit5.Text = memoEdit1.Text = "";
            labelControl4.Text = ": Result :";
            labelControl4.Appearance.ForeColor = System.Drawing.Color.Black;
        }
    }
}

วันพฤหัสบดีที่ 26 กันยายน พ.ศ. 2556

[VS2013] TIPเล็กๆ วิธี Break exceptiion ขณะ Runtime

ในโหมด Debug ของ Visual Studio 2012 หลายๆคนคงจะคุ้นเคยกับ Message box ที่จะคอยเด้งขึ้นมาเตือนเมื่อเกิด Error ขึ้นขณะรันโปรแกรม ซึ่งแมสเซจจะแสดงก็ต่อเมื่อเกิด error ที่ไม่สามารถ throw ไปได้ ทำให้โปรแกรมหยุดชะงั้นที่จุดนั้นพอดี

วันนี้จะมาแนะนำ trick การดัดจับ Error + warning message ที่เกิดขึ้นทั้งหมด เพื่อให้ รู้ตำแหน่งที่แท้จริงของจุดเกิด Runtime error ไม่ใช่แสดงค่าว่า "Object reference is not set" (หรือคำอื่นๆ) แล้วก็จากไปเฉยๆ

ไปที่ DEBUG > EXCEPTION...
ในช่อง Break when an exception is: จะมี Name ให้เลือก หาอันที่ชื่อว่า Commom Language Runtime Exception (CLR)ซึ่งข้างในจะมี properties ให้เลือกมากมาย โดยสามารถเลือกตามงานที่จะ dubug ได้เลยครับ เช่น

ถ้าต้องการ Thrown เฉพาะโค๊ด Linq ก็เลือก option : System.Data.Linq


เพียงเท่านี้ครับ error หรือ warning ทั้งหมดจะขึ้นแจ้งตื่นเราก่อน ที่จะข้ามไป โดยระบุบรรทัดที่เกิดความผิดพลาดขึ้น หรือในทางกลับกันถ้าใครที่รำคาญพวก message เหล่านี้ ก็สามารถติก thrown ออกไปได้เลย ก็จะไม่มีข้อความมายุ่งหรือกวนใจอีก

วันศุกร์ที่ 13 กันยายน พ.ศ. 2556

[TeamViewer] วิธีการ Remote Control เครื่องคอมในวงแลนเดียวกัน

วิธีในการ connect เครื่องคอมของเพื่อนที่อยู่ในวงแลนเดียวกัน (Local area Network Connection) ผ่านโปรแกรม TeamViewer มีดังนี้ครับ

1. ในหน้าต่างหลักของตัวโปรแกรม คลิก Extras > Options เพื่อเข้าหน้าต่างออฟชั่น


2. ในแทป General หาบรรทัด Connection in local network (via IP address)


3. เลือก Incomming Lan connection เป็น accept เพื่ออนุญาติให้เชื่อมต่อจาก Lan ได้
4. ใช้ IP address ของเครื่องเป็น UserName และ Password ที่โปรแกรม Gen ขึ้นมาให้ในการ Login
5. ที่ status bar จะแสดง Connecting.. แสดงว่าเครื่องกำลังพยายามคอนเน็กอยู่และ Connected เมื่อคอนเน็กอีกเครื่องได้สมบูรณ์แล้ว ส่วนค่า ip address ของอีกเครื่องก็หาได้จาก YourID ของเพื่อนหรือจะรันคำสั่ง ipconfig ใน cmd ก็ได้เช่นกันครับ

โปรแกรมที่โปรแกรมเมอร์ขาดไม่ได้ก็คือ TeamViewer เพราะใช้งานง่ายและเร็วในการรีโมตเครื่องอีกทั้งยังมีคุณสมบัติเรื่องความปลอดภัยในระบบพิสูจน์ตัวตน โดยพาสเวิร์ดที่เจนมาให้นั้น สามารถแก้ไขได้ตลอดเวลา อีกทั้งโปรแกรมนี้ยังใช้กันมากอันดับต้นๆในการควบคุมเครื่องคอมพิวเตอร์รวมไปถึงการส่งต่อไฟล์ (file transfer) จากระยะไกล

วันพฤหัสบดีที่ 12 กันยายน พ.ศ. 2556

[WinForm c#] เบาๆกับโปรแกรม test SQL Connection อย่างง่าย


วันนี้ว่างๆ กับวันศุกร์ยมๆ (บรรยากาศเงียบๆ) ทดลองทำโปรแกรม ทดสอบคอนเน็คชั่นด้วย sql server 2008 r2 เพื่อตรวจสอบ connection string ว่าถูกต้องไหมก่อนจะใช้ดึงข้อมูลจากเบสต่อไป แต่ว่าการเทสคอนเน็กชั่นนั้น เราจะเทสแค่ทดสอบเชื่อมต่อกับ Host เท่านั้นว่ามีการตอบกลับมาไหม ไม่ได้เชื่อมต่อ database หรือ table อันไหนเลย

ดังนั้น Connection string ที่ใช้ก็คือ อักษรด้านล่างนี้เลยครับ
Connect Timeout=10;Pooling=false;Integrated Security=sspi;server=(local)
โดยเปลี่ยนคำว่า (local) ที่ท้ายของประโยคเป็น Host Name อื่นๆได้เช่น Url หรือ ip address ได้ แต่ผมไม่ได้ทดลองกับโฮสอื่นๆนะครับ แต่กับ (local) เทสได้แน่นอน แต่ผ่าน URL ลองแล้วมีปัญหา >> เดี๋ยวศึกษาเพิ่มเติมต่อไปเรื่อยๆละกัน

ต่อไปก็เริ่มต้นการคอนเน็คจริงๆสักที เริ่มต้นจากตรวจสอบข้อมูลที่กรอกลงไปทั้งหมดว่าถูกต้องแล้วหรือยัง ฟิลล์ที่จำเป็นคือ
Hostname, Username, Password, Database, Table

โปรแกรมอันนี้ถ้า test connect สำเร็จเเล้ว จะตั้งค่า default ของยูสเซอร์และพาสเวิร์ดให้อัตโนมัติ ถ้าไม่ได้เซ็ตตามค่าที่กำหนดไว้ก็แก้ไขให้ตรงด้วยนะครับ และนอกจากนี้จะทำการค้นหาตารางทั้งหมดที่อยู่ใน database ลูกนั้น เพื่อนำไปใส่ให้กับ combobox ตารางข้างล่าง ซึ่งคิวรี่ข้างในคือ

string query = "SELECT * FROM [dbo].[" + textTable.Text + "]";

โดยต้องกำหนดค่า table ด้วยนะครับไม่งั้นกด connect ยังไงก็พัง แต่ถ้าคอนเน็กสำเร็จ จะแสดงข้อมูลบน column ทั้งหมดในตารางออกมาที่ช่องผลลัพนะครับ เอาเป็นว่าวันนี้มันยมแท้ ขี้เกียจพิมพ์ต่อละ เอาโค๊ดไปแปะแล้วจัด control ต่างๆให้ต้องกับรูป design เป็นอันเสร็จสิ้นแล้วครับ













Code สมบูรณ์ ข้างล่างนี้ครับ

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;
using System.Data.SqlClient;
namespace ConsoleSqlConnect
{
    public partial class TestSQLConnection : Form
    {
        public TestSQLConnection()
        {
            InitializeComponent();
        }

        private void TestSQLConnection_Load(object sender, EventArgs e)
        {
            textHostName.Text = "(local)"; // set default for connection string [sql server]
            textdbName.Text = "Sample"; // set default 
            progressPanel1.Hide();
        }
        private void simpleButton1_Click(object sender, EventArgs e)
        {
            //test Connection
            progressPanel1.Show();
            ComboBoxTable.Properties.Items.Clear();
            memoResult.EditValue = string.Empty;
            string con = "Connect Timeout=10;Pooling=false;Integrated Security=sspi;server="+textHostName.EditValue;
            memoEdit1.Text = con;
            using (SqlConnection sqlconn = new SqlConnection(con))
            {
                try
                {
                    sqlconn.Open();
                    memoResult.EditValue = "Test Connect Complete"+System.Environment.NewLine+"Choose Database";
                    string query = "USE Sample SELECT * FROM sys.Tables";
                    SqlCommand cmd = new SqlCommand(query, sqlconn);
                    cmd.CommandType = CommandType.Text;
                    SqlDataReader read = cmd.ExecuteReader();
                    if (read.HasRows)
                    {
                        int num = -1;
                        while (read.Read())
                        {
                            ComboBoxTable.Properties.Items.Add(new DevExpress.XtraEditors.Controls.ImageComboBoxItem(read[0].ToString(), read[0].ToString(), num));
                            num++;
                        }
                        ComboBoxTable.EditValue = ComboBoxTable.Properties.Items[0].Value.ToString();
                        textUserName.Text = "sa"; // set default 
                        textPassword.Text = "12345"; // set default 
                    }
                    sqlconn.Close();
                }
                catch (SqlException ex)
                {
                    memoResult.EditValue = "Test Connect Fail";
                }
            }
            progressPanel1.Hide();
        }

        private void simpleButton2_Click(object sender, EventArgs e)
        {
            //connect Database
            progressPanel1.Show();
            string strConnect = "Data Source=" + textHostName.Text + ";Initial Catalog=" + textdbName.Text + ";User ID=" + textUserName.Text + ";Password=" + textPassword.Text;
            memoEdit1.Text = strConnect;
            using (SqlConnection sqlconn = new SqlConnection(strConnect))
            {
                try
                {
                    sqlconn.Open();
                    memoResult.EditValue = "Connection to " + ComboBoxTable.EditValue + " Complete" + Environment.NewLine;
                    string query = "SELECT * FROM [dbo].[" + textTable.Text + "]";
                    SqlCommand cmd = new SqlCommand(query, sqlconn);
                    cmd.CommandType = CommandType.Text;
                    SqlDataReader read = cmd.ExecuteReader();
                    if (read.HasRows)
                    {
                        while (read.Read())
                        {
                            memoResult.EditValue += read[1].ToString()+Environment.NewLine;
                        }
                         
                    }
                    sqlconn.Close();
                }
                catch (SqlException ex)
                {
                    memoResult.EditValue = "Connection Fail"+ex;
                }
            }
            progressPanel1.Hide();
        }

        private string GenStandardConnectionString()
        {
            //syntax : Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;
            return "Server = " + textHostName.Text + "; Database = " + textdbName.Text + "; User Id = "+textUserName.Text+"; Password = "+textPassword.Text+";";
        }

        private void ComboBoxTable_EditValueChanged(object sender, EventArgs e)
        {
            textTable.Text = ComboBoxTable.Text;
        }
    }
}
ปล. ใช้ DevExpress 12 เป็นตัว design หน้าจอนะครับ Control ต่างๆก็จะ reference ด้วย Dev Express ถ้าใครใช้ Control เจ้าอื่นก็จัดให้ตรงด้วยนะครับ
วิธีใช้งาน
1 กด test Connection ถ้าผ่านจะขึ้น "Test Connect Complete"
2 เลือก Database ที่จะ connect
3 กด Connect เพื่อเชื่อมต่อ database
4 ตรง result จะเเสดงข้อมูลจากตารางที่เชื่อมต่อสำเร็จ

อ่านความรู้อื่นๆ [2weektrain2014]

วันพุธที่ 11 กันยายน พ.ศ. 2556

อยากให้ชีวิตง่ายขึ้นต้องใช้ Store Procedure [WinForm c# + SQL Server]

คราวที่แล้วผม Blog เกี่ยวกับการติดต่อฐานข้อมูลด้วย SQLConnection ไปแล้ว คราวนี้เพิ่มความเก๋ไปอีกนิดหน่อยด้วยการเรียกใช้คำสั่ง SQL ด้วย Store Procedure ที่สร้างไปในดาต้าเบส โดยตัวอย่างนี้จะสร้างโปรแกรมค้นหาข้อมูลผู้ใช้งาน(ยูสเซอร์)อย่างง่ายๆ >> คำถามคือใช้แล้วชีวิตดียังไง?


คำตอบคือ แทนที่เราจะเขียนโค๊ด sql ซ้ำๆคำสั่งเดิมๆที่หน้า form ของเรา น่าจะมีวิธีที่สามารถเรียกใช้งาน query ทันทีได้เลยโดยไม่ต้องมาเริ่มต้นเขียนคิวรี่ "SELECT * FROM..." ใหม่ทุกครั้งไป นั้นแหละครับเรียกว่า store procedure ซึ่งคำสั้งเหล่านี้เราจะเขียนเตรียมไว้ก่อนที่ดาต้าเบสของเรา แล้วตั้งชื่อมันไว้ พอจะใช้งานแต่ละทีก็เลือกตามชื่อแล้วส่งตัวแปรที่จำเป็นไปให้ จากนั้นนั่งรอเอ็กซิคิวผลลัพธ์ได้เลยครับ

วิธีการสร้าง store procedure บน SQL Server 2008 R2
เข้าไปที่เบสปัจจุบัน แล้วเลือกโฟลเดอร์  Programability > Store procedures จากนั้นคลิกขวาเลือเมนู New Store Procedure.. เพื่อเพิ่มสโตร์โพซิเยอร์ตัวใหม่เข้าไป แล้วเซ็ตค่าตามรูปเลยครับ (อย่าลืมเปลี่ยนค่าที่อยู่ในกรอบสีแดงให้ตรงกับที่อยู่ในเบสของคุณด้วย)


เตรียมสิ่งต่อไปนี้ก่อน

สร้าง Databaseไว้ ชื่อว่า Sample โดยกำหนดให้มีตาราง User แล้ว add ข้อมูลไว้สัก 2-3 บรรทัดนะครับ
สร้าง Windows Form Application ขึ้นมา ตั้งชื่อว่า SearchApplication แล้วจัดหน้าจอให้ได้แบบด้านล่างนี้เลยครับ โดยเราจะรับข้อมูลชื่อ User จาก textEdit ด้านบนสุดแล้วเมื่อกดปุ่ม search โปรแกรมจะวิ่งไปค้นหาข้อมูลผ่าน store procedure ที่เราสร้างเอาไว้ แล้วแสดงค่าผลลัพธืตรงกรอบ result ที่เป็น label edit
สร้าง store procedures ขึ้นมาใหม่



ในโค๊ด อธิบายนิดหน่อย
การเพิ่ม parameter นั้นมีวธีการคือ cmd.Parameters.Add(new SqlParameter("@strName", text));
โดย @strName เป็นชื่อ store ที่อยู่ในดาต้าเบส ซึ่งเราต้องส่งไปให้ถูกตัวด้วย
text เป็นค่าของตัวแปรที่เราจะส่งไป >> อย่าลืมว่าใน c# และ SQL Server ก็มี FileType เช่นกัน ถ้า Map ไม่ตรงก็จะ error เช่น map stringในc# to intในSQLServer แบบนี้ไม่ได้นะครับ เพราะจะไม่ขึ้น error ตอน complie แต่พังแน่ๆตอน run
จากนั้นเพิ่ม Command Type ให้ SQL รู้จักด้วยว่า "Connection ต่อไปนี้คือ store" ด้วยการเซ็ต cmd.CommandType = CommandType.StoredProcedure; เพิ่มเข้าไป >> นอกจากนี้ก็เหมือนกัน SQLConnection โค๊ดเดิมทุกประการ







โค๊ดสมบูรณ์ด้านล่างนี้ครับ
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;
using System.Data.SqlClient;

namespace ConsoleSqlConnect
{
    public partial class Search : Form
    {
        public Search()
        {
            InitializeComponent();
            labelControl1.Text = "";
        }
        string text = string.Empty;
        SqlConnection sqlConn = null;
        private void Search_Load(object sender, EventArgs e)
        {
            string ConnectionString = GetConnectionString();
            sqlConn = new SqlConnection(ConnectionString);
            
        }
        private void simpleButton1_Click(object sender, EventArgs e)
        {
            labelControl1.Text = "";
            text = textEdit1.EditValue.ToString();
            try
            {
                sqlConn.Open();
                using (SqlCommand cmd = new SqlCommand("SearchUserName", sqlConn))
                {

                    #region sql
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add(new SqlParameter("@strName", text));
                    SqlDataReader result = cmd.ExecuteReader();
                    if(result != null)
                    {
                    while (result.Read())
                    {
                        labelControl1.Text = " Item Found >> " + System.Environment.NewLine + 
                            "\tUserName : " + result[1] + System.Environment.NewLine + "\tPassword : " + result[2];
                    }
                    }
                    else{
                    }
                    #endregion
                }
                sqlConn.Close();
            }
            catch (SqlException ex)
            {
                MessageBox.Show("Error : " + ex);
            }

        }
        private static string GetConnectionString()
        {
            string strConnect = "";

            string localhost = "(local)";
            string userName = "sa";
            string Password = "12345";
            string Catalog = "Sample";

            strConnect = "Data Source=" + localhost + ";Initial Catalog=" + Catalog + ";User ID=" + userName + ";Password=" + Password + "";
            return strConnect;
        }
    }
}

อยากเปลี่ยน query เป็นแบบอื่นก็แก้ไขในฟิลล์ BEGIN ได้เลยครับ หรืออยากเพิ่มคำสั่งอื่นๆก็สร้างสโตรมาใหม่ แล้วเพิ่มตัวแปรเข้าไปก็ได้ จัดเป็นหมวดหมู่คำสั่ง select alter delete ให้เป็นระเบียบ

วันพุธที่ 4 กันยายน พ.ศ. 2556

[โปรแกรม searchหาชื่อสินค้า] SQLite บน C# เอาไว้อ่านไฟล์ .db ใน WinForm มันง่ายมั่กๆ


วันก่อนผมเขียนเกี่ยวกับการสร้าง app ดึงข้อมูลจากฐานข้อมูล SQL Server 2008 r2 ไปแล้วซึ่งเขียนง่ายไม่ซับซ้อนแล้ว ผมว่ายังมีง่ายกว่านั้น แต่คราวนี้ผมต้องการดึง table จากไฟล์นามสกุล .db ลูกหนึ่งซึ่งค้นพี่ gooไปๆมาๆก็มาลงที่ SQLite {O_O} เอ๊ะนี้มีใช้เฉพาะเว็บไม่ใช่หรือ สรุปผู้พัฒนาเค้าสร้าง libary สำหรับใช้บน Win และ android มาด้วยซึ่งสะดวกเอามากๆ

sqlite เหมาะกับโปรแกรมที่ run แบบ stand alone และที่สำคัญ "ฟรี" โดยสามารถดาว์นโหลดไลบราลี่มาใช้งานได้ โดยการใช้งาน sqlite บน c# ก็ไม่ได้ใช้ code ที่สลับซับซ้อนเพราะ syntax คล้ายๆกับ sqlconnection นั่นแหละ


มาเริ่มกันเลยครับ Download libary .dll ตัวล่าสุดจาก Offical website ของ SQLite เค้าลงมา เลือกให้ถูกด้วยนะครับว่า จะเป็นแบบ 64 bit หรือ 32 bit หรือจะโหลดตัว install มาติดตั้งก็ได้ครับ ง่ายดี

หลังจากนั้น Install เลยครับ แล้ว add reference ให้ project ของเราซะ ตัวที่ต้องใช้งานมี
System.Data.SqlClient;
System.Data.SQLite;

เท่านี้เครื่องเราก็พร้อมใช้งานแล้วครับ ลุยขั้นตอนต่อไปเลย
เรื่อง connect string ศึกษาเพิ่มเติมได้ที่ website นี้ครับ http://www.connectionstrings.com/sqlite/ ซึ่งเค้ารวบรวม connection แบบต่างๆเอาไว้มีออฟชั่นเยอะแยะมากมาย แต่ผมขอเลือกแบบง่ายที่สุดก็เเล้วกัน

*หมายเหตุ เครื่องคอมผม ใช้windows 7 64 bit แต่เจอ error นี้เข้าไปหลังจากพยายามโหลด Libary ชื่อ SQLite.Interop.dll ซึ่งไปค้นหาทางแก้มา ได้ความว่าเราต้อง Prefer เป็น 64bit ถึงจะโหลดได้ >> ซึ่งต้องไป config เพิ่มที่ไฟล์ project (*.csproj) file ซึ่งคลิกขวา edit as EditPlus ได้เลยครับ แล้วเพิ่ม <Prefer32Bit>false</Prefer32Bit> เข้าไป ต่อท้ายใน tag <PropertyGroup>


แต่ถ้าไม่เจอปัญหานี้ก็รอดตัวไปครับ


มาลุยโค๊ดกันเลยครับ >> ลองโค๊ดนี้กับการอ่านไฟล์ .db สักตัวนึง ถ้าใน Console Connect Complete ออกมาก็แสดงว่าเรา Connect ฐานข้อมูลสำเร็จแล้วครับ เพื่อทดลองดึงข้อมูล งั้นก็เอาฐานข้อมูลที่ sqlite แถมมาให้เลยละกัน [code ข้างล่างนี้]
using System.Text;

using System.Threading.Tasks;

using System.Data.SQLite;

namespace sqlite

{

    class MainClass

    {

        public static void Main(string[] args)

        {

            string dbfile = "C:\\northwindEF.db";

            string connStr = "Data Source=" + dbfile + ";Version=3;Synchronous=Off;UTF8Encoding=True;";

            SQLiteConnection sqlConn = null;

            sqlConn = new SQLiteConnection(connStr);

            try

            {

                sqlConn.Open();

                Console.WriteLine("Connect Complete, Please Input Product Name : ");

                Console.ReadLine();

            }

            catch (Exception ex)

            {

                Console.WriteLine("Error" + ex);

                Console.ReadLine();

            }

        }

    }

}



 หลังจากนั่นก็จัด query บ้านๆ ไปเลยครับ โค๊ด sql select ธรรมดาที่เอาไว้ search หาข้อมูลที่เรากรอกลงไปนั้นก็คือคิวรี่ข้างล่างนี้
string query = "SELECT ProductName, QuantityPerUnit FROM Products WHERE ProductName like '" + strInput+"'";

วันนี้ขอโปรแกรมง่ายๆก่อนละกัน คราวหลังถ้ามีเวลายาวๆ จะเขียนตัวอย่างให้ละเอียดมากกว่านี้นะครับ เอาพอเป็นแนวละกัน SQLite เป็นไลบราลี่ฟรีสามารดาว์นโหลดผ่านหน้าเว็บเค้า แล้วยังมีการออกอัพเดตใหม่ๆตลอดเวลา บายครับ

[Complete Code Example] สรุปตัวอย่างโค๊ดที่ใช้ในโปรแกรม C# sqlite Connect
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Data.SQLite;



namespace sqlite

{

    class MainClass

    {

        public static void Main(string[] args)

        {

            string dbfile = "C:\\northwindEF.db";

            string connStr = "Data Source=" + dbfile + ";Version=3;Synchronous=Off;UTF8Encoding=True;";



            SQLiteConnection sqlConn = null;

            sqlConn = new SQLiteConnection(connStr);



            try

            {

                sqlConn.Open();

                Console.WriteLine("Connect Complete");

                do

                {

                    Console.WriteLine("\nPlease Input Products Name : ");

                    string strInput = Console.ReadLine();



                    string query = "SELECT ProductName, QuantityPerUnit FROM Products WHERE ProductName like '" + strInput+"'";

                    SQLiteCommand command = new SQLiteCommand(query, sqlConn);

                    SQLiteDataReader reader = command.ExecuteReader();

                    if (reader != null)

                    {

                        while (reader.Read())

                        {

                            Console.WriteLine("Product Name : " + reader[0] + "\t ProductPrice : " + reader[1]);

                        }

                    }

                    else

                    {

                        Console.WriteLine("No Product");

                    }



                } while (true);



                sqlConn.Close();

            }

            catch (Exception ex)

            {

                Console.WriteLine("Error" + ex);

                Console.ReadLine();

            }

        }

    }

}

เป็น Console Application นะครับแต่ก็สามารถดัดแปลงให้เสดงเป็น UI สวยๆ ได้แค่เอาข้อมูลไปใสในกริดวิวของ Winform ที่เราเตรียมเอาไว้แสดงผล

วันจันทร์ที่ 2 กันยายน พ.ศ. 2556

ปรับแต่ง Notepad++ ให้เป็น Editor เมพ


นั่งเขียนเว็บอยู่ดีๆ Editplus ตัวเก่งของผมที่ช่วยผมเขียนเว็บก็หมดช่วงทดลองลง (เสียใจ) ใจหนึ่งก็จะ search หาตัว crack มาลงให้รู้แล้วรู้ลอดไป เพราะชอบ editor ตัวนี้มากแต่อีกใจก็อยากลองหาอะไรใหม่ๆมาลองเขียนโค๊ดดูบ้าง จะได้เป็นหลายๆเจ้า

ตั้งแต่เป็นโปรแกรมเมอร์เต็มตัวผมรับรู้ได้อย่างนึงครับ คือการไปละเมิดลิขสิทธิ์ software เพราะผมเองก็เขียนซอฟแวร์ ถ้ามีใครแอบมา crack โปรแกรมผมไปใช้ฟรีๆผมก็คงหมดกำลังใจเขียนโค๊ดเหมือนกัน ดังนั้นวันนี้ผมจะมาแนะนำการปรับแต่ง free editor ให้ประสิทธิภาพเทียบเท่ากับกับซอฟแวร์ที่ขายไลเซนต์ให้จงได้

ซึ่งวิธีการเลือกตัว editor สำหรับตัวผมเองจะคำนึงถึง 3 หัวข้อหลักๆที่ตรงตามนิสัยการ dev ของผมนั้นก็คือ
1 ต้องโหลดเร็ว ไม่กินแรม >> คอมผมจะ 5 ปีแล้วครับ เริ่มติ่งต้อง ซุกซนหลายเวลา ดังนั้นโปรแกรมต้องเบาไม่หนักเครื่อง
2 ต้องทำ auto complete ได้เพื่อย่นระยะเวลาการเขียนโค๊ดลง ข้อนี้ประมาณว่าพิมอะไรลงไปแล้วโปรแกรมจะคอยแนะนำ syntax ให้
3 ต้องฟรี และใช้กันกว้างขวาง มี plugin เสริมการทำงานที่พัฒนาอยู่เสมอ

จาก 3 ข้อนี้โปรแกรมที่เข้ารอบมีเยอะมากเลยครับ ผมเลยตัดสินจากตัวที่ดังๆละกัน >> เผื่อเกิดปัญหา จะได้ search Google หาวิธีแก้ได้ง่ายๆ ซึ่ง editor ตัวนั้นก็คือ Notepad++ นั้นเอง

ชื่อก็บอกแล้วครับว่าบวกจากตัวเดิม 2 รอบแสดงว่าต้องเมพกว่า 2 เท่า ซึ่ง plugin ตัวนี้เยอะมากครับ ผมยังลองเล่นได้ไม่หมดเลย เดี๋ยวจะเเนะนำเอาเฉพาะตัวที่สำคัญจริงๆให้การเขียนเว็บละกันครับ

อันดับเเรกเลยมาปรับแต่งกันก่อน ผมชอบเลือกนามสกุลไฟล์ที่เกี่ยวข้องกับไฟล์ที่เราจะแก้ไขเท่านั้นครับ เพราะเวลา save เอกสารเราจะได้เลือกง่ายๆ ผมdisable ตัวอื่นเหลือแต่เท่าที่เห็นนี้ครับ คือตัวที่ผมใช้จริงๆ เลือก settings > Preference > Language Menu

ต่อมาคือการเซ็ตสีของพื้นหลังและ theme ที่จะเอาไว้แสดงผล  >> ผมขอเน้นสีมืดๆละกันครับ จะได้ช่วยถนอมสายตา เวลาจ้องมองคอมพิวเตอร์นานๆ เลือกที่ settings > เเล้วเลือก style configurtor.. ที่ช่อง select theme เลือกได้ตามใจอยากได้เลยครับ


ต่อไปเป็นตัว explror ซึ่งเป็น plugin ที่ทำให้สามารถ browse ไฟล์ได้จากเมนูทางซ้าย คล้ายๆ edit plus วิธีการ install ก็แสนง่าย ให้ไปที่ plugIn > PlugIn manager > show Plugin Manager แล้วเลือก Install ตัว Explorer จากนั้น restart โปรแกรมใหม่แล้วจะมีแถบเมนู explorer เพิ่มขึ้นมาในหมวด PlugIn คลิกเลือก Explorer.. หรือ key ctrl+alt+shift+E ก็จะใช้งานได้ทันที

ต่อไปเป็นฟังชั่น auto complete ซึ่งจะแสดง tag ที่อยู่ในฐานข้อมูลของอิดิเตอร์เอง ทำให้การเขียนโค๊ดไวมาขึ้น แต่ตัวนี้ เท่าที่ผมลองมี tag ใหม่ๆของ html5 และ css3 อยู่เหมือนกันแต่ว่าก็ไม่ได้ครบถ้วนทั้งหมด ซึ่งผมว่าก็พอแล้วสำหรับ เขียนเว็บสักเว็บนึง แต่คิดว่าอนาคตน่าจะมาอัพเดตใหม่ๆ ที่auto complete ได้ดีกว่านี้


ส่วนต่อไปผมจะปรับแต่งให้ไม่ต้องตรวจคำผิด เพราะโปรแกรมจะตรวจแม่ทั้ง string ทั้งหลายที่อยู่ใน quote ซึ่น่ารำคาญมากสำหรับผม >> เอาออกไปซะ ชื่อมันคือ DSpellCheck

ต่อไปเป็น PlugIn ชื่อ textFX เป็นตัวที่ทำให้ชีวิตง่ายขึ้นมาก เพราะจะ ไฮไลท์ tag html ที่ tag เปิดและปิดให้ ทำให้ไม่พลาดใส่ผิดแท็กอย่างแน่นอน โดยเมื่อ install ปลักอินตัวนี้มาแล้ว เลือกเมนู textFX > textFX setting > เลือก auto close XHTML/XML <tag> เวลาใช้งานก็กด ctrl + T ก็จะแสดงไฮไลท์ให้แล้ว

ต่อมาเป็น macro สคิปเล็กๆที่เรา gen ไว้สำหรับงานซ้ำๆ จะได้ไม่ต้องคลิกขวา copy แล้ววาง มันช้าให้มาโครจัดการเถอะ โดยการกด record เเล้วเริ่มทำการแก้ไขโค๊ด เมื่อแก้ไขเสร็จสิ้นก็กด stop record เพียงเท่านี้ เมื่อถึงบรรทัดที่ต้องการแก้ก็แค่คลิก playback โค๊ดที่พิมไว้ก็จะถูกวางลงทันที

สรุปนะครับ ผมคิดว่าถ้าชอบความเบาของโปรแกรม และความเร็วในการโหลดเพิ่มมาขึ้น + plugIn ดีๆน่าจะพอสูสีกับหลายๆเจ้าที่เสียค่าไลเซนต์ได้อยู่ ที่สำคัญกินแรมน้อยมากถ้าเทียบกับฟังชั่นที่ใช้จริงๆกับแรมที่เสียไป ผมคิดว่าตัวนี้น่าจะทำคะแนนได้มากกว่า editor ตัวอื่นๆด้วยซ้ำไป ชึ่งถ้าต้องการฟังชั่นที่ดีกว่านี้เช่น auto complete ที่ดีกว่า หรือโหมด Debug แนะนำให้หาโหลด IDE มาเลยดีกว่า ซึ่งก็ต้องแลกกับแรมที่ต้องมอบให้โปรแกรมที่มากขึ้น

วันอังคารที่ 27 สิงหาคม พ.ศ. 2556

อัพเดตโค๊ด Revisionล่าสุดมาMerge >> แล้วโค๊ดอะไรเปลี่ยนแปลงบ้าง


การใช้งาน Revision Control ในโปรเจกค์เขียนโปรแกรมที่มีขนาดใหญ่ถือว่าจำเป็นมาก เพราะเป็นเหมือนตัวช่วยให้เราทำงานแยกส่วนกับคนอื่นได้โดยอ้างอิงโค๊ดตรงกลาง ดังนั้นเมื่อใดก็ตามที่มีการแก้ไขไฟล์จะมีการเก็บ Log ส่วนที่เปลี่ยนแปลงไปกับ SVN ทำให้เราทราบ version ปัจจุบันว่ามีการปป.ไปถึงไหน และสามารถ revert กลับเพื่อกู้คืน version เดิมกรณีที่โค๊ดใหม่กระทบระบบส่วนรวม


แล้วเมื่อไฟล์เดียวกันถูกแก้ด้วย 2 คนหล่ะ
ถ้ามีการแก้ไขไฟล์พร้อมๆกัน คนที่ commit ไฟล์ขึ้นไปบน server ก่อนจะไม่ต้องกังวลเรื่องโค๊ดชนกัน แต่คนที่คอมมิตทีหลังจะต้อง Update โค๊ดตัวล่าสุดมาก่อน ซึ่งถ้าชนกันกับโค๊ดเดิม จะต้องเลือกโค๊ดอันใดอันหนึ่งก่อน Commit แต่ถ้าไม่ชนกันโค๊ดจะ Merge เข้าหากันทำมห้เราไม่ทราบว่า โค๊ดอะไรบ้างที่เปลี่ยนไปตามกาลเวลา


ถ้าใช้เต่า SVN (TortoiseSVN) และ plugin svn กับ visual Studio
บนโปรเจกของเราคลิกขวาที่ไฟล์ที่เพิ่ง update มาใหม่ >> เลือก Show Different from xxx.cs แล้ว SVN จะทำการเปรียบเทียบไฟล์ของเรากับ Version ล่าสุดว่ามีส่วนไหนที่แตกต่างกันบ้าง โดย

- สีเขียว : โค๊ดที่ฝั่งเราเพิ่มลงไป
- สีแดง : โค๊ดที่ฝั่งเค้ายังไม่มี หรือโดนลบ
โค๊ดในหน้าต่างทางซ้ายมือคือฝั่ง server ส่วนทางขวามือคือโค๊ดของเรา เพียงเท่านี้เราก็สามารถ อัพเดตโค๊ดแล้วเอามาดูความแตกต่างได้ง่ายๆ

นอกจากนี้ยังสามารถดูความแตกต่างของแต่ละ revision ได้ด้วยการ คลิกขวาที่หัว solution คลิก VisualSVN > Show Log.. เพื่อเเสดง Log ไฟล์ทั้งหมดที่ถูกคอมมิต > เลือกไฟล์เดียวกัน 2 ไฟล์ที่ต่าง revision > เลือก Compare  Revision จะปรากฎหน้าต่างซ้ายขวาเหมือนเดิม แต่คราวนี้จะเเสดงสีเหลืองที่โค๊ดที่แตกต่างกัน
ส่วนคำสั่ง Show different as unified diff จะใช้เพื่อแสดงเฉพาะโค๊ดตัวล่าสุดว่ามีการอัพเดตส่วนไหนไปบ้าง

พอใช้ SVN เเล้วการควบคุม version เป็นเรื่องง่ายไปเลย ยิ่งบน Windows มีเต่าSVN ที่ใช้งานง่ายมากๆ นึกถึงตอนเรียนที่พองานแต่ละคนเสร็จก็ก็อปใส่ Handy Drive มารวมกันแล้วแก้กันยาวมากๆ นึกแล้วตลกตัวเอง

วันจันทร์ที่ 26 สิงหาคม พ.ศ. 2556

รู้จักกับ ADO.Net frame work แล้วถึงตา SqlConnection บน C#


นอกจาก Modelง่ายๆของ Linq ที่พูดถึงในโพสที่ผ่านมาบน Winform ก็มีชุดคำสั่งที่ใช้ในการเชื่อมต่อฐานข้อมูลเช่นเดียวกันซึ่งไม่ได้ยากและซับซ้อนอะไรแต่จะมีข้อแตกต่างจาก Linq ที่ผมพบเจอก็คือ

1 ต้องใส่ Connecttion String ก่อนดึงข้อมูลมาแต่ละครั้ง ซึ่งน่าจะช่วยในเรื่องความปลอดภัยในการเข้าถึงข้อมูลระดับหนึ่งซึ่ง ADO.Net นั้นใช้การผูก model กับเบสตั้งแต่ครั้งแรกที่เริ่มสร้าง ทำให้การเข้าถึงนั้นง่ายเพียงแค่เรียก Data Entities ขึ้นมาแล้วอัพเดตเบสด้วยลิงคิว (เดี๋ยวศึกษาต่อเรื่อยๆครับ แล้วจะมาเล่าอีกที)
2 การคิวรี่ต้องใช้ string ที่เป็นภาษา sql นั้นคือจะรู้ว่าคิวรี่ถูกหรือผิดนั้นต้อง execute query ก่อนเพื่อรับผลลัพธ์มา แต่ ถ้าเป็น Linq จะง่ายกว่าเยอะ เพราะสามารถselectข้อมูลสดๆมาและรู้ด้วยว่ามีคอลัมม์ไหนบ้างบนฐานข้อมูล ซึ่งช่วยย่นเวลาได้เยอะทีเดียว


โค๊ดที่ใช้เรียกข้อมูลก็ง่ายๆ ไม่กี่ step ตามนี้
import libary โดย using System.Data.SqlClient;

ใช้ class SqlConnection สร้างคอเน็กชั่นใหม่ขึ้นมา
SqlConnection sqlConn = new SqlConnection(ConnectionString);
โดยพารามิเตอร์ของ  ConnectionString มีดังนี้
1 Host Server ที่ต้องการ connect : Data Source
2 ฐานข้อมูลที่จะ connect : Initial Catalog
3 Username ของ host server : User ID
4 Password ของ Host server : Password



หลังจากนั้นทดลองรันโปรแกรมเพื่อคอเน็คทดสอบดูครับ ถ้าไม่เป็ค่า Null แสดงว่า Connect สมบูรณ์

ถ้าผ่านมาได้อย่างสมบูรณ์จนถึงขั้นตอนนี้ ก็เริ่มต้นดึงข้อมูลได้เลย เริ่มจากการ open Connection ก่อน
sqlConn.Open();
แล้วสร้างคำสั่ง sql โดยสร้างจาก class : SqlCommand
SqlCommand sqlComm = new SqlCommand();
แล้วทดสอบคิวรี่select ง่ายๆจากตาราง User ที่ผมสร้างไว้ในเบสด้วยคิวรี่นี้
"SELECT * FROM [dbo].[User]" >> เลือกทุกอย่างที่อยู่ในตาราง User

เสร็จแล้วเราจะได้ผลลัพออกมา ส่งต่อให้กับตัวแปร reader ของ class SqlDataReader ซึ่งเป็นคลาสที่รองรับการอ่านค่าจากฐานข้อมูลซึ่งมีลักษณะตัวแปรเป็น Array นั่นหมายความว่าเราสามารถอ้างอิงตัวแปรแต่ละช่องได้โดย ชี้อินเด็กไปอ้างอิงเเต่ละ column นอกจากนี้ ยังมีคำสั่งง่ายๆให้การตรวจสอบว่าคิวรี่ที่ส่งไป return ข้อมูลกลับมาไหม ด้วยคำสั้ง

reader.HasRows ซึ่งจะ >= 1 ถ้ามีข้อมูลรีเทิร์นกลับ

ข้างล่างนี้เป็น โค๊ดสมบูรณ์ ลองโหลดไปทดลองดูกันได้ครับ กับ SQLบน windows application

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleSqlConnect
{
    class Program
    {
        static void Main(string[] args)
        {
            string table = "[dbo].[User]";
            SqlDataReader reader = null;
            string ConnectionString = GetConnectionString();
            SqlConnection sqlConn = new SqlConnection(ConnectionString);
            try
            {
                sqlConn.Open();
                Console.WriteLine("Connected");
                using (SqlCommand sqlComm = new SqlCommand())
                {
                string query = string.Concat("SELECT * FROM "+table);
                sqlComm.CommandText = query;
                sqlComm.CommandType = CommandType.Text;
                sqlComm.Connection = sqlConn;

                reader = sqlComm.ExecuteReader(); // exe query
             
                    while (reader.Read())
                    {
                        Console.WriteLine(reader[0] + " " + reader[1] + " " + reader[2]);
                    }
                }
                sqlConn.Close();
                 
            }
            catch(Exception ex)
            {
                Console.WriteLine("Connect fail");
            }
            Console.ReadLine();
        }

        private static string GetConnectionString()
        {
            string strConnect = "";

            string localhost = "(local)";
            string userName  = "sa";
            string Password  = "12345";
            string Catalog   = "Sample";

            strConnect = "Data Source=" + localhost + ";Initial Catalog=" + Catalog + ";User ID=" + userName + ";Password=" + Password + "";
            return strConnect;
        }
    }
}

วันอาทิตย์ที่ 25 สิงหาคม พ.ศ. 2556

วิธีการเป็น Administrator บน PC ของตัวเอง

ผมว่าออกจะน่าขำไปสักนิด กับการที่เครื่องคอมพิวเตอร์ของตัวเองแท้ๆแต่กลับ log in เข้าใช้ได้เพียง User ธรรมดาซึ่งจะโดนจำกับสิทธิในการการทำที่มีการดัดแปลงระบบทั้งหมด ซึ่งต้องมานั่งคอยคลิกขวา run as administrator เพื่อใช้งานบางฟังชั่นของ Windows ได้ครบ


เรื่องมีอยู่ว่าผมต้องการลบ assembly ตัวหนึ่งที่อยู่ใน drive C:/Windows/assembly ซึ่งผมทำการ Uninstall โปรแกรมไม่สมบูรณืเองทำให้ไม่ได้ล้างค่าใน assembly ไปด้วย ดังนั้นพอรันโปรแกรมผมเลยมีปัญหาว่ายังเห็นเอสเซมบรี่ตัวเก่าอยู่ซึ่งเวอร์ชั่นที่ซ้ำกันทำให้ทำงานต่อไม่ได้(เลือกไม่ได้ว่างั้น)

การลบต้องการสิทธิของ admin ซึ่งทดลองรัน as admin ด้วย Expplorer แล้วลองลบดูก็ยัง access denied
อ้าวงี้กวนละครับคุณ win7 ไม่ได้ให้สิทธิแอดมินจริงๆกับเรา แบบนี้ต้องเจอไม่เด็ด เปิด cmd(command promt) ด้วยสิทธิ admin ขึ้นมาก่อน ถ้าเปิดถูก location ปัจจุบันจะอยู่ที่ C:/Windows/system32

แล้วจัดโค๊ดชุดนี้ลงไปเลยครับ : net user administrator /active:yes


เท่านี้ครับเราก็เพิ่ม User ที่เป็น admin ขึ้นมาได้แล้ว >> ทำการ switch user ไป log on ที่ Administrtor

เเล้วสิทธิทั้งหมดก็เป็นของเรา ตอนนี้เราก็สามารถทำการ แก้ไข ดัดแปลงทุกสิ่งอย่างได้ตามใจอยากเลยครับ อย่างผมอยากลบ assembly กวนใจก็ไม่ใช่ปัญหาอีกต่อไป

ถ้าต้องการเอาสิทธิแอดมินออกก็เพียงเปลี่ยนคำสั่งเดิมจาก Yes เป็น No

วันอังคารที่ 28 พฤษภาคม พ.ศ. 2556

ลบ .Bak แสนกวนใจใน Edit Plus

ลบ .Bak แสนกวนใจใน Edit Plus

สำหรับใครที่ใช้ Edit plus เป็น Editor ในการเขียนโค๊ดไม่ว่าจะเป็น html php c/c++ java ต้องมีไม่มากก็น้อยที่รู้สึกรำคาญเวลาที่
เจ้าอิดิทเตอร์ตัวนี้สำรองไฟล์ให้เรา (ช่างรู้ใจจริงๆ) แต่บางครั้งเราก็อยากปิดฟังชั่นนี้ออกไป โดยเฉพาะผมที่ใช้เขียนเว็บอยู่บ่อยๆ เวลาอัพโหลดข้อมูลขึ้นโฮสหลายๆไฟล์จะรู้สึกรำคาญมาก
เพราะต้องนั่งเลือกไฟล์ที่ไม่ใช้ .bak เท่านั้น >> จะได้ไม่หนักโฮสด้วย

วันนี้เลยมีวิธีง่ายๆ มาแบ่งปันเป็นวิธีปิด auto backup file นามสกุล .bak ของ Edit Plus ตามขั้นตอนดังนี้เลยครับ
ไปที่ tool > preference > ทางด้านซ้ายจะมี catagories ให้เลือกคลิกที่แท๊ป File แล้วติกคำว่า
Create backup wher saving ออก เพียงเท่านี้ไฟล์แบ็คอัพกวนใจก็จะหาไปในทันที


วันจันทร์ที่ 27 พฤษภาคม พ.ศ. 2556

จับผิด ถ้าคิดแอบใช้คอมเรา ด้วย Event Log

เคยสงสัยกันไหมว่า ตอนเราไม่อยู่มีใครมาแอบเล่นคิมพิวเตอร์ของเราหรือเปล่า บางทีอาจเป็นเพื่อนของเรา หรือคนรู้จักอื่นๆ
ซึ่งเราก็ไม่ได้ซีเรียสอะไรกับเรื่องพวกนี้หรอก แต่..รู้ไว้ก็ดีเหมือนกันว่า "คอมพิวเตอร์ของเรา turn on เวลาไหนบ้าง"

อันดับแรกผมอยากแนะนำให้รู้จัก administrator tools ซึ่งเป็นเครื่องไม้เครื่องมือที่เป็นประโยชน์มากสำหรับการจัดการ
บนระบบของเรา คลิก start แล้ว search คำว่า "administrator tools" คลิกผลการค้นหาแรกจะเข้าสู่หน้าต่างดังรูป



แล้วหา Event viewer เครื่องมือตัวนี้แหละครับที่คอยจับดู เหตุการณ์ต่างๆที่เกิดขึ้นเวลาเราเปิดเรื่องหรือรันโปรแกรมอะไรต่างๆ เสมือนคอยเก็บ log

การใช้งานของเราไว้อย่างละเอียด (ลองเข้าไปดูจะรู้ว่าแค่รันแอพพริเคชั่นนิดๆหน่อยๆ ก็จะถูกเก็บข้อมูลไว้ทั้งหมด) ทางซ้ายมือจะมีไอคอนเขียนไว้ว่า Windows Logs
คลิกเข้าไปเลยครับ จะเจอลิส์ของ log ที่เราใช้งานไปมหาศาล นับไม่ถ้วน

ทีนี่ให้ลองสังเกตุ เวลาที่เกิด event แต่ละตัวขึ้นในคอลัม Date ซึ่งจะบอกข้อมูลละเอียดถึงเวฃาที่เกิดขึ้นด้วย เราสามารถนำไปประยุกต์คือ "ช่วงที่เราไม่ได้เล่นคอม
จะต้องไม่มี log ในช่วงนั้น"


ทางขวามือจะมี Filter เอาไว้กรองข้อมูลว่าจะเอาเฉพาะอะไรบ้าง จากรูปจะเห็นว่ามีให้คลิดคือ Critical , Warning , Verbose, Error, Information
นอกจากนี้ ยังใส่ keyword เฉพาะที่ทำให้การค้นหาเป็นเรื่องง่ายขึ้น

เท่านี้ครับเราก็สามารถตรวจสอบการเข้าใช้งานคอมพิวเตอร์ด้วยวิธีง่ายๆ

วันพฤหัสบดีที่ 16 พฤษภาคม พ.ศ. 2556

เรื่องของ MyComputer ที่อาจยังไม่รู้

ตอน uninstall โปรแกรมเข้ากันยังไงครับ ยังเป็นแบบนี้อยู่หรือเปล่า Start > Control Panel > Program and Feature ถึงจะเจอหน้าลิสต์โปรแกรม

ตอนดูสเปกเครื่อง ทำกันยังไงครับ Start > คลิกขวาที่ My Computer > Properties กันอยู่ใช่ไหม

มันมีวิธีเข้าที่ไวกว่านั้นครับ วันนี้จะมาแนะนำ เพียงเเค่เข้า My Computer แค่ครั้งเดียว ทุกหน้าก็จะมาอยู่ในมือเรา แหะๆ มาดูกัน


ที่ผมขีดเส้นใต้สีแดงๆ ไว้นั่นแหละครับ
-System Properties : ก็คือการดูสเปกเครื่องคอมเราว่า cpu อะไร ram เท่าไหร่
-Uninstall or Change a program : คือ Uninstall ดีๆนี้เอง เข้าง่ายๆได้ที่นี้เลย
-Map Network drive : คือการเลือก Drive ให้ยิงไปโฟลเดอร์ที่เรากำหนดไว้ อันนี้เล่นระวังๆด้วย
- Open Control panel : ความหมายตรงตัวครับ เปิดคอนโทรพาเนล

วันศุกร์ที่ 26 เมษายน พ.ศ. 2556

เรื่องของ Delegate ในภาษา C# เรื่องนี้ ไม่เคยเจอเลยในตอนเรียน แต่มันก็ไม่ใช่ศาสตร์ขั้นสูงอะไรเลย แต่มีประโยชน์มาก เมื่อใช่ร่วมกับ Event ซึ่งตามคอนเซตที่ผมเข้าใจคือ "การรวบรวมเหตุการณ์(method) เข้าไว้เพื่อเรียกใช้งานในครั้งเดียว" ซึ่งเมทอดนั้นจะมาจากหลากหลาย class มาดูกันเลยดีกว่าว่าโค๊ดเขียนกันยังไง

ขั้นแรกก็เพียงประกาศ delegate เอาไว้...

ผมแปะโค๊ดไว้ก่อน เดี๋ยวมาอธิบายทีหลัง ตอนนี้ ไม่ว่าง ฮ่าๆๆ

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SampleDay1
{
    public class Program4
    {

        public static void Main(string[] args)
        {
            Person person1 = new Person() { name = "Sam" };
            Person person2 = new Person() { name = "Lula" };
            Person person3 = new Person() { name = "Billy" };
            Animals animal1 = new Animals() { name = "Dog" };

            Home home = new Home();
            home.OnFired += person1.PersonFired;
            home.OnFired += person2.PersonFired;
            home.OnFired += person3.PersonFired;
            home.OnFired += animal1.Bank;
            home.Fire();

            Func<int,int> fu = new Func<int,int>(DoSong);
            int result = fu.Invoke(2);

            Console.ReadLine();
        }
             public static int DoSong(int u)
            {
                Console.WriteLine("sdfdsf");
                 return 1;
            }
    }

        public class Home
        {
            public string color;
            public int height;
            public int width;

            public event OnFireHandler OnFired;

            public void Fire()
            {
                string ss = "h";
                if (OnFired != null)
                {
                    OnFired(ss);
                }
            }

            public void build(string chars)
            {
                Console.WriteLine("CH :" + chars);
            }

        }
        public class Person
        {
            public string name;
            public string PersonFired(string x)
            {
                Console.WriteLine(name + " said fire fire fire!!!"+ x);
                return null;
            }
        }
        public partial class Animals
        {
            public string name;

            public string Bank(string xx)
            { Console.WriteLine(name + "said Bank Bank Bank!!!" + xx); return null; }
        }

        public delegate string OnFireHandler(string str);
}

วันพฤหัสบดีที่ 25 เมษายน พ.ศ. 2556

Tip : เล็กๆกับการ Commit SVN


Trick เล็กๆน้อยกับการใช้งาน เต่า SVN :

จริงๆแล้วการแก้ไข ไฟล์เดียวกันในเวลาเดียวกันนั่น จำเป็นต้องบอกอีกฝ่ายด้วย เพื่อให้ไม่ commit ทับกัน โดยวิธีการก็ง่ายๆคือ ให้คนแรกแก้ไขให้เสร็จก่อน แล้วทำการ build ให้ผ่าน (หรือไม่มี error นั่นเอง) แล้วจึง Commit ไฟล์นั่นขึ้นไปบน SVN 
ต่อมา ค่อยให้อีกคน SVN Update ไฟล์ตัวล่าสุดลงมาก่อนแล้วจึงค่อยแก้ไข และ commit ตามวิธีการต่อไป

นอกจากนี้ การ SVN Update ในบางครั้งยังเกิดปัญหา โดยเฉพาะไฟล์ที่ modifier เท่านั้น ยกตัวอย่างเช่นไฟล์ Model ของ Entities Framework ของ Microsoft ที่ต้องมีการ Update อยู่บ่อยๆ

แนะนำให้ ลบ Folder ที่เก็บ model นั่นทิ้ง แล้ว SVN Update” จะดีกว่าเพราะ SVN จะเห็นว่าเครื่องเรานั้นยังไม่มีไฟล์ ดังนั้นจะทำการโหลดไฟล์ลงมาใหม่ทั้งหมดใน revision ล่าสุด ทำให้ใหม่สุดๆ สดสุดๆ
สำหรับไฟล์ที่แก้ไขคนเดียวก็ไม่ต้องห่วงเรื่อง commit เลย เพราะสามารถทำไฟล์ให้สมบูรณ์ก่อน(หรืออย่าให้เหลือ error ก็พอ แล้ว) แล้วค่อยคอมมิท เฉพาะไฟล์นั่นขึ้นไป ถ้าคนอื่น update svn ก็จะได้รับไฟล์ของเราไปคอมไพล์ด้วย

ปล. วันนี้เจอโค๊ดเล่นงานไป 1 บรรทัด >> หาแทบตาย สุดท้ายขาดแค่บรรทัดเดียว #เหนื่อย #กว่าจะเจอ #debugแทบตาย (commit SVN)

วันอังคารที่ 23 เมษายน พ.ศ. 2556

[OUTLOOK] เบื่อรับเมล์ปะปนกันไปหมดไหม? กรองมันซะเลย!



ขอโทษทีครับที่ช่วงนี้ ไม่ได้โพสบทความใหม่ๆเพิ่มเลย เอาเป็นว่าวันนี้มาสอนวิธีการทำฟิลเตอร์ e-mail  ที่โดยใช้โปรแกรม Microsoft Outlook 2010 ซึ่งมีประโยชน์มาก และใช้เป็นตัวช่วยจัดหมดหมู่ Email ให้แยกกลุ่มอย่างเป็นระเบียบ ถ้านึกภาพไม่ออกให้ลองนึกถึง เมลล์ขยะที่เมื่อถูกส่งเข้า Inbox เราปุ๊บก็จะถูกจับยัดลง Junk mail เฉยเลย >> เพราะมันมี ระบบ คอยตรวจสอบชื่อหัวเรื่องที่น่าจะเป็นเมลล์ขยะนั่นเอง
เราต้องสร้างกฎการจัดกลุ่ม โดยมีให้เลือก รูปแบบ คือ


1.       แบ่งตามรายชื่อผู้ส่ง (From) คือ ย้ายเข้ากล่องถ้ามีเมลล์มาจาก address ของคนนี้
2.       แบ่งตามคำในหัวเรื่อง (Title Contain) คือถ้ามีคำที่กำหนดในหัวเรื่องเมลล์ จะถูกย้ายเข้ากล่อง 

นอกจากนี้ยังกำหนดได้ด้วยว่าจะให้ส่งต่อเมลล์ไปยังผู้อื่นที่อยู่ใน Contract ของเราหรือไม่
ขั้นแรกคลิกขวาที่เมลล์ที่ต้องการกรอง หรือคลิกเมนูด้านบนโดยเลือก RULE | Create rule จะเห็นไดอะล็อก create rule และช่องให้ติกมากมายซึ่งมีดังนี้

-          From : คือเลือกว่าให้ฟิลเตอร์เฉพาะเมลล์ที่มาจากคนนี้เท่านั่น
-          Subject contain : คือฟิลเตอร์จากคำที่อยู่ในชื่อเรื่อง
-          Send to: คือส่งต่อให้คนอื่น

แล้วทำการเลือกโฟล์เดอร์ที่จะให้ทำการย้ายเมลล์ไปเก็บไว้ อย่างในตัวอย่างนี้เลือก Target Folder หรือจะสร้างโฟลเดอร์ขึ้นมาใหม่ก็ได้ คลิก OK

เลือก run this rule now on messages already on the current folder ถ้าต้องการให้นำกฎไปใช้กับทั้ง Inbox
เพียงเท่านี้ เมลล์ก็จะถูกจัดระเบียบสวยงาม เป็นหมู่ๆไป

วันพฤหัสบดีที่ 4 เมษายน พ.ศ. 2556

ระบบ LogIn ใน Windows Form Application


ระบบ LogIn ใน Windows Form Application ซึ่งผมได้สร้างข้อมูลใน Table “Users” ไว้แล้ว โดยมีข้อมูลดังนี้คือ
คอลัมม์ UserID: 1 ,
UserName: admin,
UserPassword: admin,
UserEmail: admin@admin.com

เริ่มต้นก็ทำการสร้างฟอร์มหลักขึ้นมา โดยคลิกขวาที่ชื่อโปรเจกค์ > add new item> windows form ตั้งชื่อ(Name) ว่า frmMain.cs ซึ่ง แล้วลากเอาคอมโพเน้นชื่อว่า MenuStrip กับ StatusbarStrip มาวางไว้ด้านบนและล่างของฟอร์มเพื่อเพิ่มชื่อ นาฬิกา

โดยหลักการ LogIn คือ ให้ฟอร์มของหน้า logIn เด้งขึ้นมาก่อนเพื่อรอการ Authentication หากล็อกอินสำเร็จก็จะผ่านเข้าสู่หน้าเมนหลัก แล้วแสดงชื่อของผู้ใช้งานในปัญจุบัน ภายใต้ status bar
เริ่มต้นโดยการสร้าง Windows Form ใหม่ขึ้นมาหนึ่งอัน คลิกลาก Label เข้ามาวางภายในฟอร์ม 2 อัน (Username กัน Password) และ EditText อีกสองอันเช่นเดียวกัน เพื่อให้ผู้ใช้กรอกข้อมูลทั้งหมด และปุ่ม OK และ Cancel ซึ่งเราจะเข้ามาสร้าง behavior ทีหลัง อ๋อ อย่าลืม ตั้งชื่อ (Name) ให้กับ text ด้วย
ดับเบิลคลิกที่ form เพื่อสร้าง ฟังชั่น On load


        private void frmMain_Load(object sender, EventArgs e)
        {
            this.Hide();
            timer1.Start();
            dlgLogin dlg = new dlgLogin();
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                this.CurrentUser = dlg.CurrentUser;
                if (this.CurrentUser != null)
                {
                    lblLogonUser.Text = "Logon User : " + this.CurrentUser.Username;
                }
                this.Show();
            }
            else
            {
                Application.Exit();
            }
        }

ถ้า เราคลิกปุ่ม OK คลาส dlgLogin จะ return ค่า DialogResult.OK มีโค๊ดดังนี้

public partial class dlgLogin : Form
    {
        public User CurrentUser { get; set; }
        SampleEntities db;

        public dlgLogin()
        {
            InitializeComponent();
            db = new SampleEntities();
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            // Authen user
            var result = from it in db.Users
                         where it.Username == txtUsername.Text && it.Password == txtPassword.Text
                         select it;


            if (result != null && result.Count() > 0)
            { // Pass
                CurrentUser = result.First();
                this.DialogResult = System.Windows.Forms.DialogResult.OK;
            }
            else
            {
                MessageBox.Show("Username หรือ Password ไม่ถูกต้อง", "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
        }

        private void txtUsername_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                txtPassword.Select();
            }
        }

        private void txtPassword_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                btnLogin.PerformClick();
            }
        }
    }
โค๊ด LINQ ในการเช็คค่า username password คือ
var result = from it in db.Users
                         where it.Username == txtUsername.Text && it.Password == txtPassword.Text
                         select it;

แปลงได้ ภาษา SQL คือ “SELECT * FROM USERS WHERE USERNAME == username AND PASSWORD == password ซึ่งหากค่าที่ return กลับไม่เป็น 1 แสดงว่า มียูเซอนั้นและการ Authen สำเร็จ
กลับมาที่หน้า Class หลัก frmMain.cs เพื่อ ปุ่มลงไปข้างบน ชื่อว่า User  เพื่อดึงเอาข้อมูล User มาแสดง โดยสร้าง Class ใหม่ขึ้นมาชื่อว่า “frmUsers.cs” (add new item > windows form) ซึ่งมีโค๊ดดังนี้


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 SampleWinForm.Forms
{
    public partial class frmUserList : Form
    {

        public frmUserList()
        {
            InitializeComponent();
        }

        private void frmUserList_Load(object sender, EventArgs e)
        {
            DoLoadData();
        }

        private void DoLoadData()
        {
            using (var db = new SampleEntities())
            {
                List<User> users = (from it in db.Users
                                    select it).ToList();

                gridControl.DataSource = users;
            }
        }

        private void gridView_RowClick(object sender, DevExpress.XtraGrid.Views.Grid.RowClickEventArgs e)
        {
            List<User> users = gridControl.DataSource as List<User>;
            if (users == null)
                return;

            User user = users[gridView.FocusedRowHandle];
            frmUserInfo frm = new frmUserInfo();
            frm.UserID = user.UserID;
            if (frm.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
                DoLoadData();
            }
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {

            using(var db = new SampleEntities()){

                frmUserInfo frm = new frmUserInfo();
                frm.UserID = 0;

                if (frm.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
                {
                    DoLoadData();
                }

               }
           
           
        }
    }
}

ฟังชั่น DoLoadData จะถูกเรียกขึ้นใหม่ทุกครั้งเมื่อมีการเรียกใช้ และแสดงข้อมูลในกริด อย่าลืมสร้างปุ่ม add ไว้เพิ่ม user ใหม่ ซึ่งต้องสร้าง class ใมห่ชื่อว่า frmUserInfo.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 SampleWinForm.Forms
{
    public partial class frmUserInfo : Form
    {
        public int UserID = 0;
        SampleEntities db = new SampleEntities();

        public frmUserInfo()
        {
            InitializeComponent();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = System.Windows.Forms.DialogResult.Cancel;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            User user = null;

            if (UserID == 0)
            {
                user = new User();
                db.Users.Add(user);
            }
            else
            {
                var result = (from it in db.Users
                             where it.UserID == UserID
                             select it).ToList();
                if (result.Count() > 0)
                {
                    user = result.First();
                }
            }

            user.Username = txtUsername.Text;
            user.Password = txtPassword.Text;
            user.Email = txtEmail.Text;
            if (db.SaveChanges() > 0)
            {
                DialogResult = System.Windows.Forms.DialogResult.OK;
            }
            else
            {
                MessageBox.Show("Save Failed.");
            }
        }

        private void frmUserInfo_Load(object sender, EventArgs e)
        {
            if (UserID > 0)
            {
                var result = (from it in db.Users
                              where it.UserID == UserID
                              select it).ToList();
                if (result.Count() > 0)
                {
                    txtUsername.Text = result.First().Username;
                    txtPassword.Text = result.First().Password;
                    txtEmail.Text = result.First().Email;
                }
            }
        }
    }
}

เดียวเพิ่มเติมให้กับหน้า LogIn >> บทความนี้ ละเอียดยังไม่พอ ยังไง ก็ติดตามกันด้วยนะครับ

May be like this posts