Search This Blog

Friday, December 11, 2009

Protecting Flash Memory of a Fujitsu MCU

တစ်လောက Fujitsu MB95F128JB ရဲ့ flash memory ကို ကာကွယ် ဖို့ အတွက် သင့်တော်တဲ့ နည်းလမ်း ရှာ ကြည့် တော့ စိတ်ကြိုက် မတွေ့ခဲ့ပါဘူး။ နောက်တော့ သူ့ရဲ့ .mhx ဖိုင်ကို ပြင်ကြည့် ဖို့ စိတ်ကူးရပါတယ်။ ဖိုင်ရဲ့ နောက်ဆုံးလိုင်း ရဲ့ ရှေ့ မှာ အောက်ပါ လိုင်းကို ဖြည့်လိုက်ရင် အဆင်ပြေသွား ပါလိမ့်မယ်။
S104400001BA
Ref: http://en.wikipedia.org/wiki/SREC_%28file_format%29

Saturday, October 10, 2009

Multidrop network for RS232

တစ်ခါက project တစ်ခုမှာ master device တစ်ခုနဲ့ slave device ရှစ်ခု ဆက်သွယ်ပြီး communicate လုပ်ဖို့ လိုလာပါတယ်။ အစက RS485 half-duplex communication သုံးဖို့ ရည်ရွယ်ထား ပေမယ့် ဖြစ်ချင်တော့ ရောက်လာ ပြီးသား ပစ္စည်း အားလုံးက RS232 interface တွေပဲ ရှိကြတယ်။ RS232 communication က ပစ္စည်း တစ်ခု တစ်ခု ချင်းဆက်ဖို့ပါ။ တစ်ကယ်လို့ master device တစ်ခုက ပဲ ပို့ပြီး ကျန်တဲ့ slave တွေက နားပဲထောင် နေရင် ပြသနာ မရှိပေမယ့် slave တွေရဲ့ transmit line တွေက disable ဖြစ်အောင် ပိတ်ထားလို့ မရတဲ့ အတွက် master device ဆီကို ပြန်ပို့ဖို့ ဝါယာ လိုင်း တစ်ခုထဲကို တိုက်ရိုက် သွားဆက်လို့ မရပါဘူး။ သူ့တို့ရဲ့voltage အဝင်အထွက် တွေကို ကြည့်ပြီးတဲ့ အခါမှာတော့ အဲဒီ ပြသနာကို ဖြေရှင်းဖို့ နည်းလမ်းတစ်ခု ကို စဉ်းစားမိ ပါတယ်။ slave တစ်ခုချင်း စီရဲ့ transmit line တွေမှာ diode တစ်ခုစီ ထည့်ပေးလိုက်ရင် RS485 half-duplex communication လိုပဲ ဆက်သွယ်လို့ ရမယ့် hardware connection တစ်ခုကို ရရှိနိုင်ပြီး အဲဒါကိုအောက်က ပုံမှာ ကြည့်နိုင်ပါတယ်။
Updated: 2017 Sep 02
မှတ်ချက် ရေးကြ၊ မေးကြ တဲ့ ပေါ်မူ တည်ပြီး နောက်ထပ် ဆက်လို့ ရတဲ့ ပုံစံ တွေထပ် ဖြည့်လိုက် ပါတယ်။ စိတ်ဝင်စား ကြတဲ့ အတွက် ကျေးဇူး တင် ပါတယ်။

RS232 network with multiple masters and multiple slaves



UART/TTL-Serial network with single master and multiple slaves

RS232 transceivers တွေ မသုံးပဲ UART ကအထွက် TTL level signal တွေကိုပဲ သုံးမယ် ဆိုရင်တော့ အောက် ကအတိုင်း ဆက်နိုင် ပါတယ်။



UART/TTL-Serial network with multiple masters and multiple slaves



Friday, September 25, 2009

CRC Calculation in VB and C

CRC -Cyclic Redundancy Check ကို တွက်ထုတ် ဖို့ အတွက် Visual Basic 2005 နဲ့ C ကို သုံးပြီး ရေးထားတဲ့ code တချို့ပါ။

CRC Calculation in VB2005

CRC Calculation အချို့အတွက် Visual Basic 2005 source code များကို အောက်ပါ လင့်ခ် မှာတွေ့နိုင်ပါတယ်။ Calculation ကို ပိုမြန်စေဖို့ အတွက် table ကို သုံးပြီး တွက်ထားပါတယ်။


CRC Calculation - GitHub

ဥပမာ အနေနဲ့ CRC16 CCITT Calculation နမူနာ တစ်ခုကို အောက်မှာ ပြထားပါတယ်။

Dim StrIn as String= "String to calculate CRC"
Dim CRCVal16 As UInt16 = 0
Dim crc As String
CRCVal16 = CRC16_CCITT.Calculate(StrIn)
crc = CRC16_CCITT.ToString(CRCVal16)

CRC16 CCITT ရဲ့ initial value က 0xFFFF ဖြစ်ပြီး သူ့ ကို အခြား တန်ဖိုး နဲ့ စသုံးချင်ရင်တော့ အောက်ပါအတိုင်း သုံးနိုင်ပါတယ်။

