<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" 
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Bug Captor の 開發日記帳-.Net Framework</title>
<link>http://blog.roodo.com/toki_kanno/archives/cat_124034.html</link>
<description>一些開發程式時的碎碎唸，先找個地方記起來免的忘記</description>
<language>zh-tw</language>
<generator>Roodo Blog System</generator>
<copyright>All Rights Reserved</copyright>
<atom:link href="http://blog.roodo.com/toki_kanno/archives/cat_124034.xml" rel="self" type="application/rss+xml" />
<item>
	<title>Binding normal class to WPF control</title>
	<description><![CDATA[
			以ListBox為例，它有一個ItemsSource的property可以讓你指定來源通常一個簡單的List物件就可以讓它自動進行 bindingListBox list_box = new ListBox();List string_list = new List();list_box.ItemsSource = string_list;但是這樣子做有個問題，當你的string_list物件有了任何的增減或改變時WPF的UI並不會自動的幫你更新list上的改變有一個做法是使用下面的code，先將ItemsSource屬性清空再載入強制它進行refresh的動作list_box.ItemsSource = null;list_box.ItemsSource = string_list;但是這樣子必需要手動來，有點麻煩，正港的懶人做法如下public&nbsp; class&nbsp; StringList : ObservableCollection&lt;string&gt;{}StringList string_list = new StringList();list_box.ItemsSource = string_list;也就是宣告一個由ObservableCollection繼承下來的class來做為物件的container，由於ObservableCollection有實作INofiyPropertyChanged等interface，可以在物件有任何變化時，自動的通知WPF的UI進行update的動作不過有一好沒兩好，由於這是全自動的，所以無法在UI thread以外進行對該container的操作，不然你就等著它吐Exception出來給你看囉補充: 有人寫了一篇關於跨thread的WPF data binding 的文章，目前正研究中。再補: 上面那篇最後的結論是，分成兩個List來操作，一個是專門用來binding的ObservableCollection，另一個則是真正用來處理增減、數值改變的List。上面再用一個Class包起來做統一的操作。不過根本之道還是得看微軟對於這個問題將來會不會推出什麼官方的解法了。
		]]>
	</description>
	<content:encoded><![CDATA[
			以ListBox為例，它有一個ItemsSource的property可以讓你指定來源<br />通常一個簡單的List物件就可以讓它自動進行 binding<br /><br /><table border="1"><tbody><tr><td>ListBox list_box = new ListBox();<br />List string_list = new List();<br /><br />list_box.ItemsSource = string_list;</td></tr></tbody></table><br />但是這樣子做有個問題，當你的string_list物件有了任何的增減或改變時<br />WPF的UI並不會自動的幫你更新list上的改變<br /><br />有一個做法是使用下面的code，先將ItemsSource屬性清空再載入<br />強制它進行refresh的動作<br /><br /><table border="1"><tbody><tr><td>list_box.ItemsSource = null;<br />list_box.ItemsSource = string_list;</td></tr></tbody></table><br />但是這樣子必需要手動來，有點麻煩，正港的懶人做法如下<br /><br /><table border="1"><tbody><tr><td>public&nbsp; class&nbsp; StringList : ObservableCollection&lt;string&gt;{}<br /><br />StringList string_list = new StringList();<br />list_box.ItemsSource = string_list;</td></tr></tbody></table><br />也就是宣告一個由ObservableCollection繼承下來的class來做為物件的container，由於ObservableCollection有實作INofiyPropertyChanged等interface，可以在物件有任何變化時，自動的通知WPF的UI進行update的動作<br /><br />不過有一好沒兩好，由於這是全自動的，所以無法在UI thread以外進行對該container的操作，不然你就等著它吐Exception出來給你看囉<br /><br />補充: <br />有人寫了一篇關於<a href="http://blog.quantumbitdesigns.com/2008/07/22/wpf-cross-thread-collection-binding-part-4-the-grand-solution/" target="_blank">跨thread的WPF data binding</a> 的文章，目前正研究中。<br /><br />再補: <br />上面那篇最後的結論是，分成兩個List來操作，一個是專門用來binding的ObservableCollection，另一個則是真正用來處理增減、數值改變的List。上面再用一個Class包起來做統一的操作。不過根本之道還是得看微軟對於這個問題將來會不會推出什麼官方的解法了。
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/7142399.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/7142399.html</guid>
	<category>.Net Framework</category>
	<pubDate>Tue, 09 Sep 2008 10:10:41 +0800</pubDate>
</item>
<item>
	<title>SQL server compact 注意事項</title>
	<description><![CDATA[
			在 .NET 3.5 下的 SQL server compact 用起來是很方便但是要注意一件事，connection string 裡最好填的是絕對路徑因為只要程式不小心換了 current directory 後用相對路徑的data connection就找不到資料庫的家囉
		]]>
	</description>
	<content:encoded><![CDATA[
			在 .NET 3.5 下的 SQL server compact 用起來是很方便<br />但是要注意一件事，connection string 裡最好填的是絕對路徑<br /><br />因為只要程式不小心換了 current directory 後<br />用相對路徑的data connection就找不到資料庫的家囉
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/6221009.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/6221009.html</guid>
	<category>.Net Framework</category>
	<pubDate>Mon, 23 Jun 2008 23:21:48 +0800</pubDate>
</item>
<item>
	<title>memcpy (IntPtr to IntPtr) in C#</title>
	<description><![CDATA[
			直接呼叫 msvcrt.dll 中的 memcpy 即可[DllImport(&quot;msvcrt.dll&quot;)]private static extern IntPtr memcpy(IntPtr dest, IntPtr src, long size);追加一個，不想要裝 msvcrt 的，可以改 call kernel32.dll 裡的 RelMoveMemory[DllImport(&quot;Kernel32.dll&quot;, EntryPoint = &quot;RtlMoveMemory&quot;)]private static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);
		]]>
	</description>
	<content:encoded><![CDATA[
			<span style="border-collapse: separate; color: #526569; font-family: Verdana; font-size: 11px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px" class="Apple-style-span"><pre style="margin: 0px; font-family: 'Courier New',mono; color: #000066; font-size: 120%"><span style="color: black; background-color: transparent; font-family: 'Courier New'; font-size: 11px; font-weight: normal">直接呼叫 msvcrt.dll 中的 memcpy 即可<br /><br />[DllImport(<span style="font-family: 'Courier New'; font-size: 11px; font-weight: normal">&quot;msvcrt.dll&quot;</span>)]<br /><span style="color: blue; background-color: transparent; font-family: 'Courier New'; font-size: 11px; font-weight: normal">private</span> <span style="color: blue; background-color: transparent; font-family: 'Courier New'; font-size: 11px; font-weight: normal">static</span> <span style="color: blue; background-color: transparent; font-family: 'Courier New'; font-size: 11px; font-weight: normal">extern</span> IntPtr memcpy(IntPtr dest, IntPtr src, <span style="color: blue; background-color: transparent; font-family: 'Courier New'; font-size: 11px; font-weight: normal">long</span> size);<br /><br />追加一個，不想要裝 msvcrt 的，可以改 call kernel32.dll 裡的 RelMoveMemory<br /><br />[DllImport(&quot;Kernel32.dll&quot;, EntryPoint = &quot;RtlMoveMemory&quot;)]<br /><font color="#0000ff">private static extern</font> void CopyMemory(IntPtr Destination, IntPtr Source, int Length);<br /><br /></span></pre></span>
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/6209493.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/6209493.html</guid>
	<category>.Net Framework</category>
	<pubDate>Sat, 21 Jun 2008 12:33:12 +0800</pubDate>
</item>
<item>
	<title>Direct Memory Access in C#</title>
	<description><![CDATA[
			Quoted from http://www.codeproject.com/KB/GDI-plus/csharpfilters.aspx&nbsp;public static bool Conv3x3(Bitmap b, ConvMatrix m){    // Avoid divide by zero errors    if (0 == m.Factor)        return false; Bitmap         // GDI+ still lies to us - the return format is BGR, NOT RGB.     bSrc = (Bitmap)b.Clone();    BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),                         ImageLockMode.ReadWrite,                         PixelFormat.Format24bppRgb);     BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height),                        ImageLockMode.ReadWrite,                        PixelFormat.Format24bppRgb);     int stride = bmData.Stride;     int stride2 = stride * 2;     System.IntPtr Scan0 = bmData.Scan0;     System.IntPtr SrcScan0 = bmSrc.Scan0;     unsafe {         byte * p = (byte *)(void *)Scan0;         byte * pSrc = (byte *)(void *)SrcScan0;         int nOffset = stride - b.Width*3;         int nWidth = b.Width - 2;         int nHeight = b.Height - 2;                 int nPixel;                 for(int y=0;y &lt; nHeight;++y)         {             for(int x=0; x &lt; nWidth; ++x )             {                nPixel = ( ( ( (pSrc[2] * m.TopLeft) +                     (pSrc[5] * m.TopMid) +                     (pSrc[8] * m.TopRight) +                     (pSrc[2 + stride] * m.MidLeft) +                     (pSrc[5 + stride] * m.Pixel) +                     (pSrc[8 + stride] * m.MidRight) +                     (pSrc[2 + stride2] * m.BottomLeft) +                     (pSrc[5 + stride2] * m.BottomMid) +                     (pSrc[8 + stride2] * m.BottomRight))                     / m.Factor) + m.Offset);                                     if (nPixel &lt; 0) nPixel = 0;                 if (nPixel &gt; 255) nPixel = 255;                 p[5 + stride]= (byte)nPixel;                                 nPixel = ( ( ( (pSrc[1] * m.TopLeft) +                     (pSrc[4] * m.TopMid) +                     (pSrc[7] * m.TopRight) +                     (pSrc[1 + stride] * m.MidLeft) +                     (pSrc[4 + stride] * m.Pixel) +                     (pSrc[7 + stride] * m.MidRight) +                     (pSrc[1 + stride2] * m.BottomLeft) +                     (pSrc[4 + stride2] * m.BottomMid) +                     (pSrc[7 + stride2] * m.BottomRight))                     / m.Factor) + m.Offset);                                     if (nPixel &lt; 0) nPixel = 0;                 if (nPixel &gt; 255) nPixel = 255;                 p[4 + stride] = (byte)nPixel;                                 nPixel = ( ( ( (pSrc[0] * m.TopLeft) +                                (pSrc[3] * m.TopMid) +                                (pSrc[6] * m.TopRight) +                                (pSrc[0 + stride] * m.MidLeft) +                                (pSrc[3 + stride] * m.Pixel) +                                (pSrc[6 + stride] * m.MidRight) +                                (pSrc[0 + stride2] * m.BottomLeft) +                                (pSrc[3 + stride2] * m.BottomMid) +                                (pSrc[6 + stride2] * m.BottomRight))                     / m.Factor) + m.Offset);                                     if (nPixel &lt; 0) nPixel = 0;                 if (nPixel &gt; 255) nPixel = 255;                 p[3 + stride] = (byte)nPixel;                                 p += 3;                 pSrc += 3;             }                         p += nOffset;             pSrc += nOffset;         }     }         b.UnlockBits(bmData);     bSrc.UnlockBits(bmSrc);     return true; }
		]]>
	</description>
	<content:encoded><![CDATA[
			Quoted from http://www.codeproject.com/KB/GDI-plus/csharpfilters.aspx<br /><br /><table border="1" width="500"><tbody><tr><td>&nbsp;<span><pre style="margin-top: 0pt"><span class="code-keyword">public</span> <span class="code-keyword">static</span> <span class="code-keyword">bool</span> Conv3x3(Bitmap b, ConvMatrix m)<br />{<br />    <span class="code-comment">//</span><span class="code-comment"> Avoid divide by zero errors<br /></span><br />    <span class="code-keyword">if</span> (<span class="code-digit">0</span> == m.Factor)<br />        <span class="code-keyword">return</span> <span class="code-keyword">false</span>; Bitmap <br />    <br />    <span class="code-comment">//</span><span class="code-comment"> GDI+ still lies to us - the return format is BGR, NOT RGB. <br /></span><br />    bSrc = (Bitmap)b.Clone();<br />    BitmapData bmData = b.LockBits(<span class="code-keyword">new</span> Rectangle(<span class="code-digit">0</span>, <span class="code-digit">0</span>, b.Width, b.Height), <br />                        ImageLockMode.ReadWrite, <br />                        PixelFormat.Format24bppRgb); <br />    BitmapData bmSrc = bSrc.LockBits(<span class="code-keyword">new</span> Rectangle(<span class="code-digit">0</span>, <span class="code-digit">0</span>, bSrc.Width, bSrc.Height), <br />                       ImageLockMode.ReadWrite, <br />                       PixelFormat.Format24bppRgb); <br />    <span class="code-keyword">int</span> stride = bmData.Stride; <br />    <span class="code-keyword">int</span> stride2 = stride * <span class="code-digit">2</span>; <br /><br />    System.<span class="code-SDKkeyword">IntPtr</span> Scan0 = bmData.Scan0; <br />    System.<span class="code-SDKkeyword">IntPtr</span> SrcScan0 = bmSrc.Scan0; <br /><br />    <span class="code-keyword">unsafe</span> { <br />        <span class="code-keyword">byte</span> * p = (<span class="code-keyword">byte</span> *)(<span class="code-keyword">void</span> *)Scan0; <br />        <span class="code-keyword">byte</span> * pSrc = (<span class="code-keyword">byte</span> *)(<span class="code-keyword">void</span> *)SrcScan0; <br />        <span class="code-keyword">int</span> nOffset = stride - b.Width*3; <br />        <span class="code-keyword">int</span> nWidth = b.Width - <span class="code-digit">2</span>; <br />        <span class="code-keyword">int</span> nHeight = b.Height - <span class="code-digit">2</span>; <br />        <br />        <span class="code-keyword">int</span> nPixel; <br />        <br />        <span class="code-keyword">for</span>(<span class="code-keyword">int</span> y=0;y &lt; nHeight;++y) <br />        { <br />            <span class="code-keyword">for</span>(<span class="code-keyword">int</span> x=0; x &lt; nWidth; ++x ) <br />            {<br />                nPixel = ( ( ( (pSrc[<span class="code-digit">2</span>] * m.TopLeft) + <br />                    (pSrc[<span class="code-digit">5</span>] * m.TopMid) + <br />                    (pSrc[<span class="code-digit">8</span>] * m.TopRight) + <br />                    (pSrc[<span class="code-digit">2</span> + stride] * m.MidLeft) + <br />                    (pSrc[<span class="code-digit">5</span> + stride] * m.Pixel) + <br />                    (pSrc[<span class="code-digit">8</span> + stride] * m.MidRight) + <br />                    (pSrc[<span class="code-digit">2</span> + stride2] * m.BottomLeft) + <br />                    (pSrc[<span class="code-digit">5</span> + stride2] * m.BottomMid) + <br />                    (pSrc[<span class="code-digit">8</span> + stride2] * m.BottomRight)) <br />                    / m.Factor) + m.Offset); <br />                    <br />                <span class="code-keyword">if</span> (nPixel &lt; <span class="code-digit">0</span>) nPixel = <span class="code-digit">0</span>; <br />                <span class="code-keyword">if</span> (nPixel &gt; <span class="code-digit">255</span>) nPixel = <span class="code-digit">255</span>; <br />                p[<span class="code-digit">5</span> + stride]= (<span class="code-keyword">byte</span>)nPixel; <br />                <br />                nPixel = ( ( ( (pSrc[<span class="code-digit">1</span>] * m.TopLeft) + <br />                    (pSrc[<span class="code-digit">4</span>] * m.TopMid) + <br />                    (pSrc[<span class="code-digit">7</span>] * m.TopRight) + <br />                    (pSrc[<span class="code-digit">1</span> + stride] * m.MidLeft) + <br />                    (pSrc[<span class="code-digit">4</span> + stride] * m.Pixel) + <br />                    (pSrc[<span class="code-digit">7</span> + stride] * m.MidRight) + <br />                    (pSrc[<span class="code-digit">1</span> + stride2] * m.BottomLeft) + <br />                    (pSrc[<span class="code-digit">4</span> + stride2] * m.BottomMid) + <br />                    (pSrc[<span class="code-digit">7</span> + stride2] * m.BottomRight)) <br />                    / m.Factor) + m.Offset); <br />                    <br />                <span class="code-keyword">if</span> (nPixel &lt; <span class="code-digit">0</span>) nPixel = <span class="code-digit">0</span>; <br />                <span class="code-keyword">if</span> (nPixel &gt; <span class="code-digit">255</span>) nPixel = <span class="code-digit">255</span>; <br />                p[<span class="code-digit">4</span> + stride] = (<span class="code-keyword">byte</span>)nPixel; <br />                <br />                nPixel = ( ( ( (pSrc[<span class="code-digit">0</span>] * m.TopLeft) + <br />                               (pSrc[<span class="code-digit">3</span>] * m.TopMid) + <br />                               (pSrc[<span class="code-digit">6</span>] * m.TopRight) + <br />                               (pSrc[<span class="code-digit">0</span> + stride] * m.MidLeft) + <br />                               (pSrc[<span class="code-digit">3</span> + stride] * m.Pixel) + <br />                               (pSrc[<span class="code-digit">6</span> + stride] * m.MidRight) + <br />                               (pSrc[<span class="code-digit">0</span> + stride2] * m.BottomLeft) + <br />                               (pSrc[<span class="code-digit">3</span> + stride2] * m.BottomMid) + <br />                               (pSrc[<span class="code-digit">6</span> + stride2] * m.BottomRight)) <br />                    / m.Factor) + m.Offset); <br />                    <br />                <span class="code-keyword">if</span> (nPixel &lt; <span class="code-digit">0</span>) nPixel = <span class="code-digit">0</span>; <br />                <span class="code-keyword">if</span> (nPixel &gt; <span class="code-digit">255</span>) nPixel = <span class="code-digit">255</span>; <br />                p[<span class="code-digit">3</span> + stride] = (<span class="code-keyword">byte</span>)nPixel; <br />                <br />                p += <span class="code-digit">3</span>; <br />                pSrc += <span class="code-digit">3</span>; <br />            } <br />            <br />            p += nOffset; <br />            pSrc += nOffset; <br />        } <br />    } <br />    <br />    b.UnlockBits(bmData); <br />    bSrc.UnlockBits(bmSrc); <br />    <span class="code-keyword">return</span> <span class="code-keyword">true</span>; <br />}</pre></span></td></tr></tbody></table>
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/6099823.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/6099823.html</guid>
	<category>.Net Framework</category>
	<pubDate>Wed, 28 May 2008 11:28:23 +0800</pubDate>
</item>
<item>
	<title>MTA / STA 屬性影響.NET下的 COM Interop</title>
	<description><![CDATA[
			MTA 和 STA 屬性通常會被定義在.NET程式的Main函式的Class上而當在.NET平台下以Interop的方式載入COM物件的時候，其內部會根據你呼叫時程式的Thread定義，來採取不同的建構方式。MTA &gt;&gt; CoInitializeEx(NULL, COINIT_MULTITHREADED)STA &gt;&gt; CoIntializeEx(NULL, COINIT_APARTMENTTHREADED)Unknow &gt;&gt; CoInitializeEx(NULL, COINIT_MULTITHREADED)其中以CoIntializeEx(NULL, COINIT_APARTMENTTHREADED)所建立的COM物件，是無法在.NET環境下跨Thread使用的(你會得到一個Query Interface 失敗的 Exception)。所以若要在.NET下跨Thread使用COM物件，請記得將STA修改成MTA。
		]]>
	</description>
	<content:encoded><![CDATA[
			<p>MTA 和 STA 屬性通常會被定義在.NET程式的Main函式的Class上</p><p>而當在.NET平台下以Interop的方式載入COM物件的時候，其內部會根據你呼叫時程式的Thread定義，來採取不同的建構方式。</p><p>MTA &gt;&gt; CoInitializeEx(NULL, COINIT_MULTITHREADED)</p><p>STA &gt;&gt; CoIntializeEx(NULL, COINIT_APARTMENTTHREADED)</p><p>Unknow &gt;&gt; CoInitializeEx(NULL, COINIT_MULTITHREADED)</p><p>其中以CoIntializeEx(NULL, COINIT_APARTMENTTHREADED)所建立的COM物件，是無法在.NET環境下跨Thread使用的(你會得到一個Query Interface 失敗的 Exception)。所以若要在.NET下跨Thread使用COM物件，請記得將STA修改成MTA。</p>
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/2791321.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/2791321.html</guid>
	<category>.Net Framework</category>
	<pubDate>Fri, 02 Mar 2007 11:54:14 +0800</pubDate>
</item>
<item>
	<title>用 Microsoft Visual C# Express 寫 MacOSX 的程式</title>
	<description><![CDATA[
			之前就聽說C#像Java一樣可以跨平台執行，只是在MacOSX上必需要安裝Mono Framework。於是就實驗一下使用Microsoft VC# Express來編寫跨平台的GUI程式。沒想到還真的可以。這下子又多了一種開發MacOSX程式的方法了。實作過程以及教學在以下網址:http://www.iim.nctu.edu.tw/~toki/CSharpOnOSX/c%23osx.html
		]]>
	</description>
	<content:encoded><![CDATA[
			<p>之前就聽說C#像Java一樣可以跨平台執行，只是在MacOSX上必需要安裝Mono Framework。於是就實驗一下使用Microsoft VC# Express來編寫跨平台的GUI程式。沒想到還真的可以。這下子又多了一種開發MacOSX程式的方法了。</p><p>實作過程以及教學在以下網址:</p><p><a href="http://www.iim.nctu.edu.tw/~toki/CSharpOnOSX/c%23osx.html">http://www.iim.nctu.edu.tw/~toki/CSharpOnOSX/c%23osx.html</a></p>
		<a class="acontinues" href="http://blog.roodo.com/toki_kanno/archives/2128001.html">(繼續閱讀...)</a>
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/2128001.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/2128001.html</guid>
	<category>.Net Framework</category>
	<pubDate>Sun, 10 Sep 2006 16:03:35 +0800</pubDate>
</item>
<item>
	<title>當程式找不到 resource file 時該如何解決</title>
	<description><![CDATA[
			根據微軟的說法，當有了以下的行為/情怳後，你編譯出來的程式不會有任何的warning，但是當執行時會出現找不到resource檔案的exception。1、需要參照 resource 的 main windows form 的 class 不是整個專案中的第一個class。2、main window form class 的名稱有改變過微軟的解決方案是更改該resource檔案的build setting，把名字改成改變後的。但是有時候仍然無法解決這問題，這時候，手動指定resource檔案能夠有效(但是不治本)的解決這問題。例:System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(maagsServerForm::typeid));改變成:System::Resources::ResourceManager^ resources = gcnew ResourceManager(&quot;server.maagsServerForm&quot;, Assembly::GetExecutingAssembly() ) ;則變成手動指定 &quot;server.maagsServerForm.resource&quot;此檔為做為 resource 檔案。但需要注意的是，由於第一行程式通常是由 interface builder 產生，當用interface builder更動了任何 form 上的元件(增加/刪除/指定delegate)後，該行會被interface builder更新回去原來的狀態，這時候必需要手動再修改一次(所以說不治本)。
		]]>
	</description>
	<content:encoded><![CDATA[
			<p>根據微軟的說法，當有了以下的行為/情怳後，你編譯出來的程式不會有任何的warning，但是當執行時會出現找不到resource檔案的exception。</p><p>1、需要參照 resource 的 main windows form 的 class 不是整個專案中的第一個class。</p><p>2、main window form class 的名稱有改變過</p><p>微軟的解決方案是更改該resource檔案的build setting，把名字改成改變後的。但是有時候仍然無法解決這問題，這時候，手動指定resource檔案能夠有效(但是不治本)的解決這問題。</p><p>例:</p><p>System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(maagsServerForm::typeid));<br /></p><p>改變成:</p><p>System::Resources::ResourceManager^ resources = gcnew ResourceManager(&quot;server.maagsServerForm&quot;, Assembly::GetExecutingAssembly() ) ;<br /></p><p>則變成手動指定 &quot;server.maagsServerForm.resource&quot;此檔為做為 resource 檔案。</p><p>但需要注意的是，由於第一行程式通常是由 interface builder 產生，當用interface builder更動了任何 form 上的元件(增加/刪除/指定delegate)後，該行會被interface builder更新回去原來的狀態，這時候必需要手動再修改一次(所以說不治本)。</p><p />
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/1983724.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/1983724.html</guid>
	<category>.Net Framework</category>
	<pubDate>Mon, 07 Aug 2006 12:02:42 +0800</pubDate>
</item>
<item>
	<title>加速 ListBox / ListView 加入新物件的方法</title>
	<description><![CDATA[
			如果你有一堆的物件等著加入到 ListBox 或是 ListView 這些視窗元件時記得先呼叫該元件的 SuspendLayout()，停止該物件的重繪更新等到全部的物件都加入完成之後，再呼叫ResumLayout()一口氣更新這些加入的物件可以讓更新的動作快非常的多另外，也可以使用AddRange來達到加速的效果
		]]>
	</description>
	<content:encoded><![CDATA[
			<p>如果你有一堆的物件等著加入到 ListBox 或是 ListView 這些視窗元件時</p><p>記得先呼叫該元件的 SuspendLayout()，停止該物件的重繪更新</p><p>等到全部的物件都加入完成之後，再呼叫ResumLayout()</p><p>一口氣更新這些加入的物件</p><p>可以讓更新的動作快非常的多</p><p>另外，也可以使用AddRange來達到加速的效果</p>
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/1776283.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/1776283.html</guid>
	<category>.Net Framework</category>
	<pubDate>Mon, 19 Jun 2006 17:06:00 +0800</pubDate>
</item>
<item>
	<title>Don&#039;t call constructor in constructor</title>
	<description><![CDATA[
			Code:public ref class ABC{public:        ABC(){                m_pTestString = &quot;TEST&quot;;                ABC(10);        }        ABC(int i){                Console::WriteLine(&quot;i={0}, Object={1}&quot;, i, m_pTestString);        }        void Test(){                Console::WriteLine(m_pTestString);        }private:        String ^m_pTestString;};int main(array&lt;:string ^&gt; ^args){        ABC ^t = gcnew ABC();        Console::ReadKey();        return 0;}Result:i=10, Object=  *m_pTestString 在ABC(int i)中被重新初始化，所以印不出值
		]]>
	</description>
	<content:encoded><![CDATA[
			<font face="Monospace"><p>Code:</p><p>public ref class ABC{<br />public:<br />        ABC(){<br />                m_pTestString = <font color="#ff0000">&quot;TEST&quot;</font>;<br />                ABC(<font color="#0000ff">10</font>);<br />        }<br /></p><p>        ABC(<font color="#800000">int</font> i){<br />                Console::WriteLine(<font color="#ff0000">&quot;i={0}, Object={1}&quot;</font>, i, m_pTestString);<br />        }<br /><br />        <font color="#800000">void</font> Test(){<br />                Console::WriteLine(m_pTestString);<br />        }<br /></p><p>private:<br />        String ^m_pTestString;<br />};<br /><br /><font color="#800000">int</font> main(array&lt;:string ^&gt; ^args)<br />{<br />        ABC ^t = gcnew ABC();<br />        Console::ReadKey();<br />        <font color="#000000"><b>return</b> <font color="#0000ff">0</font>;<br />}<br /><br /><br />Result:</font></p><p><font color="#000000">i=10, Object=  </font></p><p>*m_pTestString 在ABC(int i)中被重新初始化，所以印不出值</:string ^ /></p></font><br />
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/1719299.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/1719299.html</guid>
	<category>.Net Framework</category>
	<pubDate>Tue, 06 Jun 2006 21:42:51 +0800</pubDate>
</item>
<item>
	<title>將傳統structure pointer 加入 .NET collection 物件中管理</title>
	<description><![CDATA[
			很簡單......就是IntPtrStruct testStruct{int a;int b;};testStruct *ts = new testStruct;ArrayList^ tList = gcnew ArrayList();tList-&gt;Add(gcnew IntPtr(ts));-------------------------------------------------取出:testStruct *ts;ts = (IntPtr^)tList[0]-&gt;ToPointer();ts-&gt;a = 10;ts-&gt;b = 10;
		]]>
	</description>
	<content:encoded><![CDATA[
			<p>很簡單......就是IntPtr</p><p>Struct testStruct{</p><p>int a;</p><p>int b;</p><p>};</p><p /><p>testStruct *ts = new testStruct;</p><p>ArrayList^ tList = gcnew ArrayList();</p><p>tList-&gt;Add(gcnew IntPtr(ts));</p><p>-------------------------------------------------</p><p>取出:</p><p>testStruct *ts;</p><p>ts = (IntPtr^)tList[0]-&gt;ToPointer();</p><p>ts-&gt;a = 10;</p><p>ts-&gt;b = 10;</p>
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/1704011.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/1704011.html</guid>
	<category>.Net Framework</category>
	<pubDate>Sat, 03 Jun 2006 21:34:17 +0800</pubDate>
</item>
<item>
	<title>透過另一個 Thread 來操作 UI</title>
	<description><![CDATA[
			在.Net Framework 下，Windows UI 是由單一的 Thread 來負責的，如果當有一個非 UI Thread 要改變 UI 的一些相關資料以及狀態時，.Net framework 會產生一個 System Exception 來攔截這個動作，也因此，我們必需要做一些特殊處理來繞過這個機制。

而主要的方法就在於，使用BeginInvoke() 以及 EndInvoke() 來觸發一個事件(Event)，再讓 UI 本身認為接收到這個事件產生對應的處理。例如，我有一個用來在 ListView 上加入一行記錄的副程式，原始的寫法如下:

void MSG(String ^s)
{
    ListViewItem ^tmp = ListView->Items->Add(L"MSG");
    tmp->SubItems->Add(String::Contact(DateTime::Now);
    tmp->SubItems->Add(s);
}

這個在單一執行緒的程式裡並沒有問題，但是如果要讓多執行緒的程式也可以使用時，必需修改成如下的形式:


delegate MSGDelegate(String ^s);
void MSG(String ^s)
{
    // 檢查是否不是由 UI Thread 來的呼叫
    if (this->InvokeRequired)
    {
        // 產生一個臨時的 delegate
        MSGDelegate del = gcnew MSGDelegate(MSG);
        // 讓系統去觸發這個 delegate
        IAsyncResult ^r =this->BeginInvoke(MSG, s);
        // 結束這個 delegate
        this->EndInvoke(r);
        return;
    }

    // 真正執行的內容
    ListViewItem ^tmp = ListView->Items->Add(L"MSG");
    tmp->SubItems->Add(String::Contact(DateTime::Now);
    tmp->SubItems->Add(s);
}

		]]>
	</description>
	<content:encoded><![CDATA[
			在.Net Framework 下，Windows UI 是由單一的 Thread 來負責的，如果當有一個非 UI Thread 要改變 UI 的一些相關資料以及狀態時，.Net framework 會產生一個 System Exception 來攔截這個動作，也因此，我們必需要做一些特殊處理來繞過這個機制。<br />
<br />
而主要的方法就在於，使用BeginInvoke() 以及 EndInvoke() 來觸發一個事件(Event)，再讓 UI 本身認為接收到這個事件產生對應的處理。例如，我有一個用來在 ListView 上加入一行記錄的副程式，原始的寫法如下:<br />
<pre><br />
void MSG(String ^s)<br />
{<br />
    ListViewItem ^tmp = ListView->Items->Add(L"MSG");<br />
    tmp->SubItems->Add(String::Contact(DateTime::Now);<br />
    tmp->SubItems->Add(s);<br />
}<br />
</pre><br />
這個在單一執行緒的程式裡並沒有問題，但是如果要讓多執行緒的程式也可以使用時，必需修改成如下的形式:<br />
<br />
<pre><br />
delegate MSGDelegate(String ^s);<br />
void MSG(String ^s)<br />
{<br />
    // 檢查是否不是由 UI Thread 來的呼叫<br />
    if (this->InvokeRequired)<br />
    {<br />
        // 產生一個臨時的 delegate<br />
        MSGDelegate del = gcnew MSGDelegate(MSG);<br />
        // 讓系統去觸發這個 delegate<br />
        IAsyncResult ^r =this->BeginInvoke(MSG, s);<br />
        // 結束這個 delegate<br />
        this->EndInvoke(r);<br />
        return;<br />
    }<br />
<br />
    // 真正執行的內容<br />
    ListViewItem ^tmp = ListView->Items->Add(L"MSG");<br />
    tmp->SubItems->Add(String::Contact(DateTime::Now);<br />
    tmp->SubItems->Add(s);<br />
}<br />
</pre>
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/933066.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/933066.html</guid>
	<category>.Net Framework</category>
	<pubDate>Fri, 30 Dec 2005 13:56:25 +0800</pubDate>
</item>
<item>
	<title>.Net Framework delegate in C++</title>
	<description><![CDATA[
			.Net Framework 裡頭有一個新的 keyword 叫做 delegate (這個基本上我懷疑是從 Cocoa Framework抄來的:P)，主要是可以讓程式設計師方便地動態指定當一些事件發生時，該執行什麼函式來處理。下面是一個簡單的範例:

//宣告一個 delegate 的樣板
delegate void OnTestCallBack(String ^s);

//當 OnTest 發生時呼叫的 function
void OnTest Func(String ^s)
{
    Console::WriteLine(s);
}

int main()
{
    //用模板建一個 delegate 物件
    OnTestCallBack ^OnTest;
    //把 OnTestFunc 指定給這個物件，如果物件已建立，可以用 += 將複數個 Func 指定上去
    OnTest = gcnew OnTestCallBack(OnTestFunc);

    // OnTest 事件發生了!
    OnTest("TEST!!!!!");
}


		]]>
	</description>
	<content:encoded><![CDATA[
			.Net Framework 裡頭有一個新的 keyword 叫做 delegate (這個基本上我懷疑是從 Cocoa Framework抄來的:P)，主要是可以讓程式設計師方便地動態指定當一些事件發生時，該執行什麼函式來處理。下面是一個簡單的範例:<br />
<br />
//宣告一個 delegate 的樣板<br />
delegate void OnTestCallBack(String ^s);<br />
<br />
//當 OnTest 發生時呼叫的 function<br />
void OnTest Func(String ^s)<br />
{<br />
    Console::WriteLine(s);<br />
}<br />
<br />
int main()<br />
{<br />
    //用模板建一個 delegate 物件<br />
    OnTestCallBack ^OnTest;<br />
    //把 OnTestFunc 指定給這個物件，如果物件已建立，可以用 += 將複數個 Func 指定上去<br />
    OnTest = gcnew OnTestCallBack(OnTestFunc);<br />
<br />
    // OnTest 事件發生了!<br />
    OnTest("TEST!!!!!");<br />
}<br />
<br />

		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/928621.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/928621.html</guid>
	<category>.Net Framework</category>
	<pubDate>Thu, 29 Dec 2005 17:29:19 +0800</pubDate>
</item>
<item>
	<title>.Net 下的 TCP/IP Server 開發</title>
	<description><![CDATA[
			.Net Framework 下寫 TCP/IP Server 應該還算方便(不過我不禁還是要說，Delphi更讚)
由於有包裝好現成的 TCPListener Class，建立元件後，該填的資料填一填，
一個會動的 Server 就出來了，以下是摸出來的範例:



	TCPListener ^listener;

	try{
		// listen on IPAddress::Any = 0.0.0.0
		IPEndPoint ^ip = gcnew IPEndPoint(IPAddress::Any, aPort);
		listener = gcnew TcpListener(ip);
	}
		catch (SocketException ^e){
		Console::WriteLine("Catch SocketException: {0}", e->ToString());
	}
	
	// start listener
	listener->Start();
	
	while(true)
	{
		// use Pending() to check if there are incoming connections
		// because AcceptTcpClient() will block!
		if (!listener->Pending())
			continue;

		TcpClient^ newClient = listener->AcceptTcpClient();
			
		Monitor::Enter(clientPool->SyncRoot);
		clientPool->Add(newClient);
		Monitor::Exit(clientPool->SyncRoot);
			
		Console::WriteLine(L"[MSG][{0}][{1}] Client connected.", 
			DateTime::Now,
			newClient->Client->RemoteEndPoint
			);
	}
	
	listener->Stop();


		]]>
	</description>
	<content:encoded><![CDATA[
			.Net Framework 下寫 TCP/IP Server 應該還算方便(不過我不禁還是要說，Delphi更讚)<br />
由於有包裝好現成的 TCPListener Class，建立元件後，該填的資料填一填，<br />
一個會動的 Server 就出來了，以下是摸出來的範例:<br />
<br />
<table border=1><br />
<td><pre><br />
	TCPListener ^listener;<br />
<br />
	try{<br />
		// listen on IPAddress::Any = 0.0.0.0<br />
		IPEndPoint ^ip = gcnew IPEndPoint(IPAddress::Any, aPort);<br />
		listener = gcnew TcpListener(ip);<br />
	}<br />
		catch (SocketException ^e){<br />
		Console::WriteLine("Catch SocketException: {0}", e->ToString());<br />
	}<br />
	<br />
	// start listener<br />
	listener->Start();<br />
	<br />
	while(true)<br />
	{<br />
		// use Pending() to check if there are incoming connections<br />
		// because AcceptTcpClient() will block!<br />
		if (!listener->Pending())<br />
			continue;<br />
<br />
		TcpClient^ newClient = listener->AcceptTcpClient();<br />
			<br />
		Monitor::Enter(clientPool->SyncRoot);<br />
		clientPool->Add(newClient);<br />
		Monitor::Exit(clientPool->SyncRoot);<br />
			<br />
		Console::WriteLine(L"[MSG][{0}][{1}] Client connected.", <br />
			DateTime::Now,<br />
			newClient->Client->RemoteEndPoint<br />
			);<br />
	}<br />
	<br />
	listener->Stop();<br />
</pre></td><br />
</table>
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/914237.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/914237.html</guid>
	<category>.Net Framework</category>
	<pubDate>Mon, 26 Dec 2005 16:28:16 +0800</pubDate>
</item>
<item>
	<title>果然微軟的東西還是Express版好用</title>
	<description><![CDATA[
			就個人使用微軟產品的經驗來說，微軟的 Express 版本一向比全功能版本好用
(Ex: Outlook vs Outlook Express)

前一陣子微軟正在免費大放送 Visual Studio 2005 Express 版本
由於剛好自己手邊有一台開發機還沒有裝 .Net 2003，想說是免費的，不如抓來試試

一用之下，棍! 果然微軟的東西只能用 Express 版啊 :P
不管是啟動、編譯、執行的速度上來說，比上 .Net 2003都好上許多
不知道是因為版本較新用了一些新的技術，或是 Express沒有外掛一些阿哩不達的奇怪功能的關係

另一方面，.Net Framework 蠻讓人覺得高興的，該包的東西都包進來了
GUI方面現在也有Windows Form Application 這種 RAD Design 的方式可用了
總覺得比起以前的版本，這版的親和力高上許多，甚至有些 Delphi 的味道
不知道是不是因為 Microsoft 之前挖角了一些 Borland 的 Delphi 開發人員有關係

不過個人更想使用的是傳聞中的 Cocoa Framework for Win32 
不知道到底會不會出啊，如果出了就太美好了
		]]>
	</description>
	<content:encoded><![CDATA[
			就個人使用微軟產品的經驗來說，微軟的 Express 版本一向比全功能版本好用<br />
(Ex: Outlook vs Outlook Express)<br />
<br />
前一陣子微軟正在免費大放送 Visual Studio 2005 Express 版本<br />
由於剛好自己手邊有一台開發機還沒有裝 .Net 2003，想說是免費的，不如抓來試試<br />
<br />
一用之下，棍! 果然微軟的東西只能用 Express 版啊 :P<br />
不管是啟動、編譯、執行的速度上來說，比上 .Net 2003都好上許多<br />
不知道是因為版本較新用了一些新的技術，或是 Express沒有外掛一些阿哩不達的奇怪功能的關係<br />
<br />
另一方面，.Net Framework 蠻讓人覺得高興的，該包的東西都包進來了<br />
GUI方面現在也有Windows Form Application 這種 RAD Design 的方式可用了<br />
總覺得比起以前的版本，這版的親和力高上許多，甚至有些 Delphi 的味道<br />
不知道是不是因為 Microsoft 之前挖角了一些 Borland 的 Delphi 開發人員有關係<br />
<br />
不過個人更想使用的是傳聞中的 Cocoa Framework for Win32 <br />
不知道到底會不會出啊，如果出了就太美好了
		
		]]>
	</content:encoded>
	<link>http://blog.roodo.com/toki_kanno/archives/914199.html</link>
	<guid>http://blog.roodo.com/toki_kanno/archives/914199.html</guid>
	<category>.Net Framework</category>
	<pubDate>Mon, 26 Dec 2005 16:28:16 +0800</pubDate>
</item>
</channel>
</rss>