2011年12月25日 星期日

[jQuery] 在datepicker建立清除(clear)按鈕

Ref: http://bugs.jqueryui.com/ticket/3999

$(function () {
    //wrap up the redraw function with our new shiz
    var dpFunc = $.datepicker._generateHTML; //record the original
    $.datepicker._generateHTML = function (inst) {
        var thishtml = $(dpFunc.call($.datepicker, inst)); //call the original
        thishtml = $('<div />').append(thishtml); //add a wrapper div for jQuery context

        //locate the button panel and add our button - with a custom css class.
        $('.ui-datepicker-buttonpane', thishtml).append(
            $('<button class="\
                ui-datepicker-clear ui-state-default ui-priority-primary ui-corner-all\
                "\>清除</button>'
            ).click(function () {
                inst.input.attr('value', '');
                inst.input.datepicker('hide');
            })
        );

        thishtml = thishtml.children(); //remove the wrapper div
        return thishtml; //assume okay to return a jQuery
    };
});



2011年10月18日 星期二

[Oracle] 測試OracleConnection是否正確關閉

  • 若Connection String沒有設定Pooling,預設是開啟(true)。

  • 查詢V$Session檢視connection建立情況:OracleConnection.Open()後會建立一connection, 查詢V$Session會出現一筆資料(需以SYSDBA身份登入)
    SELECT SID, USER#, Serial#, audsid, STATUS,
            SchemaName, OsUser, Process, Machine, Program
    FROM V$Session
    WHERE OsUser='Auser'


  • 關閉connection, 除了OracleConnection.Close()外, 也需要OracleDataReader.Close()(如果有reader的話), 否則connection無法返還至pool.
    以下例子中, 執行reader.Close()後, V$Session不再有connection的資料,
    若reader.Close()未執行, V$Session會有此connection的資料存在.
        public static void RunSample()
        {
            using (OracleConnection conn =
                new OracleConnection(
                "Data Source=dbserver;User ID=auser;Password=auser;Max Pool Size=3"))
            {
                conn.Open();

                using (OracleCommand comm =
                    new OracleCommand(Settings.GetHostsCmd, conn))
                {
                    OracleDataReader reader = comm.ExecuteReader();
                    while (reader.Read())
                    {
                        Console.WriteLine(string.Format("{0} {1} {2}",
                            reader.GetValue(0),
                            reader.GetValue(1),
                            reader.GetValue(2)));
                    }

                    //reader.Close();
                    Console.WriteLine("Done! ");
                }
            }// 離開using scope, Connection會被close.

            // 移除pool內全部的connection.
            // 若只close connection 沒有close reader,
            // connection沒有返還至pool, 因此無法移除此connection. 
            // 在V$Session可以查詢到此connection.
            OracleConnection.ClearAllPools();
        }

2011年7月22日 星期五

[Visual Studio] 無法找到AL.exe (錯誤訊息MSB3084及MSB3086)

使用Visual studio 2010 express測試javascript file多語言,
在加入另一語系的Resources.OO.resx後, 出現以下的錯誤訊息:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2342,9): warning MSB3084: 工作嘗試在以下兩個位置尋找 "AL.exe"。1) 在根據 SdkToolsPath 而產生的 "C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\" (處理器專屬目錄) 底下 2) 在 SDKToolsPath 屬性所指定之 "C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\" 底下的 x86 專屬目錄。您可以執行下列其中一項來解決這個問題:  1) 將 "SDKToolsPath" 屬性設為 Microsoft Windows SDK 的位置。

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2342,9): error MSB3086:
工作無法使用 SdkToolsPath "C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\"
或登錄機碼 "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A" 來尋找 "AL.exe"。請確認已設定 SdkToolsPath、工具存在於 SdkToolsPath 底下的正確處理器專屬位置,以及已安裝 Microsoft Windows SDK。





失敗了很多次才解決此問題,以下是嚐試過的方法(失敗範例):
- 將Resources.OO.resx更名為Resources.OO-00.resx。
http://kgrhash.wordpress.com/2010/12/17/fix-task-could-not-find-al-exe-using-the-sdktoolspath/