CRCVal16 = CRC16_CCITT.Calculate(Str1)
CRCVal16 = CRC16_CCITT.Calculate(Str2, CRCVal16)
crc = CRC16_CCITT.ToString(CRCVal16)

CRC Calculation in C

CRC Calculation အချို့အတွက် C source code များကို အောက်ပါ လင့်ခ် မှာတွေ့နိုင်ပါတယ်။ Storage သုံးတာ သက်သာအောင် table ကို မသုံးပဲ တွက်ထားပါတယ်။


CRC Calculation - GitHub

ဥပမာ အနေနဲ့ CRC16 CCITT Calculation နမူနာ တစ်ခုကို အောက်မှာ ပြထားပါတယ်။

#define STRLEN 4
char str[STRLEN]={0x01,0x01,0x00,0x0B};
unsigned char c[2];
unsigned int crc;
//Calculate CRC16 CCITT
crc=CRC16CCITT_InitialValue();
crc=CRC16CCITT_Calculate(str,STRLEN,crc);
CRC16CCITT_ToString(crc,c);
printf("CRC16 CCITT = %02X %02X \n",c[0],c[1]);


အောက်ကလို Online checksum calculator တွေကလည်း ကုဒ်တွေကို debug လုပ်တဲ့ အခါ အသုံးကျပါတယ်။

Online Checksum Calculator

Tuesday, August 18, 2009

SDCC - Small Device C Compiler

SDCC - Small Device C Compiler က အလကား ရနိုင်တဲ့ free open source C compiler ပါ။ သူက 8051 နဲ့ အခြား microcontroller အချို့အတွက်ပါ။ SDCC လို အလကား မဟုတ်ပဲ ပိုက်ဆံ ပေးဝယ်ရတဲ့ အခြား Keil တို့လို compiler တွေလဲ ရှိပါတယ်။ အဲဒီမှာ free evaluation version ကိုရနိုင်ပေမယ့် အစမ်းသဘော အတွက်ပဲ ရည်ရွယ်ပြီး code size ကို 2k byte ထက် ပိုသုံးလို့ မရအောင် ကန့်သတ်ထားပါတယ်။ SDCC ရဲ့ကောင်းတဲ့ အချက်ကတော့ ပိုက်ဆံ တစ်ပြားမှ မကုန်ပဲ အလကား ရနိုင်တာပါ။ ဒီမှာ ပြောမှာ ကတော့ SDCC manual ကို အကျဉ်းချုံး ထုတ်နုတ်ပြော တာပါ။

Installing
http://sdcc.sourceforge.net/ ကိုသွားပြီး setup program ကို download လုပ်နိုင်ပါတယ်။ နောက် setup program ကို Run ပါ။

Testing the SDCC Compiler
နောက် command prompt ကိုသွားပြီး compiler အလုပ် လုပ်မလုပ် စမ်းကြည့်ဖို့ "sdcc -v" ကို enter လုပ်ပါ။ SDCC ကသူ့ရဲ့ ဗားရှင်း နံပါတ်ကို reply ပြန်တာ ကို တွေ့ ရပါလိမ့် မယ်။

Example C Program
အောက် ပါ နမူနာ program ကို စိတ်ကြိုက် ASCII editor တစ်ခုခု သုံးပြီး ရိုက်ပါ။ ထို့နောက် led.c အမည်ဖြင့် သိမ်းပါ။ Eclipse အစရှိတဲ့ development IDE တွေသုံးလို့ လဲရပါတယ်။ အဲဒီ အကြောင်း ကြုံရင် ပြောပါမယ်။ ဒီနမူနာ က 8051 microcontroller ရဲ့ P3.4 pin ကိုဆက်သွယ်ထား တဲ့ LED ကို မှိတ်တုပ် မှိတ်တုပ် အဖွင့် အပိတ် လုပ်ပေးဖို့ ပါ။
#include<8052.h>
void main()
{
int i;
while(1)
{
P3_4=0;   //Output 0
for(i=0;i<30000;i++);  //delay loop
P3_4=1;   //Output 1
for(i=0;i<30000;i++);  //delay loop
}
}


Compiling and Getting Hex File
command prompt မှာ ဖိုင် led.c ရှိတဲ့ နေရာကို သွားပြီး "sdcc led.c" ကို enter လုပ်ပါ။ အားလုံး အဆင်ပြေရင် အမှား မတက်ပဲ led.ihx ဆိုတဲ့ဖိုင် ထွက်လာပါမယ်။ "dir" ကို enter လုပ်ပြီး အဲဒီဖိုင် ထွက်မထွက် ကြည့်နိုင်ပါတယ်။ နောက် သင့်ရဲ့ chip ထဲကို download လုပ်ဖို့ သင့်တော်တဲ့ intel hex file ရအောင် "packihx led.ihx>led.hex" ကို enter လုပ်ပါ။ ထွက်လာတဲ့ led.hex ကို သုံးလို့ ရပါပြီ။

