<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Phanix's Blog &#187; 學習工作</title>
	<atom:link href="http://blog.phanix.idv.tw/archives/category/%e5%ad%b8%e7%bf%92%e5%b7%a5%e4%bd%9c/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.phanix.idv.tw</link>
	<description></description>
	<lastBuildDate>Tue, 07 Feb 2012 01:03:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>[C#][Maya][Python] Maya commandPort for external communication / 利用 commandPort 命令讓外部程式與 Maya 溝通</title>
		<link>http://blog.phanix.idv.tw/archives/2011/12/28/1009/</link>
		<comments>http://blog.phanix.idv.tw/archives/2011/12/28/1009/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 10:15:31 +0000</pubDate>
		<dc:creator>Phanix</dc:creator>
				<category><![CDATA[學習工作]]></category>
		<category><![CDATA[工作]]></category>
		<category><![CDATA[程式]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[Maya]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.phanix.idv.tw/?p=1009</guid>
		<description><![CDATA[利用 tcp client connection 或 socket connection 來跟 Maya 溝通 先給 python 程式&#8230; import socket host = YOUR_HOST_ADDRESS # &#8216;localhost&#8217; or &#8217;127.0.0.1&#8242; for local machine, IP_ADDRESS for remote machine port = YOUR_PORT_NUMBER_OF_MAYA maya = socket.socket(socket.AF_INET, socket.SOCK_STREAM) maya.connect( (host, port) ) message = &#8216;sphere()&#8217; maya.send(message) maya.close() C# 用 socket connection Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, [...]]]></description>
			<content:encoded><![CDATA[<p>利用 tcp client connection 或 socket connection 來跟 Maya 溝通<br />
<span id="more-1009"></span></p>
<p>先給 python 程式&#8230;</p>
<blockquote><p>
import socket</p>
<p>host = YOUR_HOST_ADDRESS # &#8216;localhost&#8217; or &#8217;127.0.0.1&#8242; for local machine, IP_ADDRESS for remote machine<br />
port = YOUR_PORT_NUMBER_OF_MAYA</p>
<p>maya = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<br />
maya.connect( (host, port) )</p>
<p>message = &#8216;sphere()&#8217;<br />
maya.send(message)<br />
maya.close()
</p></blockquote>
<p>C# 用 socket connection</p>
<blockquote><p>
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);<br />
s.Connect(YOUR_HOST_ADDRESS, YOUR_PORT_NUMBER_OF_MAYA);</p>
<p>string strCmd = &#8220;sphere()&#8221;;<br />
byte[] buf = System.Text.Encoding.Default.GetBytes(strCmd);</p>
<p>NetworkStream ns = new NetworkStream(s);</p>
<p>ns.Write(buf, 0, buf.Length);<br />
ns.Flush();<br />
ns.Close();</p>
<p>s.Close();
</p></blockquote>
<p>C# 用 Tcp client connection 的話也差不多</p>
<blockquote><p>
TcpClient tc = new TcpClient();<br />
tc.Connect(YOUR_HOST_ADDRESS, YOUR_PORT_NUMBER_OF_MAYA);</p>
<p>string strCmd = &#8220;sphere()&#8221;;<br />
byte[] buf = System.Text.Encoding.Default.GetBytes(strCmd);</p>
<p>NetworkStream ns = tc.GetStream();</p>
<p>ns.Write(buf, 0, buf.Length);<br />
ns.Flush();<br />
ns.Close();</p>
<p>tc.Close();
</p></blockquote>
<p>比較需要注意的大概是 commandPort 命令的用法。</p>
<p>如果是使用</p>
<blockquote><p>
commandPort -echoOutput -n &#8220;:6000&#8243;;
</p></blockquote>
<p>則會會開 port 6000 並 bind 在 127.0.0.1 上，這時候如果是要從 remote 機器上來控制就會 connection refused。</p>
<p>如果是使用</p>
<blockquote><p>
commandPort -echoOutput -n &#8220;YOUR_IP_ADDRESS:6000&#8243;;
</p></blockquote>
<p>則會會開 port 6000 並 bind 在 YOUR_IP_ADDRESS 上，這時候如果從本機用 localhost 來控制會 connection refused，但是用 YOUR_IP_ADDRESS 則不會有問題。</p>
<p>最簡單的解決方式是</p>
<blockquote><p>
commandPort -echoOutput -n &#8220;0.0.0.0:6000&#8243;;
</p></blockquote>
<p>這樣不論是本機或者 remote 機器來控制 Maya 做事情都可以很順利。</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-7434619175264093";
google_ad_width = 468;
google_ad_height = 60;
google_ad_format = "468x60_as";
google_ad_type = "text_image";
google_ad_channel = "";
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p> ]]></content:encoded>
			<wfw:commentRss>http://blog.phanix.idv.tw/archives/2011/12/28/1009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[C#] XMLWriter Encoding Issue / XMLWriter 控制文字編碼</title>
		<link>http://blog.phanix.idv.tw/archives/2011/12/26/1008/</link>
		<comments>http://blog.phanix.idv.tw/archives/2011/12/26/1008/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 07:12:51 +0000</pubDate>
		<dc:creator>Phanix</dc:creator>
				<category><![CDATA[學習工作]]></category>
		<category><![CDATA[工作]]></category>
		<category><![CDATA[程式]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.phanix.idv.tw/?p=1008</guid>
		<description><![CDATA[一般狀況下，如果不是很在意使用 XMLWriter 後輸出的文字編碼是哪一種的話，可以很簡單地用下面的方式完成 StringBuilder sb = new StringBuilder(); XmlWriter writer = XmlWriter.Create(sb); writer.WriteStartDocument(); //補上 xml 內容, 用 writer.WriteStartElement() 等完成 writer.WriteEndDocument(); writer.Flush(); XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml(sb.ToString()); 但是可以發現到這樣子所輸出的 XML 文件是變成 UTF-16 encoding。雖然有 XmlWriterSettings 這東西可以去設定 XMLWriter 的編碼，不過看起來好像是有些問題，輸出的 XML 結果依舊是 UTF-16。 解決的方法是用 MemoryStream 與 XMLTextWriter。 MemoryStream stream = new MemoryStream(); XmlWriter writer = new XmlTextWriter(stream, Encoding.UTF8); writer.WriteStartDocument(); [...]]]></description>
			<content:encoded><![CDATA[<p>一般狀況下，如果不是很在意使用 XMLWriter 後輸出的文字編碼是哪一種的話，可以很簡單地用下面的方式完成</p>
<blockquote><p>
StringBuilder sb = new StringBuilder();<br />
XmlWriter writer = XmlWriter.Create(sb);</p>
<p>writer.WriteStartDocument();<br />
//補上 xml 內容, 用 writer.WriteStartElement() 等完成<br />
writer.WriteEndDocument();</p>
<p>writer.Flush();</p>
<p>XmlDocument xmlDocument = new XmlDocument();<br />
xmlDocument.LoadXml(sb.ToString());
</p></blockquote>
<p>但是可以發現到這樣子所輸出的 XML 文件是變成 UTF-16 encoding。雖然有 XmlWriterSettings 這東西可以去設定 XMLWriter 的編碼，不過看起來好像是有些問題，輸出的 XML 結果依舊是 UTF-16。</p>
<p>解決的方法是用 MemoryStream 與 XMLTextWriter。</p>
<blockquote><p>
<span style="color:red;">MemoryStream stream = new MemoryStream();<br />
XmlWriter writer = new XmlTextWriter(stream, Encoding.UTF8);</span></p>
<p>writer.WriteStartDocument();<br />
//補上 xml 內容, 用 writer.WriteStartElement() 等完成<br />
writer.WriteEndDocument();</p>
<p>writer.Flush();</p>
<p><span style="color:red;">StreamReader reader = new StreamReader(stream, Encoding.UTF8, true);<br />
stream.Seek(0, SeekOrigin.Begin);<br />
string result = reader.ReadToEnd();</span></p>
<p>XmlDocument xmlDocument = new XmlDocument();<br />
xmlDocument.LoadXml(result);
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.phanix.idv.tw/archives/2011/12/26/1008/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[C#] Unix Timestamp</title>
		<link>http://blog.phanix.idv.tw/archives/2011/07/26/969/</link>
		<comments>http://blog.phanix.idv.tw/archives/2011/07/26/969/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 09:48:35 +0000</pubDate>
		<dc:creator>Phanix</dc:creator>
				<category><![CDATA[學習工作]]></category>
		<category><![CDATA[工作]]></category>
		<category><![CDATA[程式]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.phanix.idv.tw/?p=969</guid>
		<description><![CDATA[因為 Facebook 上頭記錄時間是用 Unix Timestamp，所以來看一下怎麼做。 Unix Timestamp 的定義為目前 UTC 時間減去 Unix epoch 起始時間(1970/1/1 0:0:0 UTC)所得到的秒數。(Ref: Unix time) private double UnixTimestamp(DateTime _datetime) { //Unix Epoch: 1970/1/1 0:0:0 TimeSpan span = (_datetime - new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime()); return (double)span.TotalSeconds; }]]></description>
			<content:encoded><![CDATA[<p>因為 Facebook 上頭記錄時間是用 Unix Timestamp，所以來看一下怎麼做。</p>
<p><span id="more-969"></span></p>
<p>Unix Timestamp 的定義為目前 UTC 時間減去 Unix epoch 起始時間(1970/1/1 0:0:0 UTC)所得到的秒數。(Ref: <a href="http://en.wikipedia.org/wiki/Unix_time" target="_blank">Unix time</a>)</p>
<pre>private double UnixTimestamp(DateTime _datetime)
{
    //Unix Epoch: 1970/1/1 0:0:0
    TimeSpan span = (_datetime - new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime());

    return (double)span.TotalSeconds;
} </pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.phanix.idv.tw/archives/2011/07/26/969/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# 處理 facebook JSON Serialized Data</title>
		<link>http://blog.phanix.idv.tw/archives/2011/07/19/962/</link>
		<comments>http://blog.phanix.idv.tw/archives/2011/07/19/962/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 02:30:21 +0000</pubDate>
		<dc:creator>Phanix</dc:creator>
				<category><![CDATA[學習工作]]></category>
		<category><![CDATA[工作]]></category>
		<category><![CDATA[程式]]></category>
		<category><![CDATA[網路應用]]></category>
		<category><![CDATA[電腦網路]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.phanix.idv.tw/?p=962</guid>
		<description><![CDATA[當透過 access token 去 facebook 抓取資料時，回傳的資料將以 JSON 的方式編碼，在 C# 裡頭可以用 JavaScriptSerializer 來處理，下面是個很懶惰的處理方式，不需要另外先去設計與宣告一個符合 facebook JSON 格式的 class object 來儲存資料，反正需要的時候再來針對 Key 另外處理即可。 using System.Web.Script.Serialization; using System.Collections; using System.IO; private void ProcessFBJSON() { JavaScriptSerializer jss = new JavaScriptSerializer(); string json; StreamReader sr = new StreamReader(@"C:\file.txt", Encoding.Default); json = sr.ReadToEnd(); sr.Close(); Dictionary dicSer = jss.Deserialize(json); traceDic(dicSer); } private void [...]]]></description>
			<content:encoded><![CDATA[<p>當透過 access token 去 facebook 抓取資料時，回傳的資料將以 JSON 的方式編碼，在 C# 裡頭可以用 JavaScriptSerializer 來處理，下面是個很懶惰的處理方式，不需要另外先去設計與宣告一個符合 facebook JSON 格式的 class object 來儲存資料，反正需要的時候再來針對 Key 另外處理即可。</p>
<p><span id="more-962"></span></p>
<pre>using System.Web.Script.Serialization;
using System.Collections;
using System.IO;

private void ProcessFBJSON()
{
    JavaScriptSerializer jss = new JavaScriptSerializer();

    string json;

    StreamReader sr = new StreamReader(@"C:\file.txt", Encoding.Default);
    json = sr.ReadToEnd();
    sr.Close();

    Dictionary<string, object> dicSer = jss.Deserialize<Dictionary<string, object>>(json);

    traceDic(dicSer);
}

private void traceDic(Dictionary<string, object> dic)
{
    foreach (KeyValuePair<string, object> p in dic)
    {
        if (p.Value is String)
        {
            textBox1.Text = textBox1.Text + p.Key + ": " + p.Value + "\r\n";
        }
        else if (p.Value is ArrayList)
        {
            textBox1.Text = textBox1.Text + p.Key + ": {\r\n";
            traceArrayList((ArrayList)(p.Value));
            textBox1.Text = textBox1.Text + "}\r\n";
        }
        else if (p.Value is Dictionary<string, object>)
        {
            textBox1.Text = textBox1.Text + p.Key + ": [{\r\n";
            traceDic((Dictionary<string, object>)(p.Value));
            textBox1.Text = textBox1.Text + "}]\r\n";
        }
        else if (p.Value is int || p.Value is float || p.Value is double)
        {
            textBox1.Text = textBox1.Text + p.Key + ": " + p.Value.ToString() + "\r\n";
        }
        else
        {
            MessageBox.Show("dictionary: " + p.Value.GetType().ToString());
        }
    }
}

private void traceArrayList(ArrayList al)
{
    for (int i = 0; i < al.Count; i++)
    {
        if (al[i] is String)
        {
            textBox1.Text = textBox1.Text + "   " + al[i].ToString() + "\r\n";
        }
        else if (al[i] is Dictionary<string, object>)
        {
            traceDic((Dictionary<string, object>)(al[i]));
        }
        else
        {
            MessageBox.Show("arrlist: " + al[i].GetType().ToString());
        }
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.phanix.idv.tw/archives/2011/07/19/962/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET 取得 windows 帳號資訊</title>
		<link>http://blog.phanix.idv.tw/archives/2011/06/20/938/</link>
		<comments>http://blog.phanix.idv.tw/archives/2011/06/20/938/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 10:43:25 +0000</pubDate>
		<dc:creator>Phanix</dc:creator>
				<category><![CDATA[學習工作]]></category>
		<category><![CDATA[工作]]></category>
		<category><![CDATA[程式]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[Account]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://blog.phanix.idv.tw/?p=938</guid>
		<description><![CDATA[取得登入帳號 Environment.UserName 取得帳號等有儲存在本機上的資訊 using System.Security.Principal; using System.Threading; //----- AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); WindowsPrincipal myPrincipal = (WindowsPrincipal)Thread.CurrentPrincipal; WindowsIdentity myIdentity = (WindowsIdentity)myPrincipal.Identity; Console.WriteLine("IdentityType: " + myIdentity.ToString()); Console.WriteLine("Name: {0}", myIdentity.Name); Console.WriteLine("Member of Users? {0}", myPrincipal.IsInRole(WindowsBuiltInRole.User)); Console.WriteLine("Member of Administrators? {0}", myPrincipal.IsInRole(WindowsBuiltInRole.Administrator)); Console.WriteLine("Authenticated: {0}", myIdentity.IsAuthenticated); Console.WriteLine("Anonymous: {0}", myIdentity.IsAnonymous); 取得帳號等有儲存在本機上的資訊 &#8211; II 使用 Win32 API using System.Runtime.InteropServices; //----- [DllImport("Advapi32.dll", EntryPoint="GetUserName", ExactSpelling=false, SetLastError=true)] static extern [...]]]></description>
			<content:encoded><![CDATA[<h2>取得登入帳號</h2>
<p>Environment.UserName</p>
<p><br/><br/><br/></p>
<h2>取得帳號等有儲存在本機上的資訊</h2>
<pre>
using System.Security.Principal;
using System.Threading;

//-----

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

WindowsPrincipal myPrincipal = (WindowsPrincipal)Thread.CurrentPrincipal;

WindowsIdentity myIdentity = (WindowsIdentity)myPrincipal.Identity;

Console.WriteLine("IdentityType: " + myIdentity.ToString());
Console.WriteLine("Name: {0}", myIdentity.Name);
Console.WriteLine("Member of Users? {0}", myPrincipal.IsInRole(WindowsBuiltInRole.User));
Console.WriteLine("Member of Administrators? {0}", myPrincipal.IsInRole(WindowsBuiltInRole.Administrator));
Console.WriteLine("Authenticated: {0}", myIdentity.IsAuthenticated);
Console.WriteLine("Anonymous: {0}", myIdentity.IsAnonymous);</pre>
<p><br/><br/><br/></p>
<h2>取得帳號等有儲存在本機上的資訊 &#8211; II</h2>
<p>使用 Win32 API</p>
<pre>
using System.Runtime.InteropServices;

//-----
[DllImport("Advapi32.dll", EntryPoint="GetUserName",  ExactSpelling=false, SetLastError=true)]
static extern bool GetUserName([MarshalAs(UnmanagedType.LPArray)] byte[] lpBuffer,
						[MarshalAs(UnmanagedType.LPArray)] Int32[] nSize );

//-----
byte[] str = new byte[256];
Int32[] len = new Int32[1];
len[0] = 256;
GetUserName(str, len);
MessageBox.Show(System.Text.Encoding.ASCII.GetString(str));

string a = System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();

MessageBox.Show(a.ToString());</pre>
<p><br/><br/><br/></p>
<h2>LDAP</h2>
<p>這是可以取得最詳細資訊的方法</p>
<pre>using System.DirectoryServices;

//-----

string principal = Environment.UserName;
string filter = string.Format("(&#038;(ObjectClass={0})(sAMAccountName={1}))", "person", principal);
string[] properties = new string[] { "fullname" };

//用匿名登入，理論上LDAP都會允許，但只有 read 權限
DirectoryEntry adRoot = new DirectoryEntry("LDAP://yourdomain.com", null, null, AuthenticationTypes.Secure);
DirectorySearcher searcher = new DirectorySearcher(adRoot);
searcher.SearchScope = SearchScope.Subtree;
searcher.ReferralChasing = ReferralChasingOption.All;
searcher.PropertiesToLoad.AddRange(properties);
searcher.Filter = filter;
SearchResult result = searcher.FindOne();
DirectoryEntry directoryEntry = result.GetDirectoryEntry();

string displayName = directoryEntry.Properties["displayName"][0].ToString();
string firstName = directoryEntry.Properties["givenName"][0].ToString();
string lastName = directoryEntry.Properties["sn"][0].ToString();
string email = directoryEntry.Properties["mail"][0].ToString();
string department = directoryEntry.Properties["department"][0].ToString();
string description = directoryEntry.Properties["description"][0].ToString();</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.phanix.idv.tw/archives/2011/06/20/938/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# window form drawing over other controls / 在 window form 中繪製圖形並疊在控制項上</title>
		<link>http://blog.phanix.idv.tw/archives/2011/02/23/901/</link>
		<comments>http://blog.phanix.idv.tw/archives/2011/02/23/901/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 07:14:21 +0000</pubDate>
		<dc:creator>Phanix</dc:creator>
				<category><![CDATA[學習工作]]></category>
		<category><![CDATA[工作]]></category>
		<category><![CDATA[程式]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[panel]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[transparent]]></category>

		<guid isPermaLink="false">http://blog.phanix.idv.tw/?p=901</guid>
		<description><![CDATA[本文以中英夾雜並陳 This article is interleaved with Chinese and English. 本來還想在網路上看能不能找到答案的, 結果只有找到一些可能的提示&#8230; 不過最後還是摸索出來了啦 At the beginning, I hope to scrounge the solution from Internet, but after hours of searching, I only find some possible hints. Anyway, here&#8217;s the solution. 之所以會想要弄這樣的功能，是因為要做出類似在檔案總管中用拖曳選取時有半透明選取區域的效果。但是如果在 window form 中匯製矩形時，會發現這個矩形區域會被其他的控制項壓在下面，使得這個半透明的效果變得很奇怪(如下圖). This issue is caused by I wanna make a semi-transparent selection area in [...]]]></description>
			<content:encoded><![CDATA[<p>本文以中英夾雜並陳</p>
<p>This article is interleaved with Chinese and English.</p>
<p>本來還想在網路上看能不能找到答案的, 結果只有找到一些可能的提示&#8230; 不過最後還是摸索出來了啦 <img src='http://blog.phanix.idv.tw/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>At the beginning, I hope to scrounge the solution from Internet, but after hours of searching, I only find some possible hints. Anyway, here&#8217;s the solution.</p>
<p><span id="more-901"></span></p>
<p>之所以會想要弄這樣的功能，是因為要做出類似在檔案總管中用拖曳選取時有半透明選取區域的效果。但是如果在 window form 中匯製矩形時，會發現這個矩形區域會被其他的控制項壓在下面，使得這個半透明的效果變得很奇怪(如下圖).</p>
<p>This issue is caused by I wanna make a semi-transparent selection area in a window form, just what we usually use in windows file manager. However, if we just draw a rectangle in a window form, this rectangle will be &#8220;overlayed&#8221; by other controls, just like the figure below. Yep, quite weird.</p>
<p><a href="http://www.flickr.com/photos/phanix/5469721099/" title="underlay by Phanix, on Flickr"><img src="http://farm6.static.flickr.com/5176/5469721099_44301821ef_z.jpg" width="562" height="640" alt="underlay" /></a></p>
<p>而我想要的效果是如下圖這樣的, 半透明的選取區域壓在控制項上方.</p>
<p>The figure below is what I really want is a semi-transparent selection region overlays other controls.<br />
<a href="http://www.flickr.com/photos/phanix/5470314074/" title="Overlay by Phanix, on Flickr"><img src="http://farm6.static.flickr.com/5099/5470314074_b2a3f14b4c_z.jpg" width="640" height="577" alt="Overlay" /></a></p>
<p>最開始的時候我的想法是做一個透明的 Panel, 同時給定顏色，然後隨著滑鼠拖曳動態地去調整大小。結果我在網路上找到了製作透明 Panel 的方法(程式碼如下)，但，很遺憾地，對這個透明 Panel 指定顏色還不能達到我想要的效果。</p>
<p>My first trial is creating a transparent Panel and assign some color onto in, and adjust the size as mouse dragging and moving. I scrounged a transparent panel solution from Internet (source code as below), but, unfortunately, assigning color onto it still does not meet what I want.</p>
<blockquote><pre>public class TransparentPanel : System.Windows.Forms.Panel
{
    public TransparentPanel()
    {
    }

    protected override System.Windows.Forms.CreateParams CreateParams
    {
        get
        {
            System.Windows.Forms.CreateParams createParams = base.CreateParams;
            createParams.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT

            return createParams;
        }
    }

    protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
    {
        // Do not paint background.
    }
}</pre>
</blockquote>
<p>那, 在這個透明的 panel 上頭畫一個半透明的矩形呢? 似乎有點可行, 但是在滑鼠拖曳移動時會變得很糟糕, 留下許多殘像.</p>
<p>Well, how about drawing a semi-transparent rectangle on the transparent panel? Sounds reasonable, but there are lots of afterimages while mouse dragging and moving.</p>
<blockquote>
<pre>//draw a semi-transparent rectangle by adjusting the alpha value of Color.FromArgb function.
Rectangle rec = new Rectangle(topLeftRec, howBig);
Graphics.FillRectangle(new SolidBrush(Color.FromArgb(150, 255, 255, 0)), rec);</pre>
</blockquote>
<p>後來看到一些提示之後找到了解法，必須透過控制項的 Paint event 來把這個矩形匯製出來。雖然還不是很清楚為什麼要這樣做，但感覺起來是把這個矩形的匯製的動作跟著控制項匯製的動作綁在一起。藉由改變 transparent panel 的大小與位置來觸發 Paint event.</p>
<p>Finally, with some hints on Internet, I find the solution &#8212; painting the rectangle as a control&#8217;s paint event is triggered. Although I still do not fully understand the reason why I have to follow this process, I think it might require combining drawing rectangle with the control&#8217;s paint process. By changing the size and location of the transparent panel, the Paint event can be triggered.</p>
<blockquote><pre>private void pTransparent_Paint(object sender, PaintEventArgs e)
{
    base.OnPaint(e);
    Graphics dc = e.Graphics;

    Pen blackPen = new Pen(Color.Black, 1);
    Point topLeftRec = new Point(e.ClipRectangle.X, e.ClipRectangle.Y);
    Size howBig = new Size(e.ClipRectangle.Width, e.ClipRectangle.Height);
    Rectangle rec = new Rectangle(topLeftRec, howBig);

    Console.WriteLine(topLeftRec.ToString());

    dc.DrawRectangle(blackPen, rec);
    dc.FillRectangle(new SolidBrush(Color.FromArgb(150, 255, 255, 0)), rec);
    blackPen.Dispose();
}

private Rectangle drawrect;
private bool md = false;
private Point startpoint, drawtopleft;
private Size drawsize;

private void flowLayoutPanel1_MouseMove(object sender, MouseEventArgs e)
{
    if (md == true)  //md is a boolean variable representing in mouse dragging mode or not.
    {
        drawtopleft.X = Math.Min(startpoint.X, e.X);
        drawtopleft.Y = Math.Min(startpoint.Y, e.Y);

        drawsize.Width = Math.Abs(startpoint.X - e.X);
        drawsize.Height = Math.Abs(startpoint.Y - e.Y);

        drawrect = new Rectangle(drawtopleft, drawsize);
        ((FlowLayoutPanel)sender).Refresh();

        pTransparent.Width = drawrect.Width;
        pTransparent.Height = drawrect.Height;
        pTransparent.Left = drawtopleft.X;
        pTransparent.Top = drawtopleft.Y;
        }
    }
}</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.phanix.idv.tw/archives/2011/02/23/901/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# Windows form 透明 panel (transparent panel)</title>
		<link>http://blog.phanix.idv.tw/archives/2011/02/18/900/</link>
		<comments>http://blog.phanix.idv.tw/archives/2011/02/18/900/#comments</comments>
		<pubDate>Fri, 18 Feb 2011 09:43:22 +0000</pubDate>
		<dc:creator>Phanix</dc:creator>
				<category><![CDATA[學習工作]]></category>
		<category><![CDATA[工作]]></category>
		<category><![CDATA[程式]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.phanix.idv.tw/?p=900</guid>
		<description><![CDATA[using System.Windows.Forms; namespace XXX_namespace { /// /// A transparent control. /// public class TransparentPanel : Panel { public TransparentPanel() { } protected override CreateParams CreateParams { get { CreateParams createParams = base.CreateParams; createParams.ExStyle &#124;= 0x00000020; // WS_EX_TRANSPARENT return createParams; } } protected override void OnPaintBackground(PaintEventArgs e) { // Do not paint background. } } }]]></description>
			<content:encoded><![CDATA[<pre>using System.Windows.Forms;

namespace XXX_namespace
{
    ///
<summary>
    /// A transparent control.
    /// </summary>

    public class TransparentPanel : Panel
    {
        public TransparentPanel()
        {
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams createParams = base.CreateParams;
                createParams.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
                return createParams;
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            // Do not paint background.
        }
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.phanix.idv.tw/archives/2011/02/18/900/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WSET Intermediate Certification!</title>
		<link>http://blog.phanix.idv.tw/archives/2011/01/23/895/</link>
		<comments>http://blog.phanix.idv.tw/archives/2011/01/23/895/#comments</comments>
		<pubDate>Sun, 23 Jan 2011 15:40:10 +0000</pubDate>
		<dc:creator>Phanix</dc:creator>
				<category><![CDATA[學習工作]]></category>
		<category><![CDATA[生活點滴]]></category>
		<category><![CDATA[WSET]]></category>

		<guid isPermaLink="false">http://blog.phanix.idv.tw/?p=895</guid>
		<description><![CDATA[科科～全班最高分&#8230; 雖然我不知道這分數怎麼來的，我明明就錯了好幾題啊 @@&#8221;]]></description>
			<content:encoded><![CDATA[<p>科科～全班最高分&#8230; 雖然我不知道這分數怎麼來的，我明明就錯了好幾題啊 @@&#8221;</p>
<p><a href="http://www.flickr.com/photos/phanix/5381228118/" title="R0018661 by Phanix, on Flickr"><img src="http://farm6.static.flickr.com/5008/5381228118_5f892b726f_z.jpg" width="640" height="480" alt="R0018661" /></a></p>
<p><a href="http://www.flickr.com/photos/phanix/5380627623/" title="R0018662 by Phanix, on Flickr"><img src="http://farm6.static.flickr.com/5248/5380627623_ff5b65bb79_z.jpg" width="480" height="640" alt="R0018662" /></a></p>
<p><a href="http://www.flickr.com/photos/phanix/5381231376/" title="R0018663 by Phanix, on Flickr"><img src="http://farm6.static.flickr.com/5009/5381231376_abc03c4c2e_z.jpg" width="480" height="640" alt="R0018663" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phanix.idv.tw/archives/2011/01/23/895/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DOS batch ADSL dial and disconnect</title>
		<link>http://blog.phanix.idv.tw/archives/2010/11/26/862/</link>
		<comments>http://blog.phanix.idv.tw/archives/2010/11/26/862/#comments</comments>
		<pubDate>Fri, 26 Nov 2010 11:56:53 +0000</pubDate>
		<dc:creator>Phanix</dc:creator>
				<category><![CDATA[學習工作]]></category>
		<category><![CDATA[程式]]></category>
		<category><![CDATA[網路應用]]></category>
		<category><![CDATA[電腦網路]]></category>
		<category><![CDATA[ADSL]]></category>
		<category><![CDATA[batch]]></category>
		<category><![CDATA[dos]]></category>
		<category><![CDATA[撥號]]></category>
		<category><![CDATA[自動撥號]]></category>

		<guid isPermaLink="false">http://blog.phanix.idv.tw/?p=862</guid>
		<description><![CDATA[把 ADSL 撥號跟斷線做成 Batch (.bat) 檔。 什麼時候可以用？當用浮動IP ADSL，想要跳IP掃網頁的時候。 @echo off rem 定義 ADSL 撥號名稱, ID, Password set adsl=預先設置號的ADSL撥號名稱 set adslid=YOUR_ID set adslpw=YOUR_PASSWORD :start rem 斷線 / disconnect Rasdial %adsl% /disconnect rem 撥號連線 / dial Rasdial %adsl% %adslid% %adslpw%]]></description>
			<content:encoded><![CDATA[<p>把 ADSL 撥號跟斷線做成 Batch (.bat) 檔。<br />
什麼時候可以用？當用浮動IP ADSL，想要跳IP掃網頁的時候。 <img src='http://blog.phanix.idv.tw/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p><span id="more-862"></span></p>
<pre>@echo off
rem 定義 ADSL 撥號名稱, ID, Password
set adsl=預先設置號的ADSL撥號名稱
set adslid=YOUR_ID
set adslpw=YOUR_PASSWORD

:start
rem 斷線 / disconnect
Rasdial %adsl% /disconnect

rem 撥號連線 / dial
Rasdial %adsl% %adslid% %adslpw%</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.phanix.idv.tw/archives/2010/11/26/862/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Germany wine classification system / 德國酒分級制度</title>
		<link>http://blog.phanix.idv.tw/archives/2010/10/24/844/</link>
		<comments>http://blog.phanix.idv.tw/archives/2010/10/24/844/#comments</comments>
		<pubDate>Sun, 24 Oct 2010 04:04:15 +0000</pubDate>
		<dc:creator>Phanix</dc:creator>
				<category><![CDATA[吃喝玩樂]]></category>
		<category><![CDATA[唸書]]></category>
		<category><![CDATA[學習工作]]></category>
		<category><![CDATA[生活點滴]]></category>
		<category><![CDATA[翻閱之樂]]></category>

		<guid isPermaLink="false">http://blog.phanix.idv.tw/?p=844</guid>
		<description><![CDATA[做個整理，資料大多來自 Wikipedia 跟網路上的資訊。 Official Classification / 官方分級制度 VDP 組織 Großes Gewächs &#038; Erstes Gewächs / Great Growth &#038; First Growth]]></description>
			<content:encoded><![CDATA[<p>做個整理，資料大多來自 Wikipedia 跟網路上的資訊。</p>
<p><span id="more-844"></span></p>
<h2>Official Classification / 官方分級制度</h2>
<p><div style="width:47.5%; float: left; padding-right: 5%; display: inline;" class="post_column_1"><p><br />
The official <a href="http://en.wikipedia.org/wiki/German_wine_classification" target="_blank">classification system of Germany</a> wine was settled down in law in 1971. This classification system defined the &#8220;must weight&#8221; (sugar sweetness in grape juice), wine regions, information should be listed on label, etc. This classification system classify Germany wines into 4 levels, Deutscher Tafelwein (German table wine), Deutscher Landwein (German country wine, just like Vin de Pays), Qualitätswein bestimmter Anbaugebiete (QbA, quality wine from a specific region), and Prädikatswein (In August 1, 2007, renamed from Qualitätswein mit Prädikat, QmP).</p>
<p>This 4 levels category is similar to French AOC. But, Tafelwein and Landwein only account for 3.6% of all Germany wines, respectively. QbA is about 49.6%, and QmP is about 46.8%. This percentage distribution is quite different from French AOC.</p>
<p>However, this classification system does not rigorously define the wine region, grape variety, vinification, ageing regulations, etc. as other &#8220;old world&#8221; countries&#8217; classification law, so that this system is criticized by many top wine producers.<br />
</div><br />
<div style="width:47.5%; float: left; padding-right: 0%; display: inline;" class="post_column_1"><p><br />
德國官方的葡萄酒分級制度在 1971 年訂定，主要是規定了葡萄汁糖份含量、葡萄酒生產區、必須在酒標上標示的資訊等。此官方分級制度將德國葡萄酒分為四個等級：餐酒(German Table Wine)、地區餐酒(German country wine, 跟法國的 Vin de Pays類似)、QbA、QmP。</p>
<p>此四級的分類很像法國AOC的分類，不過德國的 talbe wine 跟 country wine 其實只佔了約 3.6%，QbA佔了 49.6%，QmP佔了約 46.8%。此比例的分佈跟法國卻很不一樣。</p>
<p>然而，此分級制度並沒有很嚴格地規範產區、葡萄品種、製作過程、陳年條件等其他舊世界國家分級制度會列出的項目，因此這個官方的分級制度其實被不少酒業人士所詬病。<br />
</div><br />
<div style="clear: both;"></div></p>
<h2>VDP 組織</h2>
<p><img src="http://upload.wikimedia.org/wikipedia/commons/4/47/VDP-Schild.jpg" width="800"><br />
<div style="width:47.5%; float: left; padding-right: 5%; display: inline;" class="post_column_1"><p><br />
<a href="http://en.wikipedia.org/wiki/Verband_Deutscher_Pr%C3%A4dikats-_und_Qualit%C3%A4tsweing%C3%BCter" target="_blank">VDP</a> (Verband Deutscher Prädikats- und Qualitätsweingüter e.V.) is another classification system, established by the Association of German Prädikat Wine Estates in 1910. There are about 200 wineries (3% of total wineries in Germany) in this unofficial system. The winery wants to be the member of VDP should follow more stringent regulations than the official law. VDP members can use the above eagle logo on their wine bottles.<br />
</div><br />
<div style="width:47.5%; float: left; padding-right: 0%; display: inline;" class="post_column_1"><p><br />
VDP 是另一個分級制度，由 Association of German Prädikat Wine Estates 這個非官方組織在 1910 年訂定，主要的成員包含了約 200+ 家的酒莊(約佔全德國酒莊數量的 3%)。VDP 的規範其實跟官方的分級制度不會差太多，但更加嚴格一些。而 VDP 的成員酒莊可以在他們的酒瓶子上使用如上圖的 VDP logo 老鷹圖案。<br />
</div><br />
<div style="clear: both;"></div></p>
<h2>Großes Gewächs &#038; Erstes Gewächs / Great Growth &#038; First Growth</h2>
<p><div style="width:47.5%; float: left; padding-right: 5%; display: inline;" class="post_column_1"><p><br />
<a href="http://de.wikipedia.org/wiki/Gro%C3%9Fes_Gew%C3%A4chs" target="_blank">Großes Gewächs</a> and <a href="http://de.wikipedia.org/wiki/Erstes_Gew%C3%A4chs" target="_blank">Erstes Gewächs</a> are the other unofficial classification systems created by VDP. The legacy Germany wine classification system is not similar to the systems of French, Italy and Spain, which stringently define the grape varieties, regions, yield, wine making process, aging policies, etc. That&#8217;s why VDP creates these two classifications and related pyramid.</p>
<p>So, we might call this &#8220;Großes Gewächs&#8221; as &#8220;Great Growth&#8221;, and &#8220;Erstes Gewächs&#8221; as &#8220;First Growth&#8221; classifications of Germany wines. Both systems only regulate &#8220;dry wines&#8221; (white and red) on the vineyard, region, grape varieties, yield (maximum 50 hl/ha), late harvesting policies (must weight should be Spatlese level at least), wine making process, and aging time. Basically, these two system are the same, but &#8220;Erstes Gewächs&#8221; is only used in Rheingau region. &#8220;Erstes Gewächs&#8221; requires at 12% and 13% alcohol and max. 13 g/L and 6 g/L residual sugar to Riesling and Pinot Noir, respectively.</p>
<p>Both systems do not authorize the certification to a winery, but to an individual wine instead. Very similar to Spain&#8217;s Crianza, Reserva and Gran Riserva regulations.<br />
</div><br />
<div style="width:47.5%; float: left; padding-right: 0%; display: inline;" class="post_column_1"><p><br />
Großes Gewächs 與 Erstes Gewächs 都是由 VDP 組織所訂定。現有官方的分級制度主要是依照葡萄汁含糖量來對酒分級，但此方式較難像法國、義大利或西班牙的分級制度較能讓消費者區分出酒的品質好壞。有鑑於此，VDP 的 Großes Gewächs 與 Erstes Gewächs 嚴格規定了葡萄品種、產區、單位面積產量(max. 50 hl/ha)、製作過程、陳年要求、晚收的定義等。這兩個制度其實差不多，但都只針對 dry wine 給予認證，此外，Erstes Gewächs 只用在 Rheingau (萊茵高)產區。各地的 Großes Gewächs 規定有一些差異，而 Rheingau 的 Erstes Gewächs 則規定對 Riesling 至少要有 12% 的酒精濃度，以及最多 13 g/L 的殘糖量；而 Pinot Noir 則至少 13% 酒精度與最多 6 g/L 的殘糖量。</p>
<p>要注意的是，VDP不是針對酒莊給予 Großes Gewächs 或 Erstes Gewächs，而是針對酒款是否符合此規定給予認證。有點類似西班牙的 Crianza, Reserva, Gran Reserva 品質要求規範。<br />
</div><br />
<div style="clear: both;"></div></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phanix.idv.tw/archives/2010/10/24/844/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