- 尋找AL.exe(在C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin底下),將它複製到
C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin。

- 修改註冊表,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A的InstallationFolder="C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\"。

- 安裝完整版的.Net Framework 4.0,http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=0a391abd-25c1-4fc0-
919f-b21f31ab88b7。

以上皆是失敗的示範 (頭大)。



最後找到的解法:
1. 安裝SDK for Windows 7 and .NET Framework 4,
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=8279

2. 修改註冊表:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0底下有3處的值以"v7.1"取代"v7.0A"的部分,
FrameworkSDKRoot=$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1@InstallationFolder)
SDK35ToolsPath=$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx35Tools-x86@InstallationFolder)
SDK40ToolsPath=$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools-x86@InstallationFolder)

之後便能在加入Resources.OO.resx時,順利建置。

2011年7月7日 星期四

C# 將圖檔/Imaget轉換為byte array

以下是2種方式的測試結果,
一是使用FileStream讀入圖檔,
另一是使用System.Drawing.Image讀入圖檔。
           
        // 先將圖檔讀到FileStream, 再轉換為byte array。
        private static void ToBinaryByFileStream(string imageFile)
        {
            FileStream fs = new FileStream(imageFile, FileMode.Open);
            byte[] buffer = new byte[fs.Length];
            fs.Read(buffer, 0, buffer.Length);
            fs.Close();
        }

        // 先將圖檔讀到Image object, 再轉換為byte array。
        private static void ToBinaryByImageObj(string imageFile)
        {
            System.Drawing.Image image = System.Drawing.Image.FromFile(imageFile);
            MemoryStream mr = new MemoryStream();
            image.Save(mr, System.Drawing.Imaging.ImageFormat.Png);
            byte[] binaryImage = mr.ToArray();
            mr.Dispose();
            image.Dispose();
        }

// 測試method。 
public static void ConvertImageToBinary()
        {
            Console.WriteLine("=== Convert the image file to the binary object. ===");

            string imageFolder = @"D:\Images";
            // 測試的image數量。
            int sampleCount = 100;

            string[] imagePaths = Directory.GetFiles(imageFolder, "*.png");
            if (0 == imagePaths.Length)
            {
                Console.WriteLine("No image found.");
                return;
            }

            Stopwatch sw = new Stopwatch();

            sw.Reset();
            sw.Start();
            for (int i = 0; i < sampleCount; i++)
            {
                ToBinaryByFileStream(imagePaths[i]);
            }
            sw.Stop();
            Console.WriteLine("By FileStream: {0} ms.",
                sw.ElapsedMilliseconds);

            sw.Reset();
            sw.Start();
            for (int i = 0; i < sampleCount; i++)
            {
                ToBinaryByImageObj(imagePaths[i]);
            }
            sw.Stop();
            Console.WriteLine("By System.Drawing.Image: {0} ms.",
                sw.ElapsedMilliseconds);
        }


測試100張圖檔的結果

Unit: ms

By FileStream
152
By System.Drawing.Image
2692


Image object會讀取圖檔的相關資訊,
相對地,FileStream只作資料的搬移,所以效能上會快很多。

在Excel中 將秒數轉換成時分秒

使用Excel記錄測試數據時,當這些數據皆是以秒數為單位時,
換算成時分秒後會比較清楚感受到時間的經過,
因此寫個巨集來轉換這些數據。