Projects with Multiple Source Files
SDCC က တစ်ကြိမ်မှာ တစ်ဖိုင် ပဲ compile လုပ်ပေးနိုင်ပါတယ်။ ဥပမာ main.c blink.c ဆိုတဲ့ ဖိုင်တွေရှိ တဲ့ project ကို စမ်းဖို့ အောက်ပါ အတိုင်း ရိုက်ထည့်ပြီး ဖိုင် များကို ဖန်တီးပါ။
//File name: main.c
#include "blink.h"
void main()
{
while(1)
{
toggle();
delay();
}
}


//File name: blink.c
#include <8052.h>
#include "blink.h"
void toggle()
{
P3_4^=1;
}
void delay()
{
int i;
for(i=0;i<30000;i++); //delay loop
}


//File name: blink.h
void toggle();
void delay();

main() function မပါတဲ့ ဖိုင်များကို "sdcc -c blink.c" ဆိုတဲ့ command သုံးပြီး သပ်သပ် compile လုပ်ပါ။ နောက် main() function ပါတဲ့ ဖိုင်ကို နောက်ဆုံးမှ "sdcc main.c blink.rel" ဆိုတဲ့ ပုံစံ အတိုင်း compile လုပ်နိုင်ပါတယ်။ main.ihx ဆိုတဲ့ ဖိုင်ထွက်လာမှာ ဖြစ်ပြီး ထုံးစံ အတိုင်း main.hex ကို ရယူ အသုံးပြု နိုင်ပါတယ်။

Monday, March 16, 2009

String and ASCII Code Conversion in VB 2005

ကျွန်တော်တို့ အခါအားလျော်စွာ သုံးဖို့ လိုတဲ့ ASCII code နဲ့ string အပြန် အလှန် ပြောင်းလဲတဲ့ ဖန်ရှင်လေး တွေကို ရေးကြည့်ထား ပါတယ်။ အဲဒါ ကို A Visual Basic class to convert between hexadecimal, ascii, and text string on GitHub မှာ ယူနိုင်ပါတယ်။
'Author: Yan Naing Aye
'WebSite: http://cool-emerald.blogspot.sg/
'Updated: 2009 April 24
'-----------------------------------------------------------------------------
Public Class ClsMyStr
    Public Shared Function AsAsciiEncodedStr(ByVal CharString As String) As String
        Dim outS As String = ""
        Dim temp As String = ""
        Dim i As Integer = 0
        For i = 0 To CharString.Length - 1
            temp = "00" & Hex(Asc(CharString(i)))
            temp = Right(temp, 2)
            outS = outS & temp
        Next i
        Return outS
    End Function
    Public Shared Function AsSpacedAsciiEncodedStr(ByVal CharString As String) As String
        Dim outS As String = ""
        Dim temp As String = ""
        Dim i As Integer = 0
        For i = 0 To CharString.Length - 1
            temp = "00" & Hex(Asc(CharString(i)))
            temp = Right(temp, 2)
            outS = outS & temp & " "
        Next i
        Return outS
    End Function
    Public Shared Function AsAsciiDecodedStr(ByVal AsciiEncodedStr As String) As String
        Dim outS As String = ""
        Dim i As Integer = 0
        Dim l As Integer = AsciiEncodedStr.Length - 2

        If (AsciiEncodedStr.Length Mod 2) <> 0 Then
            l -= 1
        End If
        For i = 0 To l Step 2
            outS = outS & Chr(Val("&H" & AsciiEncodedStr.Substring(i, 2)))
        Next i
        Return outS
    End Function
    Public Shared Function GetAsciiEncodedStr(ByVal RawAsciiEncodedStr As String) As String
        Dim i As Integer = 0
        Dim c As String
        Dim cmd As String = ""

        For i = 0 To RawAsciiEncodedStr.Length - 1
            c = RawAsciiEncodedStr(i)
            If (Asc(c) >= &H30) AndAlso (Asc(c) <= &H39) Then
                cmd = cmd & c
            ElseIf (Asc(c) >= &H41) AndAlso (Asc(c) <= &H5A) Then
                cmd = cmd & c
            ElseIf (Asc(c) >= &H61) AndAlso (Asc(c) <= &H7A) Then
                cmd = cmd & Chr(Asc(c) - &H20) 'change to upper case
            Else
                'MessageBox.Show("Got invalid character.")
            End If
        Next i
        If cmd.Length < 2 Then
            cmd = "0" & cmd
        End If
        Return cmd
    End Function
    Public Shared Function DoubleQuote() As String
        Return ControlChars.Quote
    End Function
    Public Shared Function Byte2Text(ByVal byteArray() As Byte) As String
        Dim str As String = BitConverter.ToString(byteArray)
        Return str
    End Function
    Public Shared Function Byte2Str(ByVal byteArray() As Byte) As String
        'Dim str As String = System.Text.Encoding.ASCII.GetString(byteArray)
        Dim str As String = ""
        For i As Integer = 0 To UBound(byteArray)
            str &= Chr(byteArray(i))
        Next
        Return str
    End Function
    Public Shared Function Str2Byte(ByVal str As String) As Byte()
        'Dim ba() As Byte = System.Text.Encoding.ASCII.GetBytes(str)
        Dim ba() As Byte
        Try
            ReDim ba(str.Length - 1)
            For i As Integer = 0 To UBound(ba)
                ba(i) = Asc(str(i))
            Next
        Catch ex As Exception
            ReDim ba(0)
            ba(0) = 0
        End Try        
        Return ba
    End Function
    Public Shared Function GetSignedDecimalText(ByVal RawStr As String) As String
        Dim i As Integer = 0
        Dim c As String
        Dim cmd As String = ""

        For i = 0 To RawStr.Length - 1
            c = RawStr(i)
            If (Asc(c) >= &H30) AndAlso (Asc(c) <= &H39) Then
                cmd = cmd & c
            ElseIf (Asc(c) = &H2D) Then
                If cmd.Length = 0 Then
                    cmd = cmd & c
                End If
            Else
                'MessageBox.Show("Got invalid character.")
            End If
        Next i        
        Return cmd
    End Function
End Class

Sunday, February 22, 2009

Reading and Writing a File in VB 2005


တစ်ခါ တလေ Visual Basic 2005 ကိုသုံးပြီး ဖိုင်တွေရေးဖို့ ဖတ်ဖို့ လိုတတ်ပါတယ်။ အဲဒီ အခါ အလွယ်တကူ ကိုးကားလို့ရအောင် တစ်ချို့ ကုဒ်လေးတွေ ကို တင်လိုက်ပါတယ်။ အောက်က နမူနာ နှစ်ခုကတော့ ဒီနေရာက နေ ကိုးကားထားတာပါ။
Dim objStreamReader As StreamReader
Dim strLine As String

'Pass the file path and the file name to the StreamReader constructor.
objStreamReader = New StreamReader("C:\Boot.ini")

'Read the first line of text.
strLine = objStreamReader.ReadLine

'Continue to read until you reach the end of the file.
Do While Not strLine Is Nothing
  'Write the line to the Console window.
  Console.WriteLine(strLine)

  'Read the next line.
  strLine = objStreamReader.ReadLine
Loop

'Close the file.
objStreamReader.Close()

Dim objStreamWriter As StreamWriter

'Pass the file path and the file name to the StreamWriter constructor.
objStreamWriter = New StreamWriter("C:\Testfile.txt")

'Write a line of text.
objStreamWriter.WriteLine("Hello World")
'Write a second line of text.
objStreamWriter.WriteLine("From the StreamWriter class")

'Close the file.
objStreamWriter.Close()


ဖိုင်ကိုသုံးနေတုန်း error တက်ခဲ့ရင် တော့ သုံးလက်စ ဖိုင်ကို မပိတ်နိုင်ပဲ ထွက်သွားတာမျိုး ဖြစ်နိုင်ပါတယ်။ အဲဒါကို တားဆီးဖို့ ကတော့ Try ... Finally ကိုအောက်ပါအတိုင်း သုံးနိုင်ပါတယ်။

Dim strLine As String
Dim sr As StreamReader = Nothing
Try
    sr = New StreamReader(fileName)
    strLine = sr.ReadToEnd()
Finally
    sr.Close()
End Try



Visual Basic 2005 မှာ Using ဆိုတဲ့ statement အသစ် က IDisposable object တွေကို အလိုအလျောက် release လုပ်ပေးနိုင်ပါတယ်။ Exception တစ်ခုခု ဖြစ်ရင် သူ့ရဲ့ caller ဆီကိုရောက်သွားမှာပါ။ အကယ်၍ အဲဒီ exception ကို ကိုယ့်ဟာကိုယ် catch လုပ်ချင်ရင်တော့ Try ... Catch ... Finally block ကိုပဲ သုံးရမှာပါ။

Dim strLine As String
Using sr As New StreamReader(fileName)
    strLine = sr.ReadToEnd
End Using


ဖိုင်ဖတ်တဲ့ အခါ ပိုပြီးလွယ်ကူ ရှင်းလင်း ချင်ရင် File.ReadAllText or File.ReadAllBytes static method ကိုသုံးလို့လဲ ရပါတယ်။
Log File