1. 開啟Excel
2. 按下Alt + F11 (或 工具 -> 巨集 -> Visual Basic 編輯器)
3. 開啟Visual Basic編輯器後,在工具列選擇 插入 -> 模組 ,來新增一個模組。
4. 輸入以下的程式碼:
   Function ConvertToTimespan(Seconds) As Variant
        '取得時分秒的數值
        HourDigit = Int(Seconds / 3600)
        MinuteDigit = Int((Seconds - HourDigit * 3600) / 60)
        SecondDigit = Seconds - HourDigit * 3600 - MinuteDigit * 60
       
        '顯示格式為: "10h 0m 32s"
        '當數值存在才顯示,例輸入秒數換算後為0時14分,則結果會是"14m 0s"。
        result = ""
        If (HourDigit > 0) Then
            result = result & HourDigit & "h "
        End If
           
        If (MinuteDigit <= 0) Then
            If (HourDigit > 0) Then result = result & MinuteDigit & "m "
        Else
            result = result & MinuteDigit & "m "
        End If
       
        result = result & SecondDigit & "s "       
        ConvertToTimespan = result
   End Function

5. 關閉Visual Basic 編輯器回到Excel。
    使用方式與一般函數相同(eg: SUM),
    在Excel的儲存格內輸入"=ConvertToTimespan(A1)"。

結果:

46
850
4000
46s
14m 10s
1h 6m 40s


   

2011年7月4日 星期一

.Net 語音應用程式

在Win7環境下開發語音應用程式:SAPI 已包含在win7內,不用另外安裝。
執行畫面:


加入Reference:
System.Speech.Synthesis:文字語音轉換器
Microsoft.VisualBasic:繁簡體轉換


    public partial class Form1 : Form
    {
        SpeechSynthesizer m_Speaker; // 文字語音轉換器。 
        public Form1()
        {
            InitializeComponent();
            m_Speaker = new SpeechSynthesizer();
        }

        // 朗讀英文句子。
        private void buttonReadEng_Click(object sender, EventArgs e)
        {
            // 設定語音為英文。
            m_Speaker.SelectVoice("Microsoft Anna"); 
            m_Speaker.SpeakAsync(this.buttonReadEng.Text);
        }

        // 朗讀中文句子。
        private void buttonReadCht_Click(object sender, EventArgs e)
        {
            // 中文語音部分,系統預設為簡體中文。
            m_Speaker.SelectVoice("Microsoft Simplified Chinese");
            // 將原本繁體文字轉為簡體,SpeechSynthesizer才能辨識。
            // 輸入文字(繁體),轉換類型,區域設定ID(zh-cn)。
            string simCht = Strings.StrConv(
                buttonReadCht.Text, VbStrConv.SimplifiedChinese, 2052); 
            m_Speaker.SpeakAsync(simCht);
        }
    }


參考:
SAPI介紹:http://www.cnblogs.com/TravelingLight/archive/2010/12/09/1901300.html
在XP的環境下:http://www.chncms.com/2010/12/2/DOTNETVOICESPEACH.html
Local ID:http://msdn.microsoft.com/en-us/library/0h88fahh.aspx

2011年5月17日 星期二

【成語】吉光片羽

吉光:古代神话中的神兽名;片羽:一片毛。比喻残存的珍贵文物。


參照:http://www.zdic.net/cy/ch/ZdicE5Zdic90Zdic8912010.htm

漢典:http://www.zdic.net/
很豐富的線上字詞典, 除了解釋與出處外, 讀音還包涵拼音及注音, 方便查詢對照,
尚可使用它來查詢輸入法的字根.

2011年5月16日 星期一

C# 辨斷Form/UserControl在Design mode?

使用VS時, 在Designer查看Form, 或將UserControl拉進designer,
會因為一些初始操作而產生exception, 像使用外部資源(資料庫連線)等,
這些操作其實在design模式並不需要,
那要如何辨斷Form/UserControl是在Design模式下, 進而忽略這些操作呢?

可以使用Form/UserControl的屬性, DesignMode.
DesignMode在使用上有限制, 它在constructor內無效(always return false),
於是我們將一些design模式下不需要的操作移到load handler裡,
當它是design模式就直接return, 忽略掉這些操作:


        public Form1()
        {
            InitializeComponent();

            // Load handler
            this.Load += new EventHandler(Form1_Load);
        }

        void Form1_Load(object sender, EventArgs e)
        {
           
            if (this.DesignMode) // 如果是design模式, 直接return.
                return;
           
            // Design模式下不需要的操作, eg: 資料庫連線
        }