Log files တွေ အလွယ်တကူ ရေးဖို့ class တစ်ခု ကို ရေးကြည့် ထားပါတယ်။ သူ့ရဲ့ ကုဒ်တွေကို VB class for log file on GitHub ကနေ ယူလို့ သုံးလို့ ရပါတယ်။
'Author: Yan Naing Aye
'WebSite: http://cool-emerald.blogspot.sg/
'Updated: 2009 June 25
'-----------------------------------------------------------------------------
Imports System.IO
Public Class ClsLog
    Private mEnableLog As Boolean = False
    Private mLogFileDirectory As String = ""
    Private mLogFilePath As String = ""
    Private mLogFileLifeSpan As Integer = 0
    Private mLogFileFirstName As String = "AppName"
    Public Sub New()
        mEnableLog = False
        mLogFileDirectory = My.Application.Info.DirectoryPath
        mLogFileLifeSpan = 0
        mLogFileFirstName = My.Application.Info.AssemblyName
    End Sub
    Public Property LogFileLifeSpan() As Integer
        Get
            Return mLogFileLifeSpan
        End Get
        Set(ByVal value As Integer)
            mLogFileLifeSpan = IIf(value >= 0, value, 0)
        End Set
    End Property
    Public Property LogFileFirstName() As String
        Get
            Return mLogFileFirstName
        End Get
        Set(ByVal value As String)            
            mLogFileFirstName = value
        End Set
    End Property
    Public Property LogEnable() As Boolean
        Get
            Return mEnableLog
        End Get
        Set(ByVal value As Boolean)
            If value = True Then
                If Directory.Exists(Me.LogFileDirectory) Then
                    mEnableLog = value
                Else
                    mEnableLog = False
                    Throw New Exception("Invalid file directory.")
                End If
            Else
                mEnableLog = value
            End If
        End Set
    End Property
    Public Property LogFileDirectory() As String
        Get
            Return mLogFileDirectory
        End Get
        Set(ByVal value As String)
            value = Trim(value)
            If Directory.Exists(value) Then
                Dim i As Integer = value.Length - 1
                If (((value(i)) = "\") OrElse ((value(i)) = "/")) Then
                    value = value.Substring(0, i)
                End If
                mLogFileDirectory = value
            Else
                Throw New Exception("Invalid file directory.")
            End If
        End Set
    End Property
    Public ReadOnly Property LogFilePath() As String
        Get
            Return mLogFileDirectory & "\" & mLogFileFirstName & Format(Now, "-yyyy-MMM-dd") & ".log"
        End Get
    End Property
    Public Sub WriteLog(ByVal LogEntry As String)
        If mEnableLog = True Then
            mLogFilePath = mLogFileDirectory & "\" & mLogFileFirstName & Format(Now, "-yyyy-MMM-dd") & ".log"
            Dim objStreamWriter As StreamWriter = New StreamWriter(mLogFilePath, True)
            Try
                objStreamWriter.WriteLine(LogEntry)
            Catch ex As Exception
            Finally
                objStreamWriter.Close()
            End Try
        End If
    End Sub
    Public Sub WriteTimeAndLog(ByVal LogEntry As String)
        WriteLog(Now.ToLongTimeString & " " & LogEntry)
    End Sub
    Public Sub CleanupFiles()
        If mLogFileLifeSpan > 0 Then 'if life span is zero, there will be no cleaning up
            Try
                Dim LogFiles() As String = Directory.GetFiles(mLogFileDirectory)
                For Each LogFile As String In LogFiles
                    If (DateDiff("d", File.GetLastWriteTime(LogFile), Now) > mLogFileLifeSpan) _
                    AndAlso (Right(LogFile, 4) = ".log") Then
                        File.Delete(LogFile)
                    End If
                Next
            Catch ex As Exception
            End Try
        End If
    End Sub
End Class

Sunday, February 1, 2009

FAT32 Format

ကျွန်တော့် removable hard disk ကို Windows ရော Linux စက်တွေမှာပါ သုံးချင်ပေမယ့် ပြဿနာက Linux မှာ NTFS ကသုံးလို့မရ၊ Windows XP မှာကျတော့ FAT32 နဲ့ format ချလို့မရပြန်။ "format x: /fs:fat32" command ကို Windows XP မှာ သုံးတော့ ကျွန်တော့် removable hard disk က 32 GB ထက်ပိုကြီးလို့ မရဘူးတဲ့။ အကြာကြီးစောင့် ပြီးမှ error message နဲ့ အဆုံးသတ်သွားတယ်။ Windows Vista မှာပါတဲ့ FAT32 နဲ့ format ချကြည့် တော့လည်း အဲဒါကြီးက Linux မှာအလုပ် မလုပ်ပြန်ဘူး။ နောက်ဆုံးတော့ fat32format.exe ဆိုတဲ့ freeware program သေးသေးလေးနဲ့ အလုပ်ဖြစ်သွားတယ်။ တော်တော်မြန်ပြီး သုံးရလွယ်တယ်။ Drive X ကို format ချ ဖို့ "fat32format X:" ဆိုတာလေး ရိုက်လိုက်ရုံပဲ။ FAT32 သုံးခြင်းအား ဖြင့် တစ်ခြား Mac, Linux, အစရှိတဲ့ operating systems တွေမှာပါ အဲဒီ disk ကို သုံးလို့ ရသွားပါတယ်။

Tuesday, January 20, 2009

Using Notify Icon in Visual Basic 2005


Notify icon ကို system tray မှာ ပေါ်ဖို့ အတွက် VB2005 မှာရေးရတာ VB6 ထက် အများကြီးပိုလွယ်ပါတယ်။ VB2005 မှာ Windows Application တစ်ခုကို ဖန်တီးပါ။ ထို့နောက် အောက်ပါပုံတွင် ပြထားသည့် အတိုင်း NotifyIcon control ကို ထည့်ပါ။

"NotifyIcon1" control ကို Select မှတ်ပါ။ ထို့နောက် သူ့ရဲ့ properties window မှာ "Icon" ကိုရွေးပြီး သင်သုံးချင်တဲ့ icon ကို သတ်မှတ်ပါ။ ဘာ icon မှ သတ်မှတ်မပေးခဲ့ရင် notify icon ကို system tray မှာ မြင်ရမှာ မဟုတ်ပါဘူး။
သင့် application ကို ပိတ်တဲ့ အခါ notify icon ကို ပေါ်စေဖို့ အတွက် အောက်ပါ code များကို FormClosing event တွင်ရေးပါ။

Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing        
          If MessageBox.Show("Do you really want to exit?", "Exit", MessageBoxButtons.YesNo) = Windows.Forms.DialogResult.No Then            
                e.Cancel = True           
                Me.Visible = False
                NotifyIcon1.Visible = True
          End If        
    End Sub 

Notify Icon ကို double click နှိပ်လိုက်ရင် application ကို ပြန်ပေါ်လာစေဖို့ အောက်ပါ code များကို NotifyIcon1 ၏ MouseDoubleClick event တွင်ရေးပါ။

Private Sub NotifyIcon1_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseDoubleClick
          Me.Visible = True ' Show the form.
          Me.Activate() ' Activate the form.
          NotifyIcon1.Visible = False
End Sub

File menu နဲ့ context menu တွေကနေ application ပိတ်လို့ရစေဖို့ အောက်ပါ controls များကိုထည့်ပါ။


ထို့နောက် 'Me.Close()' ကို သူတို့ရဲ့ click event မှာဖြည့်ပါ။

Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
          ' Close the form, which closes the application.
          Me.Close()
End Sub

Private Sub ContextMenuStrip1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ContextMenuStrip1.Click
          Me.Close()
End Sub

Notify Icon ပေါ်မှာ right click နှိပ်တဲ့အခါ pop up menu ပေါ်စေဖို့ NotifyIcon1 control ကို Select မှတ်ပြီး သူ့ရဲ့ ContestMenuStrip property မှာ ContextMenuStrip1 ကိုသတ်မှတ်ပေးပါ။

ပြီးရင် သင့် program ကို run နိုင်ပါပြီ။ ဝင်းဒိုး ကို ပိတ်လိုက်ရင် တစ်ကယ် ထွက်မထွက် မေးဖို့ message box တစ်ခုပေါ်လာမှာ ဖြစ်ပြီး "No" ကိုရွေးရင် system tray ထဲမှာ ကျန်နေပါလိမ့်မယ်။ Notify Icon ကို double click ပြန်နှိပ်ရင် application ပြန်ပေါ်လာမှာဖြစ်ပါတယ်။

Sunday, January 18, 2009

Capturing and Sending Key -Using AJAX

AJAX က programming language အသစ်တစ်ခု မဟုတ်ပါဘူး။ ပိုကောင်း၊ ပိုမြန်၊ ပို interactive ဖြစ်တဲ့ web applications တွေရဖို့ အတွက် နည်းပညာသစ် တစ်ခုပါ။ AJAX ရဲ့ အရေးအပါဆုံး အဓိက object တစ်ခုဖြစ်တဲ့ XMLHttpRequest ကိုသုံးပြီး web server တစ်ခုဆီကို ဒေတာ လှမ်းတောင်းတာ၊ response ပြန်ယူတာတွေကို နောက်ကွယ်ကနေ ဝက်ဘ် စာမျက်နှာကို reload ပြန်လုပ်စရာမလိုပဲ လုပ်ဆောင်နိုင်ပါတယ်။ အဲဒီ ဝက်ဘ် စာမျက်နှာ ကို ဖွင့်သုံးနေသူတောင် ဒေတာ ပို့တာ၊ ယူတာတွေကို သတိပြု မိမှာ မဟုတ်ပါဘူး။ အရင် ပို့စ်မှာ လုပ်ခဲ့ဘူးတဲ့ ကီးဖမ်းတာ၊ ပို့တာ ကိုပဲ AJAX နဲ့ ပြန်ရေးကြည့်ပါမယ်။ ဒီနမူနာကို W3Schools မှာဖော်ပြထားတဲ့ Script များကို အခြေခံပြီး ရေးထားပါတယ်။ keyCapture.html ၊ keyCapture.js ၊ and keyCapture.php ဆိုပြီး သုံးဖိုင်ပါ ပါတယ်။
ပထမဆုံး "keyCapture.html" လို့ခေါ်တဲ့ HTML page တစ်ခု ဖန်တီးပါမယ်။ သူ့မှာ server ကပြန်ပို့တဲ့ စာကို ဖော်ပြဖို့ DIV element တစ်ခု ထည့်ထားပါတယ်။ နောက် သပ်သပ်ခွဲရေးထားတဲ့ JavaScript ဖိုင်ကို head ထဲမှာ ချိတ်ထားပါမယ်။

<html>
<head>
<title>Key Capture</title>
<script src='keyCapture.js'></script>
</head>
<body>
<form>
Press a key to send to server.
<div id='text1' style="font-size: 40px; color:blue;">
</div>
</form>
</body>
</html>

ဒုတိယ အနေနဲ့ ကီးတွေကိုဖမ်းဖို့၊ AJAX ကိုသုံးပြီး server ကိုပို့ဖို့ "keyCapture.js" ဖိုင်ကို အောက်ပါ အတိုင်း ရေးပါမယ်။ နောက်မှာ သူ့ကို အသေးစိတ် ရှင်းထားပါတယ်။

var xmlHttp;
document.onkeypress = DisplayMsg;
function DisplayMsg(key_event) {
    var keyChar;
    if (document.all) {
        keyChar = String.fromCharCode(event.keyCode);
    }
    else if (document.getElementById) {
        keyChar = String.fromCharCode(key_event.which);
    }
    else if (document.layers) {
        keyChar = String.fromCharCode(key_event.which);
    }
    xmlHttp = GetXmlHttpObject();
    if (xmlHttp == null) {
        alert("Your Browser does not support AJAX!");
        return;
    }
    var url = "keyCapture.php";
    url = url + "?keyC=" + keyChar + "&sid=" + Math.random();
    xmlHttp.onreadystatechange = stateChanged;
    xmlHttp.open("GET", url, true);
    xmlHttp.send(null);
}

function stateChanged() { if (xmlHttp.readyState == 4) { document.getElementById('text1').innerHTML = xmlHttp.responseText; } } function GetXmlHttpObject() { var xmlHttp = null; try { // Firefox, Opera 8.0+, Safari xmlHttp = new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } } return xmlHttp; }
ဒီ JavaScript file မှာ ပါတဲ့ အဓိက အပိုင်းသုံးပိုင်း ကတော့
၁။ XMLHttpRequest object ကို ဖန်တီးခြင်း
၂။ ဆာဗာ ကပြန်ပို့တဲ့ ဒေတာ တွေကို သုံးဖို့ function သတ်မှတ်ခြင်း
၃။ ဆာဗာ ကို request လှမ်းပို့ခြင်း
တို့ဖြစ်ပါတယ်။
၁။ XMLHttpRequest object ကို ဖန်တီးခြင်း
ကိုယ်သုံးတဲ့ browser ပေါ်မူတည်ပြီး XMLHttpRequest object ကို ဖန်တီးပုံ ဖန်တီးနည်း ကလည်း အမျိုးမျိုး ကွဲပြားနေပါတယ်။ Internet Explorer က ActiveXObject ကိုသုံးပြီး၊ အခြား browser များက XMLHttpRequest ဆိုတဲ့ JavaScript object ကိုသုံးပါတယ်။ အားလုံးနဲ့ အဆင်ပြေအောင် အောက်ပါအတိုင်း ရေးနိုင်ပါတယ်။
function GetXmlHttpObject()
{
var xmlHttp=null;
try
  {
  // Firefox, Opera 8.0+, Safari
  xmlHttp=new XMLHttpRequest();
  }
catch (e)
  {
  // Internet Explorer
  try
    {
    xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
    }
  catch (e)
    {
    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
return xmlHttp;
}

XMLHttpRequest object ကို သုံးချင်ရင် အခုဒီ GetXmlHttpObject() function ကို အောက်ပါ အတိုင်း ခေါ်သုံးနိုင် ပါတယ်။
var xmlHttp
xmlHttp=GetXmlHttpObject();


အကယ်၍ object ဖန်တီးတာ မအောင်မြင်ရင် AJAX ကိုသုံးလို့ မရကြောင်း စာပေါ်လာဖို့ အောက်ပါ အတိုင်း ရေးနိုင် ပါတယ်။

if (xmlHttp==null)
  {
  alert ("Your browser does not support AJAX!");
  return;
  } 

၂။ ဆာဗာ ကပြန်ပို့တဲ့ ဒေတာ တွေကို သုံးဖို့ function သတ်မှတ်ခြင်း အောက်ပါ JavaScript ကိုသုံးပြီး ဆာဗာ က response status ပြောင်းသွားတိုင်း ခေါ်မယ့် function ကို ရေးသားနိုင်ပါတယ်။ အဲဒီ readyState property မှာ တန်ဖိုး (၀ ကနေ ၄ အထိ) ငါးခု ရှိပြီး request complete state (state value ၄) ကိုရောက်မှ လုပ်ဆောင်အောင် အောက်ပါ အတိုင်း ရေးပါ။


function stateChanged()
{
if (xmlHttp.readyState==4)
{
document.getElementById("txtHint").innerHTML=xmlHttp.responseText;
}
}

ဆာဗာရဲ့ response status ပြောင်းသွားတိုင်း onreadystatechange property မှာသိမ်းထားတဲ့ function ကို အလိုအလျောက် လှမ်းခေါ်မှာ ဖြစ်ပြီး XMLHttpRequest ကို ဖန်တီး အစပြုခဲ့ ပြီးရင် အောက်ပါ အတိုင်း သတ်မှတ် ထားခဲ့ရမှာ ဖြစ်ပါတယ်။

xmlHttp.onreadystatechange=stateChanged;


၃။ ဆာဗာ ကို request လှမ်းပို့ခြင်း
"GET" method ကိုသုံးပြီး request ကို ပို့တိုင်းမှာ လှမ်းပို့တဲ့ ဆာဗာ script ဖိုင်ရဲ့ url နောက်မှာ ? ခံပြီး ပို့ပေးတာကို သတိပြုမိ ကြမှာပါ။ ဒါကြောင့် url ကို အောက်ပါအတိုင်း ပြင်ပြီး တစ်ခါ request လုပ်တိုင်း သိမ်းထားတဲ့ cached version ကို ပြန်မပို့အောင် url မှာ ကြုံရာ ကျဘမ်း တန်ဖိုး နောက်တစ်ခုကို တွဲထည့်ပေး ပါမယ်။


var url = "keyCapture.php";
url = url + "?keyC=" + keyChar + "&sid=" + Math.random();

ဆာဗာကို request ပို့ဖို့ အတွက် XMLHttpRequest object ရဲ့ open() method နဲ့ send() method ကို သုံးနိုင်ပါတယ်။ open() method ရဲ့ ပထမ argument က request လုပ်တဲ့ method ကို GET သုံးမှာလား၊ POST သုံးမှာလား ဆိုတာ သတ်မှတ်ပါ တယ်။ ဒုတိယ တစ်ခုက URL သတ်မှတ်ပြီး၊ နောက်ဆုံး တစ်ခုက request ကို asynchronous လုပ်မလုပ် သတ်မှတ်တာ ဖြစ်ပါတယ်။

xmlHttp.open("GET", url, true);
xmlHttp.send(null);


တတိယ ပိုင်းအနေနဲ့ "keyCapture.php" ဆိုတဲ့ server side script ဖိုင်ကို PHP သုံးပြီး အောက်ပါအတိုင်း ရေးနိုင်ပါတယ်။

<?php
//get the parameter from URL
$k=$_GET["keyC"];
echo "Received: " . $k;
?>

Saturday, January 17, 2009

Capture Key Event in JavaScript

မိတ်ဆွေ တစ်​ယောက်က Linux server တစ်ခုမှာချိတ်ထားတဲ့ hardware တစ်ခုကို အဝေးက web page keyboard input ကနေ ဘယ်လို control လုပ်လို့ရမလဲလို့ မေးလာပါတယ်။ ကျွန်တော်လည်း ကောင်းကောင်းမသိပေမယ့် client ဘက်မှာ JavaScript နဲ့ Server ဘက်မှာ PHP သုံးဖို့ ဆုံးဖြတ်လိုက်ကြပါတယ်။ သူက ထိန်းမယ့် web page မှာ ဖောင်ဖြည့်တာတို့၊ submit လုပ်တာတို့ လုပ်ဖို့ မလိုပဲ ခလုပ်နှိပ်တာနဲ့ တန်းပြီး ပို့စေချင်တယ်တဲ့။ ဒါ့ကြောင့် hardware ကို တိုက်ရိုက်ထိန်းဖို့ ကီးတွေကို တိုက်ရိုက်ဖမ်း ပို့ဖို့လိုလာပါတယ်။ ဂူဂယ်နဲ့ အင်တာနက်မှာ ရှာကြည့်တော့ ဒီနေရာမှာ JavaScript နဲ့ ကီးတွေ ဖမ်းတဲ့ အကြောင်းရေးထားတာ တွေ့ရပါတယ်။ ခုနက script နဲ့ PHP နဲ့ပေါင်းရေးလိုက်တော့ အောက်ပါအတိုင်း key.php ရလာပါတော့တယ်။

<html>
<head>
<script language="JavaScript" type = "text/javascript">
<!--
document.onkeypress = DisplayMsg;
function DisplayMsg(key_event)
{
if (document.all) //Checks for IE 4.0 or later
{
document.form1.text1.value = String.fromCharCode(event.keyCode);
}
else if (document.getElementById) //checks for Netscape 6 or later
{
document.form1.text1.value = String.fromCharCode(key_event.which);
}
else if (document.layers) //Checks for Netscape 4
{
document.form1.text1.value = String.fromCharCode(key_event.which);
}
document.form1.submit();
}
//-->
</script>
<title>Capture Key Pressed</title>
</head>
<body>
<div style="display:none">
<form name="form1" action="key.php" method=GET>
<input type = "text" name = "text1">
</form>
</div>
<div style="font-size: 40px; color:blue;">
<?php
echo "Received: ";
echo $_GET["text1"];
?>
</div>
</body>
</html>


ဒီမှာ အဓိက ပြဿနာ ကတော့ ကီးတစ်ခု နှိပ်လိုက်တိုင်း ဝက်ဘ် စာမျက်နှာ တစ်ခုလုံး အသစ်ပြန်ပြန် ဖွင့်ပြီး reload လုပ်နေရတာ ပါပဲ။ အကယ်၍ အဲဒီစာမျက်နှာမှာ အခြား ရေးထားတာ အများကြီး ပါနေရင် အလုပ်လုပ်တာ အရမ်းနှေးသွား နိုင်ပါတယ်။ ပိုကောင်းတာက AJAX (Asynchronous JavaScript and XML) နည်းပညာကို သုံးတာပါပဲ။